الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

[ تمت الإجابة ]استدعاء الدوال بعنوانها و ليس بإسمها

مغلق
بدأه C++er في 25 ديسمبر 2009 · 5 رد · 2,681 مشاهدة · في أرشيف قسم Windows APIs
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم و رحمة الله و بركاته

الداله GetProcAddress تقوم بالحصول على موقع داله بالذاكره (الداله لابد من ان يكون تم تصديرها).

السؤال الذى لدى هو كيف يتم استدعاء لم يتم عمل export لها، حتى يكون السؤال اوضح إليكم مثال لما اريده.

داخل المكتبه Kernel32.dll توجد الداله AllocConsole و التى عند استدعائها تقوم بإستدعاء داله اخرى و التى تقوم بإنشاء نافذة الـ Console هذه الداله اسمها AllocConsoleInternal عنوانها (7C872565) و تأخذ 11 معامل.

كيف استطيع استدعاء هذه الداله ؟؟ من الـ C/C++

و الله ولى التوفيق

تم تعديل هذه المشاركة بواسطة Muhammad alaa في 25 ديسمبر 2009 في 18:25

مدونتي: C++ Tips and Tricks

#2

قمت بإستدعائها، شكرا لكم

و الله ولى التوفيق

مدونتي: C++ Tips and Tricks

#3

ألا تكتب الحل بعد ما شغلتنا بالسؤال :)

لا إله إلا الله محمد رسول الله

アッラー以外に神はなし。ムハンマドはアッラーの使徒である

#4
_- محمد نور -_ كتب:

ألا تكتب الحل بعد ما شغلتنا بالسؤال :)

معذره اخى فقد كنت مشغول حينها و نسيت وضع الإجابه.

يوجد 3 انواع من الدوال داخل الملفات التنفيذيه دوال يتم تصديرها من الملف التنفيذى و اخرى يتم استدعائها من ملف تنفيذى اخر و النوع الثالث هو الدوال الـ Private و التى بعد تحويل الكود لملف تنفيذى يتم حذف اسمها و يتم التعامل معها بالـ Offset داخل الكود.

النوع الذى يهمنى الأن هو الدوال الـ Private التى لا اسم لها، و لإستدعائها نحتاج لمعرفة موقعها بالنسبه للـ BaseOfCode (الموجود بـ Optional Header).

بمجرد معرفتك لموقعها يصبح استدعائها امر سهل حيث انك فى البدايه تقوم بتحميل المكتبه بإستخدام الداله LoadLibrary و المقبض الذى يعود لك هو بداية قسم الكود داخل الملف التنفيذى و هذا يعنى ان هذا المقبض ايا كان قيمته يساوى لـ BaseOfCode و بالتالى للحصول على هذه الداله كل ما تحتاجه هو اضافة موقع الداله التى تريدها لهذا المقبض ثم تقوم بعمل casting لهذا المقبض لمؤشر داله يماثل تعريف الداله التى تريد استدعائها، بعد عمل casting يمكنك بكل سهوله استدعاء الداله و ستعمل.

كماثل على ما قلت سنقوم بإستدعاء داله تم تصديرها و لكن ليس بالإسم و انما بالـ offset الخاص بها داخل الكود و هذه الداله هى MessageBeep و السبب فى ذلك انه يسهل الحصول على موقعها الـ Export Table، ثانيا هو انه معروف الـ signture الخاص بها.

معلومات متعلقه بالداله: (لاحظ ان لأرقام قد تختلف من اصدار لإصدار اخر انا اعمل على ويندوز XP SP3 بتحديث 12/2009)

Library: user32.dll
BaseOfCode : 0x1000
Function Offset to BaseOfCode (aslo RVA) : 0x21F7B (our needed number)

لننظر الان لكود الـ C++

#include <windows.h>

typedef BOOL (WINAPI *MsgBeep) (UINT utype);

void main()
{
	const int FunIdx = 0x21F7B;

	HMODULE hLib = LoadLibrary(L"User32.dll");

	MsgBeep myfunc = (MsgBeep) ((int)hLib + FunIdx);

	myfunc(0x10);
}

كما تلاحظ لابد من تحويل الـ Handle لـ int قبل عملية الإضافه و ذلك للحصول على موقع الداله بشكل سليم دون مشاكل.

الداله myfunc قمت بتمرير لها الرقم 16 و هذا الرقم يعنى صوت الـ Critical Message يمكنك مراجعه الـ MSDN لتفاصيل اكثر عن خصائصها.

ملاحظات للغات الدوت نت (و بالخصوص VB.NET و C#).

حيث ان هذه الطريقه تعمل داخلهم و لكنها غير امنه على الإطلاق و السبب ىف ذلك يعود للـ Calling Convention حيث داخل السى و السى بلس بلس تستطيع تعريف مؤشر لداله و تحديد اسلوب التعامل مع المعاملات Calling Convention اما داخل الدوت نت فالـ Calling Convention متاحه فقط للدوال التى يتم استدعائها بإستخدام DllImportAttribute و حيث ان اغلب الدوال (Private or Exported) تم استخدام __stdcall معها فستجد صعوبه فى تحديدها لـ Delegate، و لكن لحسن الحظ ان الدوت نت اسلوب الإستدعاء الإفتراضى لها هو __stdcall لذا فلا مشكله مع دوال الـ API ان كانت تتبع هذا الإسلوب فى الإستدعاء اما إن كانت لا تتبعه فستحتاج لعمل بعض المجهود.

يمكنك الرجوع لهذا الموضوع او هذا الموضوع داخل موقع codeProject فى حال قابلت انواع اخرى من اسليب الإستدعاء، و ان كنت لا تفضل طريقتهم فيمكنك استخدام Emit لبناء الـ Delegate بشكل ديناميكى.

و الله ولى التوفيق

مدونتي: C++ Tips and Tricks

#5

هل تقصد بالصعوبة فى الدوت نت لإن مواقع الأشياء تتغير بالذاكرة !! بسبب الCC

لا إله إلا الله محمد رسول الله

アッラー以外に神はなし。ムハンマドはアッラーの使徒である

#6
_- محمد نور -_ كتب:

هل تقصد بالصعوبة فى الدوت نت لإن مواقع الأشياء تتغير بالذاكرة !! بسبب الCC

اعتقد انك تقصد GC، لا الصعوبه التى اتكلم عليها هى اسلوب ادخال المعاملات للـ Stack حيث يختلف من Calling Convention لأخر و حيث ان السائد داخل الدوت نت هو __stdcall فالإدخال يكون من اليمين إلى اليسار.

اذا قمت بتصدير دوال من داخل مكتبة مصنوعه بالدوت نت فالـ Calling Convention لها هو _stdcall حتى و لو لم تقم بكتابنه (بالطبع لن تستطيع تحديده إلا من داخل MSIL).

و الله ولى التوفيق

مدونتي: C++ Tips and Tricks

هذا الموضوع مغلق.

مواضيع مشابهة