0xA. Dynamic Lab
بسم الله الرحمن الرحيم.
في هذا المقال، سوف نقوم بحل تحدي (Lab) بسيط يعتمد بشكل كامل على التحليل الديناميكي (Dynamic Analysis) باستخدام المنقح x64dbg. سنتعلم كيف نتخطى آليات اكتشاف المنقح (Anti-Debugging) وكيف نقوم بتعديل مسار البرنامج (Patching) ليقبل أي مفتاح ندخله.
تجهيز بيئة العمل: يمكنك تحميل الملف التنفيذي الخاص بهذا اللاب من الرابط التالي dyn4m1c_cr4ckm3 في مستودع الدورة كلمة فك الضغط: p01nt
1. الاستطلاع والملاحظة (Reconnaissance)
بدايةً، نفتح موجه الأوامر (CMD) ونقوم بتشغيل البرنامج لنرى ما هي مخرجاته الأولية.
نلاحظ أن البرنامج يتطلب إدخال مفتاح (Arguments) ليعمل.
عند فتح قسم النصوص (Strings) باستخدام أداة PE-Bear، نلاحظ وجود رسالة مثيرة للاهتمام تشير إلى اكتشاف منقح (Debugger Detected).
هذا يعني بوضوح أن هناك دالة حماية داخل الكود تقوم بفحص ما إذا كان البرنامج يعمل تحت بيئة تنقيح أم لا. بالبحث في دوال الاستيراد (Imports)، نجد الدالة التالية:
دالة IsDebuggerPresent هي واجهة برمجية (API) في ويندوز مسؤولة عن اكتشاف ما إذا كان البرنامج يعمل داخل Debugger. سنأخذ هذه المعلومة كأول نقطة ارتكاز لنا.
2. تجهيز بيئة التنقيح (x64dbg Setup)
الآن، نقوم بفتح البرنامج داخل x64dbg. بما أن البرنامج يتطلب تمرير مفتاح (Argument) عند التشغيل، يجب أن نخبر المنقح بذلك:
- من القائمة العلوية، نضغط على
File->Change Command Line. - نضيف بعد مسار البرنامج كلمة اختبارية، مثلاً
test_key.
- نضغط
OK، ثم نضغط على الاختصارCtrl + F2لإعادة تشغيل البرنامج (Restart) وتطبيق الأمر السابق.
نضغط الآن على المفتاح F9 (Run) لنجعل البرنامج ينفذ التعليمات الأولية للنظام حتى يتوقف عند نقطة الإدخال الرئيسية للبرنامج (Entry Point)، حيث سيظهر لنا اسم البرنامج في التعليقات.
3. تخطي حماية المنقح (Bypassing Anti-Debugging)
نريد الآن إيجاد المكان الذي يتحقق فيه البرنامج من وجود المنقح لنقوم بتعطيله.
- نضغط
Right-Click(كليك يمين) داخل مربع عرض الأكواد (CPU Window).
نختار:
Search for->Current Module->String References.في نافذة النصوص التي ستظهر، نبحث عن رسالة
Debugger detectedوننقر عليها نقراً مزدوجاً للانتقال إلى مكانها في الكود.
إذا نظرنا إلى الأسطر التي تسبق هذه الرسالة، سنرى أنه يتم استدعاء دالة IsDebuggerPresent، وبعدها مباشرة يقوم البرنامج بعمل test للنتيجة ليكتشف هل نحن نعمل على Debugger أم لا، يليه قفز شرطي (je - Jump if Equal).
عملية الترقيع (Patching): الآن سنتلاعب بهذا القفز الشرطي لنعكس المنطق تماماً.
- ننقر نقرة واحدة على تعليمة
je، ثم نضغط على زرSpace(مسطرة) لفتح نافذة التعديل (Edit Instruction).
- نقوم بتغيير التعليمة من
je(اقفز إذا كان مساوياً) إلىjne(اقفز إذا لم يكن مساوياً).
نتأكد من ظهور رسالة Instruction encoded successfully في الأسفل، مما يعني أن التعديل قد تم بنجاح في الذاكرة. بهذا نكون قد أعمينا البرنامج، ولن يكتشف أننا نقوم بتحليله!
4. تحليل دالة التحقق والتعديل النهائي (The Core Logic)
نعود الآن إلى نافذة النصوص (String References) مرة أخرى. هذه المرة، نبحث عن رسالة النجاح (Success Message) وننتقل إليها.
بالنظر إلى الكود الذي يسبق رسالة النجاح، نلاحظ استدعاء لدالة strcmp (وهي الدالة البرمجية الشهيرة التي تقوم بمقارنة نصين ببعضهما: المفتاح الأصلي والمفتاح الذي أدخلناه).
ننقر على تعليمة الـ call الخاصة بـ strcmp ونضغط F2 لوضع نقطة توقف (Breakpoint) عندها (سيتحول لون العنوان إلى الأحمر).
نضغط الآن على F9 (Run) مرة أو أكثر حتى يصل تنفيذ البرنامج إلى نقطة التوقف هذه. ملاحظة: البرنامج سيتخطى فحص الـ Debugger بنجاح بفضل التعديل الذي قمنا به سابقاً، ويمكنك رؤية ذلك في نافذة الـ CMD المرافقة لـ x64dbg.
كشف المفتاح (Leaking the Key)
قبل تنفيذ الاستدعاء لدالة strcmp مباشرة، إذا نظرنا إلى نافذة المسجلات (Registers) أو الـ Stack، سنرى أنه تم تمرير قيمتين للدالة:
- المفتاح التجريبي الذي أدخلناه (
test_key). - المفتاح الأصلي الصحيح المخزن في الذاكرة!
تعديل منطق القفز (Forcing Success)
نضغط الآن F8 (Step Over) لتنفيذ دالة المقارنة وتخطيها. مباشرة بعد دالة المقارنة، سنجد تعليمة test eax, eax تليها تعليمة قفز شرطي jne (والتي ستقفز إلى رسالة الفشل لأن مفتاحنا خاطئ).
سنقوم بعمل Patch آخر هنا: ننقر على jne ونضغط Space، ثم نغيرها إلى je. نضغط F8 للمتابعة. نلاحظ أن علم التصفير (Zero Flag - ZF) يساوي الصفر، وبسبب تغييرنا للتعليمة إلى je، فإن البرنامج سيعتبر أن المقارنة نجحت وسيقفز باتجاه رسالة النجاح.
نستمر بالضغط على F8 حتى نصل إلى استدعاء دالة memset أو نهاية الإجراء.
إذا ألقينا نظرة على نافذة الـ CMD الآن:
نحن الآن طبقنا مفهوم الـ Patching بنجاح، لأن البرنامج أعطانا رسالة “النجاح” بالرغم من أن المفتاح الذي أدخلناه (test_key) كان خاطئاً!
5. تأكيد المفتاح الأصلي
إذا أردنا التأكد من عملنا بشكل سليم بدون Patching، يمكننا أخذ المفتاح الأصلي الذي اكتشفناه في الذاكرة أثناء التحليل قبل استدعاء strcmp، ونقوم بتشغيل البرنامج من الـ CMD بشكل طبيعي وتمرير هذا المفتاح له.
تهانينا! لقد قمت للتو بهندسة برنامج عكسياً، تخطيت حماية المنقح، عدلت المنطق البرمجي، واستخرجت المفتاح السري بنجاح.

















