بسم الله الرحمن الرحيم,

أولا أعتذر للجميع عن تأخري في كتابة هذا المقال لإنشغالي بكثير من الأمور في الآونة الأخيرة.

 

في المقالات السابقة, تعرفنا على الهندسة العكسية, و الأدوات المستخدمة في هذا العلم, كما قمنا أيضا ببعض التطبيقات العملية, و قمنا ببرمجة و دراسة برنامجين أحدهما تجاري و الآخر شخصي من كتابتنا, و تعلمنا فيهما كيفية التفكير و البدأ في فهم أو دراسة أو كسر أي حماية لبرنامج ما.

حتى الآن, نحن نسير على نهج أي كورس أو مقال أو تدريب يمكن أن تجده على الشبكة العنكبوتية, فغالبا ما تكون الكورسات و المقالات التي تعلم الهندسة العكسية تطبق المحتوى على برامج فقط تجارية كانت أم شخصية. هذا خطأ شائع, حيث كثير من الناس حينما تسألهم عن الهندسة العكسية, تكون اجابتهم (هو علم كسر حماية البرامج أو فهم البرامج), و هذا المفهوم صحيح نسبيا و ليس كليا. فالهندسة العكسية حينما قمنا بتعريفها في أول مقال, اتفقنا أنها (فك غموض و فهم مشكلة ما), و أتفقنا أيضا أنها لا تسري فقط في مجال الحاسبات, بل تمتد لتشمل جميع نواحي الحياة, من آلات, برمجيات و حتى الكائنات الحية.

اليوم بأذن الله تعالى سنتطرق الى بعد جديد من أبعاد الهندسة العكسية البرمجية, سنقوم بفك غموض ملف نجهله, و سندرسه حتى نصل الى فهم الملف و استخراج كل المعلومات المهمة بداخله. هذا النوع من التطبيقات للهندسة العكسية سنحتاجه كثيرا في كسر حماية الملفات المتحكمة ببرنامج ما. على سبيل المثال الألعاب, كثيرا منا يعلم أن معظم الألعاب تحتوي خاصية حفظ حالة اللعبة (savegame), و هذا يعني أن اللعبة تقوم بحفظ ملف ما في مكان ما بالحاسب, هذا الملف غالبا يكون مجهول البنية الداخلية internal structure, أن استطعنا فهم تلك البنية الداخلية و التعديل عليها, سنتمكن من تغيير بعض القيم في اللعبة, وبهذا استطعنا أن نعدل على اللعبة نفسها بشكل غير مباشر. مثال آخر و هو اذا كنت تريد حذف أو اضافة خصيصة معينة لجهاز تمتلكه, مثلا لنقل جهاز راوتر Network Router أو مستقبل اشارة تلفاز TV Receiver, الكثير من الأجهزة الحديثة -أن لم تكن جميعها- يمكن برمجته من خلال ملف تقوم الشركة المصنعة للجهاز ببرمجته و يسمى الفيرم وير Firmware, غالبا يكون هذا الملف مجهول البنية الداخلية, أن استطعنا دراسة و فهم تلك البنية, سنتمكن من فهم بل و أحيانا التعديل على بعض القيم و الخصائص المتواجدة في الجهاز نفسه.

الملف الذي سنقوم بدراسته بأذن الله هو ملف برمجي لراوتر يربط أجهزة تحكم البرمجية في المصانع PLC Network Router Firmware, لقد قمت باقتطاع الجزء المعقد من الملف لأنه يحتوي على بعض التشفير و بعض التعقيدات التي من الأفضل تركها لدرس تشفيرات الملفات. أيضا سأرفق نسخة من هذا الملف في آخر جزء من المقال (المراجع).

 

الآن معنا الملف الذي نجهل عنه كل شئ, هذا الملف هو فيرم وير Firmware لا نستطيع تنفيذه لنفهم بعض خصائصه لأنه ينفذ على نوع معين من المعالجات Processors (حقيقة نستطيع تنفيذه على محاكي لهذا المعالج على الحاسب ولكن نترك هذا جانبا لأنه خارج نطاق المقال), اذا أمامنا الآن ملف لا نستطيع تنفيذه ولا حتى تحميله على برنامج Disassembler or Debugger لأننا لا نعرف حتى ماذا بداخله. يمكن أن يحتوي هذا الملف على مجموعة ملفات أخرى, يمكن أن يكون مشفر, يمكن أن يكون ملف اعدادات يقرأ و لا ينفذ, الخ… هناك الكثير من الامكانيات, طبعا لن نجلس و نخمن.

الحل الوحيد أمامنا أن نقوم بفتح الملف المجهول من داخل برنامج محرر Editor, ليس محرر نصوص, بل محرر يقوم بفتح أي ملف و قرائته و تحويله لنظام السادس عشري و تسمى تلك المحررات محررات الهيكس Hex Editors. سنقوم بأذن الله باستخدام برنامج File Insight و هو محرر هيكس مجاني من شركة McAfee, حقيقة هذا من أفضل محررات الهيكس التي يمكن أن تراها في حياتك من حيث الأمكانيات و الأدوات التي بداخله, لن أقوم بشرح البرنامج لأننا سنحتاجه فقط في مهمة بسيطة و هى قراءة قيم الهيكس و محاولة استنتاج البنية الداخلية للملف المراد دراسته, و لكنك قطعا ستحتاج هذا البرنامج في الهندسة العكسية كثيرا.

pic1

 

الآن لنقم بفتح ملف الفيرم وير من داخل برنامج File Insight لنرى أن البرنامج قام بقراءة الملف و تحويل القيم بداخله الى Bytes بالنظام السادس عشري Hexadecimal System.

pic2

 

من الطبيعي أن لا نفهم القيم التي أمامنا في البداية, هذا هو المراد من صاحب هذا الفيرم وير, لا يريد لأحد فهم محتواه حتى لا يقوم بالتعديل على أي قيمة بداخله, و هنا يأتي دور الهندسة العكسية. في البداية نرى مجموعة Bytes غير مفهومة, بعضها مقابل لحروف و أرقام نستطيع أن نستنتج من تلك الحروف و الأرقام أنها تعبر عن اسم و موديل الراوتر و رقم اصدار الفيرم وير, هذا لا يهمنا كثيرا في هذا المقال.

اذا نزلنا للأسفل قليلا, نجد اسماء ملفات, و بعد كل اسم مجموعة غير مفهومة من الأرقام.

 

pic3

 

اذا تطلعنا لبعض التشابهات و الفروق بين اسماء الملفات و الارقام التي تليها, نجد أن هذا الجزء مكون من مقاطع Segments, كل مقطع بطول معين مازلنا نجهله, يحتوي كل مقطع على اسم الملف (بطول مازلنا نجهله) و بعض الأرقام المجهولة, ثم ينتهي المقطع و ندخل في مقطع جديد مكون من نفس تلك البنية و هكذا بمجموع 60 ملف. من كثرة تعاملنا في الهندسة العكسية و من الخبرة سنعرف أن أي عدد من الملفات موجودة داخل ملف ما, غالبا ما تكون مقسمة الى مقاطع كما شاهدنا في هذا الملف و كل مقطع يجب أن يحتوي على اسم الملف و عنوان Address اذا ذهبنا اليه سنجد بداية محتوى هذا الملف, و رقم آخر و هو طول الملف بالـ Bytes. اذا طبقنا هذا المنطق على المثال الخاص بنا سنلاحظ أن الملف مقسم لمقاطع, كل مقطع يحوي اسم ملف ما, كما يجب أن يعرف البرنامج الذي سيقرأ ملف الفيرم وير أين يجد محتوى الملفات التي بداخله, فيجب أن نجد عنوان معين (غالبا يكون طوله 4 bytes ) و طول الملف حتي يعلم نهاية الملف الذي يقوم بقرائته حاليا. غالبا نقوم بتحويل البنية التي ندرسها الى بنية بلغة السي ليسهل قراءتها و التعامل معها, فاذا اردنا القيام بهذا على ملف الفيرم وير, نستطيع أن نخمن أن الملف مقسم لمقاطع كل منها بطول 64 bytes ,و بنيته كالتالي.

char Filename[48]; //file name is 48 bytes long

char unknown1[4];  //unknown 4 bytes

char unknown2[4];   //unknown 4 bytes

char FileOffset[4];  //File offset Address in Little Endian format

char FileSize[4];   //File Size in Little Endian format

 

pic4

 

ممتاز جدا, الآن لنجرب ما وصلنا له من نتائج. مثلا لو أردنا رؤية المحتوى الخاص بثاني ملف, لنذهب للمقطع الخاص بثاني ملف home.htm, و نقرأ آخر 4 bytes بنظام الـ Little Endian و هذا نظام تستعمله المعالجات لقراءة القيم من اليمين لليسار, هنالك نظام اخر Big Endian و هو يقرأ القيمة من اليسار لليمين, فمثلا لو عندنا القيمة التالية بالنظام السادس عشري:

001234

بنظام الـ Little Endian, هذا الرقم سيقرأ من المعالج بهذا الشكل 341200 و هو 3412480 بالنظام العشري.

بنظام الـ Big Endian, هذا الرقم سيقرأ من المعالج بهذا الشكل 001234 و هو 4660 بالنظام العشري.

السؤال الآن, كيف علمنا هنا أن المعالج الذي سيقوم بتنفيذ و قراءة هذا الملف سيقرأه بنظام الـ Little Endian ؟

ببساطة علمنا هذا بالمنطق, اذا ذهبنا لمقطع آخر ملف في مجموعة الملفات, سنجد أن محتواه يتواجد عند العنوان:

A01E0300

هذه القيمة لا يمكن أن تقرأ بنظام الـ Big Endian, لأن الملف كله حجمه 0x32B80 فاذا قرأناها بهذا النظام, سيشير الى عنوان غير متواجد اصلا بالملف, اما اذا قرأ بنظام الـ Little Endian, سيكون 0x00031EA0 و هذا العنوان متواجد فعليا في الملف فاذا نستنتج أن كل قيم الأرقام Integers في هذا الملف و على المعالج الذي سيقرأ هذا الفيرم وير سيستخدم نظام الـ Little Endian.

 

الآن نرجع الى home.htm لنقرأ عنوان محتواها لنجده 0xE0120000, بنظام الـ Little Endian يكون 0x000012E0. قبل أن نذهب لهذا العنوان, و أثناء تحليلنا للملف و من خلال التجربة و الخطأ نعرف أنه لنصل لأي عنوان يجب أن نجمع على قيمة العنوان القيمة 0x60 فأذا أردنا الذهاب لمحتوى ملف home.htm سنجد أنه متواجد بالعنوان

0x000012E0 + 0x60 = 0x00001340

اذا ذهبنا لهذا العنوان, نجد فعليا أن هذا العنوان يشير الى بداية محتوى ملف home.htm.

 

pic5

 

الآن نريد أن نستخرج الملفات كلها من ملف الفيرم وير لنبدأ بتحليلها, و لهذا الغرض قمت بكتابة سكيربت بايثون Python Script بسيط ليقوم بهذا العمل بشكل اسرع, سأرفق هذا السكريبت في جزء المراجع في نهاية المقال.

 

بفضل الله أنتهينا من فهم و دراسة ملف الفيرم وير و استخرجنا كل الملفات بداخله. هذا مثال بسيط جدا على تطبيق الهندسة العكسية للملفات المجهولة البنية و غالبا لا تكون الأمور بتلك البساطة. أيضا لاحظنا أن هنالك بعض الـ bytes لم نتمكن من فهمها و هذا أمر طبيعي في حالة أنه أحيانا تكون تلك الـ bytes نوع من انواع اكتشاف الاخطاء error detection و مثل تلك الأمور غالبا لا نحتاج اليها.

 

المراجع:

– ملف Firmware.

– برنامج File Insight.

– سكريبت البايثون Python Script.