هل يمكنني برمجيا نستنتج الدعوة الاتفاقية التي يستخدمها C++ dll?

StackOverflow https://stackoverflow.com/questions/2277986

سؤال

تخيل أنك ترغب في كتابة برنامج اختبارات وظائف في c++ ملف dll.يجب تمكين المستخدم من اختيار dll (ونحن نفترض أننا نتحدث عن c++ dll).وينبغي أن تكون قادرة على الحصول على قائمة بجميع الوظائف تصديرها من dll.ثم يجب أن يكون المستخدم قادرا على تحديد اسم وظيفة من القائمة يدويا إدخال قائمة من الوسيطات ( الوسيطات جميع أنواع أساسية ، مثل int, double, منطقي أو شار المصفوفات (مثلا ، ج-نوع السلاسل) ) و محاولة تشغيل الوظيفة المختارة مع الوسائط المحددة.أنه يود أن يعرف إذا كانت وظيفة يعمل مع الوسائط المحددة ، أو أنها تتسبب في تحطم ( لأنها لا تطابق التوقيع على سبيل المثال ).

المشكلة الرئيسية هي أن C++, كونه بقوة كتابة اللغة يتطلب منك أن تعرف عدد و نوع من الحجج استدعاء دالة في وقت الترجمة.و في حالتي أنا ببساطة لا أعرف ما هذه الحجج ، حتى يختار المستخدم منها في وقت التشغيل.

الحل الوحيد مع استخدام الجمعية يدويا دفع الحجج على مكدس الاستدعاءات.

ولكن أنا أفهم أنه إذا كنت تريد أن تعبث مع الجمعية, من الأفضل أن نتأكد أن تدعو الاتفاقية الدالات في dll باستخدام.

حتى (النهاية:) سؤالي هو:يمكن أن أستنتج الدعوة الاتفاقية programmaticaly?Walker تبعية لن يساعدني, و ليس لدي أي فكرة عن كيفية يدويا قراءة PE format.

هل كانت مفيدة؟

المحلول

الجواب هو يمكن.

إذا كانت أسماء الوظائف مزينة C ++ ، فيمكنك تحديد عدد وأنواع الوسيطة من زخرفة الاسم ، فهذا هو أفضل سيناريو لحالة ، ومن المحتمل إلى حد ما إذا تم استخدام MSVC لكتابة الرمز في المقام الأول.

إذا كانت الوظائف التي تم تصديرها هي اتفاقية استدعاء STDCALL (الافتراضي لـ Windows API) ، فيمكنك تحديد عدد البايتات المراد دفعها ، ولكن ليس أنواع الوسيطات.

الأخبار السيئة هي أنه بالنسبة لاتفاقية الاتصال C ، لا توجد أي طريقة لمعرفة ذلك من خلال النظر إلى أسماء الرموز. ستحتاج إلى الوصول إلى الكود المصدري أو معلومات التصحيح.

http://en.wikipedia.org/wiki/x86_calling_conventions

الاسم الذي يتم إعطاء الوظيفة كتصدير ليس كذلك مطلوب للحصول على أي علاقة مع الاسم الذي يراه الرابط ، ولكن معظم الوقت ، الاسم المصدر واسم الرمز الذي يراه الرابط هو نفسه.

نصائح أخرى

لم تحدد ما إذا كنت تتحدث 32 بت أو 64 بت هنا ، والصعوبات التي حددتها أنت والملصقات الأخرى تنطبق بشكل أساسي على رمز 32 بت. على النوافذ 64 بت ، لا يوجد سوى مؤتمر واحد فقط (هو في مقالة ويكيبيديا المرتبطة من قبل جون نويلر) ، مما يعني أنك أنت فعل تعرف على اتفاقية الاتصال (بالطبع باستثناء أي شخص يطبخه).

أيضًا ، مع اتفاقية استدعاء Microsoft X64 ، لا تعرف عدد معلمات الوظيفة المراد استدعاؤها لا يمنعك من الاتصال بها ، مما يوفر أكبر عدد ممكن من المعلمات/يرغب المستخدم في ذلك. هذا لأنك كمتصل تخصيص مساحة المكدس جانباً وقم بتنظيفه بعد ذلك. - بالطبع ، قد لا يزال لا يوجد لدى عدم توفير [عدد] المعلمات المناسبة الوظيفة التي تسمى أشياء سخيفة لأنك تقدم مدخلات غير صالحة ، لكن هذه قصة أخرى.

التعليمات البرمجية المترجمة لا أقول هنا هذه هي وظيفة fastcall ، و هذا واحد هنا هو stdcall' للأسف.

ولا حتى الحديث disassemblers مثل IDA نحاول أن نستنتج أنواع الاتصال بشكل افتراضي (قد يكون هناك المساعد أو خيار في مكان ما idk).

أساسا إذا كنت الإنسان cn يمكنك ننظر القليلة الأولى التعليمات اقول 90% من الوقت.إذا كانت البوب دفع ، stdcall ، إذا به يمر params من خلال السجلات (خصوصا ecx) ثم cdecl.Fastcall يستخدم أيضا يسجل ولكن لا شيء خاص..لا أدري من أعلى رأسي.ولكن كل هذه المعلومات غير مجدية لأن البرنامج لن يكون من الواضح الإنسان.

إذا كنت تفعل اختبار, لا أميل لديك على الأقل رأس الملفات ؟ ؟ هذا صعبا طريقة لقطة الجلد..

إذا كنت تريد أن تعرف ما هي اتفاقية الاتصال التي تستخدمها وظيفة C ++ ، فإن أفضل أمل لك هو الدراسة

  1. الرأس الذي يعلن تلك الوظيفة ، و
  2. وثائق المترجم الذي جمع DLL الخاص بك.

لكن هذا الأمر برمته يبدو وكأنه القليل من الفوضى ، بصراحة. لماذا يريد صديقك أن يكون قادرًا على القيام بذلك ، ولماذا لا يستطيع الحصول على المعلومات التي يحتاجها عن طريق تحليل رأس يعلن الوظائف ذات الصلة؟

تصف هذه الصفحة الطريقة التي يشفرها VC ++ 6 المعلمة والاتصال بالاتصالات إلى اسم رمز: http://www.bottledlight.com/docs/mangle.html

أظن أن الإصدارات اللاحقة من VC ++ ستكون متوافقة لكنني لم أكن أؤكد ذلك.

هناك أيضًا بعض الأدوات التي تتم أتمتة هذا والتي تصاحب المترجم: http://msdn.microsoft.com/en-us/library/5x49w699.aspx

ينطبق الاسم millgling فقط على وظائف C ++ ؛ إذا كانت الوظيفة "خارجي" C "، فلن يعمل هذا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top