شرح تفكيك برنامج أبسط (x86)
سؤال
الرمز التالي
int _main() {return 0;}
تم تجميعها باستخدام الأمر:
gcc -s -nostdlib -nostartfiles 01-simple.c -o01-simple.exe
إصدار GCC 4.4.1 (TDM-1 Mingw32)
أنتجت Ollydbg هذا المخرج:
هل يمكنك شرح ما يحدث هنا؟ التحليل حتى الآن:
// these two seems to be an idiom:
PUSH EBP // places EBP on stack
MOV EBP, ESP // overwrites EBP with ESP
MOV EAX, 0 // EAX = 0
LEAVE // == mov esp, ebp
// pop ebp
// according to
// http://en.wikipedia.org/wiki/X86_instruction_listings
ما المقصود من كل هذا؟
المحلول
هذا يخلق إطار المكدس.
PUSH EBP
MOV EBP, ESP
في اتفاقية الاتصال المستخدمة ، يتم إرسال قيمة الإرجاع مرة أخرى عبر EAX
(لذلك 0
هل هناك لأنك كتبت return 0;
- حاول تغيير ذلك إلى return 1;
وانظر كيف يؤثر ذلك على الكود).
MOV EAX, 0
وهذا يخبر المعالج بتنظيف إطار المكدس (وهو ما يعادل MOV ESP, EBP
تليها POP EBP
وهو عكس ما تم القيام به عند إنشاء إطار المكدس):
LEAVE
نصائح أخرى
تقوم الإرشادات بإعداد إطار المكدس على محمل وقت التشغيل الذي يدخل int _main()
وظيفة،
PUSH EBP MOV EBP, ESP
يتم إعداد إطار المكدس وللوصول إلى المعلمات إذا تم توفير أي منها سيتم تعويضه EBP
+ حجم المعلمة (كلمة ، بايت ، طويل ، إلخ).
عادة EAX
السجل هو السجل العادي لإرجاع حالة الخروج من بيئة وقت التشغيل إلى محمل نظام التشغيل ،
MOV EAX, 0 LEAVE
بمعنى آخر ، أن نقول إن البرنامج قد خرج بنجاح من إرجاع 0 إلى نظام التشغيل.
عند استخدام الإرجاع ، تتم استعادة إطار المكدس عند تنفيذ وقت التشغيل قبل تسليم التحكم مرة أخرى إلى نظام التشغيل.
POP EBP
الإجماع العام هو ، في حالة حدوث خطأ ، ستكون القيمة غير صفرية ، ويمكن استخدامها من ملفات الدُفعات (تعود إلى أيام DOS القديمة) و UNIX Scripts حيث يتحقق مما إذا كان البرنامج يعمل بنجاح أم لا ، تابع فصاعدًا اعتمادًا على طبيعة ملف الدُفعات أو البرنامج النصي.
تعليمات "mov eax ، 0 'هي جسم وظيفتك. رمز الرأس هو إعداد مساحة ليتم تشغيل الكود الخاص بك.
تُرجع تعليمات "الإجازة" الكود الخاص بك إلى حيث جاء. على الرغم من أنك لا تقل المكتبات القياسية ، إلا أن هناك الكثير من التعليمات البرمجية الأخرى التي يضعها الرابط في مكانها.