الهندسة العكسية لملفات الحاسب التنفيذية – الجزء الأول

رغبتك بقراءة هذه المقالة تعني أنك تعرف مسبقاً كيفية التعامل مع نظام الأرقام السداسي عشري Hexadecimal وتعرف ما يكفي عن بنية الكمبيوتر Computer Architecture، وأن لديك خلفية جيدة في لغة الأسمبلي (لغة التجميع) وفي مبادئ عمل المعالج. إن لم تكن لديك أي خلفية أو معرفة مسبقة بذلك، فلا أنصحك بمتابعة القراءة حتى تصبح لديك خلفية جيدة بذلك كله.

تم تجميع أغلب المعلومات المذكورة هنا من مصادر مختلفة أهمها مجلة CodeBreaker Magazine والتي ظهرت لفترة ليست بالقصيرة على الإنترنت، وكانت تحتوي على معلومات وافرة بخصوص أنظمة التشغيل المختلفة وطرق متابعة عملها وكيفية التعامل مع ملفاتها. قد تحدث الكاتب Goppit في إحدى مقالات المجلة بشكل مفصل عن صيغة الملفات التنفيذية في نظام تشغيل ويندوز. و 55% من المعلومات المذكورة هنا قد تمت ترجمتها من تلك المقالة.

كما يشير عنوان هذه المقالة فالموضوع المشروح هنا هو صيغة الملفات التنفيذية أو ذاتية التشغيل Portable Executable File Format ، أو ملفات PE  كإختصار ، على نظام تشغيل ويندوز في بيئة الـ 32 بت Win32 وتنطبق نفس المفاهيم على بيئة ال64 بت. ما هي هذه الملفات؟ كيف يتم تنفيذها من قبل نظام التشغيل وكيف يتم معالجتها؟ لماذا تعطى تلك الأهمية؟ وهل نستطيع أن نتلاعب بها؟

ربما قد لاحظت أثناء استخدامك لجهاز الحاسب بأن هنالك صيغة واحدة فقط لأي ملف يمكنك تشغيله على جهازك، فلو كنت تستعمل نظام الويندوز فإنك الآن تستخدم برنامج المتصفح والذي قد يكون  Chrome.exe أو Firefox.exe أو Explorer.exe. لاحظ معي أنه لولا امتلاكك لبرنامج من هذا النوع والذي ينتهي بالصيغة exe لما كنت قادراً على فتح صفحات الإنترنت كما تفعل الآن. كذلك الحال مع ملفات الورد .Docx أو  .Doc وملفات الفيديو .avi أو .mkv  أو .mp4 وصفحات الإنترنت .html ما كنت لتستطيع أن تقرأ أي من هذه الملفات لولا امتلاكك لبرامج تشغيل لها تنتهي بصيغة ملف تنفيذي مثل Microsoft Word.exe  أو VLC.exe  أو Photoshop.exe. ما أُريدك أن تلاحظه هنا هو أن جهازك لا يقوم إلا بتشغيل نوع واحد من الملفات فقط، وهذا الملف بدوره قد يملك القدرة على تشغيل صيغ أُخرى حسب رغبة المبرمج الذي قام بكتابته. فقارئ الملفات Adobe Reader.exe كمثال هو من يسمح لك بتشغيل الملفات ذات الصيغة .pdf وهكذا.

في نظام التشغيل ويندوز 32 (أفترض انك تعرف ما المقصود بـنظام يعمل في بيئة 32 بت أو 64 بت) فإن هذه الملفات يُطلق عليها Portable Executable Files أو الملفات ذاتية التنفيذ. وهذه الملفات تشمل الصيغ التالية :

ملفات .Net  و ملفات CPL  و OCX controls  و ملفات  COM و .sys و .dll وبالتأكيد ملفات .exe

ربما قد تكون أغلب هذه الصيغ جديدة عليك، وربما لم تتعامل إلا مع آخر اثنين منها، ربما لاحظت أن ملفات الـربط الديناميكي dll وملفات ربط وتضمين الأجسام (Object Linking and Embedding OCX) لا تعمل بنفسها كما هو الحال مع ملفات الـ EXE ، بل إنها تعمل داخل ملف تنفيذي آخر عندما يقوم باستدعائها أثناء تشغيله كما سيتضح لاحقاً. ملفات DLL تُصنف مع ملفات الـ PE لأن لها نفس التنسيق أو ترتيب الأوامر كما سترى في الأجزاء اللاحقة من هذه المقالة.

من الجدير بالذكر أن العديد من أنظمة التشغيل تقوم باستخدام نفس صيغة ملفات الـPE  (والتي سنتعرف عليها بالتفصيل) الموجودة في الويندوز مثل نظام  ReactOS، كما أن الأنظمة الشبيهة باليونكس Unix-like systems تملك برنامج خاص يدعى Wine والذي يسمح لملفات الـ PE التي تمت كتابتها للويندوز بأن تعمل عليها.

ملفات الـ PE هي الوحيدة التي لها القدرة على العمل مباشرةً في نظام مايكروسوفت ويندوز، وكذلك الحال مع الأنظمة الأخرى، فكل نظام تشغيل لديه نوع أو صيغة ملفات خاصة تكون هي الصيغة الأساسية التي يسمح لها نظام التشغيل بالعمل داخل المعالج. فتوزيعه يونكس Unix لديها الملفات التنفيذية التي تدعى (Executable and Linkable Format) ELF والتي تسمح لها بالعمل عليها. من الجدير  بالذكر أن نظام ملفات ELF معروف بمرونته وعدم ارتباط طريقة عمله بأي معالج معين مما سمح للعديد من أنظمة التشغيل المشهورة بأن تتخذه كنظام ملفات رئيسي لديها. من الأنظمة التي تتخذ ELF كنظام الملفات لها:

من توزيعه يونكس:

  • Linux
  • Solaris
  • IRIX
  • FreeBSD
  • NetBSD
  • OpenBSD
  • DragonFly BSD
  • Syllable
  • HP-UXH

من الأنظمة الأخرى:

  • OpenVMS

بعض الألعاب التي تعمل تحت شاشة الكونسول consoles:

  • PlayStation 2H, PlayStation 3
  • Wii
  • GP2XH.
  • Dreamcast

 العديد من أنظمة التشغيل في الجوالات تستخدم صيغة ملفاتELF منها:

  • Symbian OSH v9
  • W800iH, W610H, W300 :Sony Ericsson
  • E398, SLVR L7, v360, v3i :Motorola

يجب أن تعرف أيضاً أن هنالك العديد من الأدوات التي يمكنها أن تحول ملف تنفيذي كُتب لنظام تشغيل معين لكي يعمل على نظام تشغيل آخر.

نستكمل بقية المقال بعرض تفصيلي لجدول محتوياته:

1. مقدمة

2. البنية الأساسية لملفات الـ PE   

3. واجهة الدوس  Dos Header  

4. واجهة ملف الـ PE

5. دلـيل البيانات Data Directory  

6. جدول الأقسام Section Table  

7. أقسام ملف الـ PE

8. نظرة في قلب البرامج

9.  واجهات برمجة التطبيقات في الويندوز Windows 32 APIs  

10. قسم البيانات الصادرة Export data  

20. قسم البيانات الواردة Import data  

  1. مقدمة:

جرب أن تفتح أي ملف على جهازك ببرنامج المفكرة، الصورة التالية لملف فيديو بصيغة MP4 تم فتحه ببرنامج المفكرة:

صورة رقم 1

ترى في الصورة بعض الكلمات والمصطلحات الواضحة والتي تم تظليلها بالون الوردي. وعند فتح ملف آخر بنفس الصيغة MP4 نرى الآتي:

صورة رقم 2

نفس المصطلحات موجودة في ملف الفيديو الأول موجودة ايضاً في الفيديو الثاني، هكذا فإنك تستنتج فوراً أن هنالك بنية أساسية أو تركيبة معينة لكل ملفات الفيديو من صيغة MP4 وهذا حتى تتمكن جميع مشغلات الفيديو دون استثناء من قراءتها.  فلو كان لهذا النوع من الملفات تركيبة معنية لم تُنشر من قِبل الشركة أو المؤسسة المنتجة لهذه الصيغة، فلن يتمكن أي شخص من برمجة قارئ لهذه الصيغة سوى الشركة المنتجة بالإضافة لخبراء الهندسة العكسية الذين يتمكنون من فك وفهم تركيبة الملف.

بالنسبة لملفات MP4 ،أو ما تسمى أيضاً بـ MPEG-4 Part 14 ،فإنها حاوي لملفات الملتيميديا Multimedia Container Format تم تطويره من قبل المنظمة الدولية لتوحيد المعايير   International Organization For Standardization (ISO)

صورة رقم 3

لكي تعرف ما الذي تعنيه تلك الكلمات والرموز الموجودة في الصورة رقم 1 والصورة رقم 2، عليك أن تحول الحروف إلى ما يقابلها من أرقام باستخدام جدول الأسكي ASCII Code والذي سيتم شرحه لاحقاً، ومنه نحصل على الآتي:

صورة رقم 4

الصورة رقم 4 توضح تحويل النص العادي إلى ما يقابله من أرقام في النظام السداسي عشر عن طريق برنامج Hex WorkShop. تُلاحظ أن هنالك بعض الرموز الموجودة في المفكرة ولا توجد في النص على يمين الصورة رقم 4، وهذا لأن برنامج Hex WorkShop مضبوط لكي يحول الحروف والأرقام فقط دون الرموز، كما أن المفكرة عندي مضبوطة على ترميز ANSI وجهازي يدعم اللغة العربية، أي أن هنالك بعض الرموز الموجودة في جدول الأسكي يستبدلها جهازي برموز أخرى عربية، سيتم توضيح كل هذا لاحقاً. المهم الآن أن تعرف أن كل رقمان في النظام السداسي عشر يمثلان بايت واحد أو حرفاً واحداً من جدول الأسكي.

صيغة ملفات MPEG-4 تتكون من عدة وحدات منفصلة تدعى الأنوية ، كل نواة عبارة عن مجموعة من التعليمات أو المعلومات المكتوبة في الملف. ففي الصورة رقم 4 نرى بداية النواة المظللة بالون البرتقالي في أعلى يسار الصورة وهي تبين طول النواة، الرقم 18 بالنظام السداسي عشر يساوي 24 بالنظام العشري (يمكنك التحويل بسهولة باستخدام الآلة الحاسبة الموجودة في الويندوز)، أي أن أول نواة تتكون من 24 بايت، أول بايت يبدأ من أول صفريين موجودان في خانة طول النواة، عد من هنالك 24 بايت، وتذكر أن كل رقمين يشيران إلى بايت واحد، بعد النواة الأولى (أي بعد 24 بايت من بداية الملف) تبدأ النواة الثانية بطول النواة مرة أخرى، وهي ثاني خانة مظللة باللون البرتقالي، الرقم الذي يشير إلى طول النواة والمظلل باللون البرتقالي يمثل 4 بايت. اللون البنفسجي يشير إلى اسم كل نواة ويأتي بعد طول النواة. طبعاً نفس الإجراء موجود في الصورة رقم 1 والصورة رقم 2، اللون الأخضر يشير إلى طول النواة بعد تحويله إلى الكلمة الموازية له من جدول الأسكي. تلاحظ أن ملفي الفيديو في الصورة رقم 1 والصورة رقم 2 لهم طول نواة مختلف، وهو شيء متوقع فهما ملفان مختلفان. الهدف من هذه الجزئية من الموضوع هو توضيح أن كل ملف ذو صيغة معينة له ترتيب معين لتعليماته وأكواده، وما أن يعرف المبرمج على هذا الترتيب وما معناه، فإنه يستطيع كتابة برنامج لقراءة هذا الملف. لكن تذكر أن الملفات الوحيدة التي يمكنها العمل في نظام تشغيل الويندوز هي الـ PE، وباقي الصيغ والملفات تعمل تحت تلك الملفات، أي أن من يقرأ صيغة ملفات الفيديو التي قمنا بدراستها في الصورة رقم 1 والصورة رقم 2 هو  برنامج قارئ ملفات الفيديو، ومن يقرأ برنامج قراء ملفات الفيديو بعد أن يقوم المستخدم بفتحه هو نظام التشغيل.

قد يسأل البعض، لماذا من المهم أن نتعرف على صيغة ملفات الـ PE؟ هنالك سببين مهمين يدفعون المبرمجين والمختصين لدراسة صيغة هذه الملفات: 1- دراسة طريقة عمل برنامج معين بغرض فهم كيفية قيام مبرمجه بعمل إجراء معين، أو إضافة وظيفة أخرى للبرنامج، أو لكسره إن كان البرنامج لا يعطيك صلاحية العمل حتى تصبح مسجلاً فيه وتملك رقم تسجيل( serial number ) خاص بك. 2- دائماً ما يقوم المبرمجون و منتجو برامج الحاسوب  بعمل ما يسمى (حزم أو packing ) لبرامجهم في سبيل ضغطها لتصغير حجمها، وكذلك حمايتها ممن يريد كسرها، ولكي تتمكن من فك هذا التحزيم (unpacking) عليك أن تعرف كيف يعمل البرنامج.

جميع الأمثلة التي سيتم استخدامها في الشرح خلال هذا المستند هي برامج معروفة يمكن تحمليها بسهولة من الإنترنت. لكن أهم ما ستحتاجه لتتمكن من تحليل البرامج بفعالية هو برنامج Hex WorkShop :

صورة رقم 5

برنامج Hex WorkShop يسمح لك بمشاهدة لغة الآلة الأصلية المكتوب فيها أي برنامج على جهازك، عملياً فإنه يقوم بنفس وظيفة برنامج المفكرة عدا أن المفكرة تُريك البرنامج بتحويل لغة الآلة إلى حروف وأرقام تبعاً لجدول الأسكي ASCII Code أو الترميز التي تم ضبطها عليه. برنامج Hex Workshop يُظهر الكتابة بالنظام السداسي عشري (Hexadecimal) لأنها أسهل بكثير من قراءة لغة الآلة الأصلية والتي هي عبارة عن أحاد وأصفار بطول البرنامج، كما أنه من السهل جداً التحويل بين النظام السداسي عشر والنظام الثنائي (لغة الآحاد  والأصفار).

هذه مقارنة لبرنامج تم فتحه بالمفكرة وبرنامج Hex WorkShop:

صورة رقم 6

تم فتح برنامج Acrobat باستخدام محرر الهيكس Hex WorkShop (يسمى بمحرر الهيكس لأنه يقوم بتحليل الملفات بالنظام السداسي عشر Hexadecimal) وباستخدام برنامج المفكرة لكي نعرف الفرق في طريقة تحليل كل منهما.  لاحظ أن محرر الهيكس يعرض لنا أيضاً شاشة خاصة على اليمين تترجم البرنامج بالآسكي ASCII Code تبعاً للجدول التالي:

صورة رقم 7

هنا أريد أن أوضح فقط أن المفكرة تعمل تماماً كبرنامج Hex WorkShop عدا أنها تترجم البرنامج المكتوب تبعاً للترميز الذي تم ضبطها عليه. عند الضغط على حفظ الملف Save as سترى أنه يمكنك اختيار ترميز الملف Encoding الذي ترغب فيه:

صورة رقم 8

هنالك العديد من المشاكل التي ظهرت بسبب اختيار ترميز الملفات المناسب الذي يجب أن يكون معياراً في جميع أجهزة الكمبيوتر. المقصود بالترميز هو الرقم بلغة الآلة الذي يوازي كل حرف من حروف الأبجدية. ففي نظام الأسكي مثلاً (والذي ظهر منذ بداية عهد الكمبيوتر) في الصورة رقم 7 ترى أن هناك 128 رقم كل واحد منها يمثل حرف من حروف الأبجدية، لكن الجميع يعلم أن مجموع كل الحروف والأرقام والرموز من كل اللغات أكثر بكثير من 128. ولهذا دعت الحاجة إلى إيجاد نظام يتوافق مع جميع اللغات إما بزيادة عدد الأرقام وبالتالي زيادة عدة الحروف المسموح بها، أو بإيجاد طريقة لتشمل حروف أكثر بأرقام أقل. بالطبع هنالك أمور تقنية تتعلق بزيادة الأرقام وتتمثل بعدد الخانات التي يمكن تمثيل هذه الأرقام بها، فالأسكي تستخدم 8 خانات أو 8 بت لتمثيل أي حرف كما هو واضح في الصورة رقم 9 (كل رقم بالنظام السداسي عشر يمثل أربع أرقام بالنظام الثنائي، 1 = 0001، 5 = 0101، 1011 = A ، بالتالي كل رقمين في النظام السداسي عشر يمثلان 8 خانات أو 8 أرقام بالنظام الثنائي)، لكني لن أتطرق لهذه النقطة لافتراضي أن القارئ لديه خلفية عنها.

نظام الأسكي يحتوي فقط على الحروف اللاتينية (الحروف الإنجليزية المعروفة) مما سبب العديد من المشاكل في الدول غير الإنجليزية. كما أنه حتى وقت قريب كانت الأجهزة تستخدم نظام الـ ANSI والذي يوفر خطوط تحتوي على 256 حرف، أول 128 منها هي حروف الأسكي مما يحل مشكلة الترميز في الولايات المتحدة وكندا و بريطانيا، ولكن بقية الحروف في هذا الترميز لا تكفي كل لغات العالم. الحروف المتبقية بعد الأول 128 حرف تم استخدامها لعلامات الترقيم وعلامات الأموال مثل ¥ و £ والكثير من الحروف مثل á, ç, è, ñ, ô و ü. أما في الدول غير الإنجليزية مثل مصر وروسيا وإسرائيل فقد تم استبدال هذه الحروف الأخيرة بحروف أخرى من لغتهم. لكن هذا أيضاً بدوره سبب مشكلة في قراءة هذه الحروف، فجهازي مثلاً مُجهز لقراءة الحروف العربية والإنجليزية (أي استبدال أخر 128 رقم بحروف عربية) لكنه لا يدعم اللغة العبرية (أي أنني أستطيع التحويل بين العربية والإنجليزية فقط ولم أقم بتثبيت العبرية في جهازي) فلا أستطيع قراءة صفحات الإنترنت ورسائل البريد المكتوبة بالعبرية أو الصينية أو اليابانية5.

صورة رقم 9

مع كثرة المشاكل في استخدام نظام ANSI وُجد أن أفضل حل هو التخلي عن الـ 8 خانات، أو 8 بت، المستخدمة في الـ ANSI والانتقال إلى نظام آخر يعين رمز واحد لكل حرف في العالم. هذا النظام يدعى Unicode وقد تم تطوره ليعمل في جميع أنظمة الحاسب وليس فقط في نظام الويندوز. مما يجب أن تعرفه أن هذا النظام تم إدخاله في نظام تشغيل مايكروسوفت ويندوز Microsoft Windows منذ الإصدار Windows 95 و Windows NT 4 وما زال مستمراً حتى الآن في Windows 7. نظام الـ Unicode يستخدم 16 خانة، أو 16 بت، للتعبير عن الحروف، لذلك يظن البعض أنه يسمح لنا بتكوين 216 = 65536 حرف. ولكن يجب أن تدرك أن هذا ليس صحيح كلياً، فنظام الـ Unicode لديه القدرة على تكوين أكثر من مليون حرف مختلف.

الآن  وبعد أن أصبح لديك فكرة أوضح عن ترميز الملفات والنصوص، يمكنك أن تفهم الفرق بين ترجمة محرر الهيكس Hex WorkShop والمفكرة لنفس الملف. وسبب اختلاف بعض الرموز التي أظهرتها المفكرة في هذه العملية. هذه كانت بالكامل مقدمة لا تتصل كثيراً بموضوعنا الأساسي وهو صيغة ملفات الـ PE، لكن عليك أن تقرأها لتفهم ولو بشكل بسيط طريقة تحليلنا لملفات الـ PE كما سيأتي لاحقاً.

ولكي تستوعب فكرة أن كل التعليمات الموجودة في أي ملف PE يمكن قراءتها باستخدام محرر الهيكس، انظر إلى حجم أي ملف PE في جهازك وليكن برنامج الآلة الحاسبة المدعو BASECALC والذي يمكنك تحميله من هنا.  سترى من خصائص ملف هذا البرنامج أن حجمه بالضبط 229,888 بايت:

صورة رقم 10

والآن افتح البرنامج بمحرر الهيكس Hex WorkShop واذهب إلى آخر الملف كما في الصورة:

صورة رقم 11

كما هو مبين في الصورة، الأرقام على اليسار تُشير إلى رقم البايت بالنسبة لبداية الملف، والأرقام التي في النصف هي بيانات الملف، أو لغة الآلة التي كُتب فيها الملف.  كل الأرقام توجد في النظام السداسي عشر، بالتالي كل رقمين معاً من الأرقام التي توجد في المنتصف يشكلان بايت واحد.  أول بايت في هذا الملف يوجد في الخانة صفر، وآخر بايت يوجد في الخانة 381FF ( أي أن قيمته هي 381FF من أول الملف) بالنظام السداسي عشر. بالتالي عدد البايتات في الملف السابق هو 00382 (البايت رقم صفر 381FF = 0 + 381FF). قم بتحويل هذا الرقم إلى النظام العشري والذي هو نظامنا العادي في العد (يُمكنك استخدام البرنامج نفسه في التحويل، أو الآلة الحاسبة الموجودة في الويندوز) وسترى أن قيمته هي 229,888 والتي هي نفس حجم الملف. ما أُحاول أن أُوضحه هو أن كل بيانات الملف التي تشكل حجم الملف بالكامل هي عبارة عن الأرقام بالنظام السداسي عشر الموجودة في الخانة التي في المنتصف في برنامج محرر الهيكس وأن أي تغيير فيها يمكن أ ن يغير عمل البرنامج بالكامل.

يمكنك تحميل برنامج Hex WorkShop من هنا، لكن يجب أن تعرف بأنه ليس مجاني بالكامل.

2. البنية الأساسية لملفات الـ PE :

المقصود بالبنية الأساسية لملفات الـ PE هو توزيع وترتيب ومعنى الأرقام أو لغة الآلة التي نراها عند فتح أي ملف ذاتي التنفيذ PE باستخدام محرر الهيكس و هي التي يعمل البرنامج ويقوم بأداء وظيفته تبعاً لها. أي ملف PE على جهازك  يتكون من الأجزاء على العناصر التالية:

صورة رقم 12

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

الصورة رقم 12 تبين ترتيب التعليمات أو الأكواد في أي ملف PE أثناء وجوده في القرص الصلب وهو نفس الترتيب الذي نراه عند فتح البرنامج باستخدام محرر الهيكس وسيأتي شرحه لاحقاً. لكن عند تشغيل البرنامج فأنه يتم تحميله إلى ذاكرة الكمبيوتر لكي يبدأ تنفيذه. مُحمل البرامج في الويندوز Windows Loader هو المسئول عن تحميل أي برنامج من القرص الصلب إلى ذاكرة الكمبيوتر RAM. بشكل عام، محمل البرامج هو جزء من أي نظام تشغيل ويلعب دور مهم في عملية تشغيل أي برنامج. فهو يقوم بنقل البرنامج من القرص الصلب إلى ذاكرة الكمبيوتر ويقوم بالإعدادات اللازمة لكي يتم تنفيذه. عملية تحميل البرنامج إلى الذاكرة تشمل قراءة محتويات الملف التنفيذي (أي قراءة الأجزاء الموجودة في الصورة رقم 12) ثم نقلها إلى الذاكرة، وما إن تتم عملية النقل هذه، يقوم نظام التشغيل بإعطاء التحكم إلى البرنامج الذي تم تحميله وسيتم توضيح هذه النقطة  أكثر فيما بعد. كل أنظمة التشغيل التي تدعم خاصية تحميل البرامج إلى الذاكرة لكي يتم تنفيذها تملك ما يسمى (محمل برامج loader). ترتيب الأكواد أو التعليمات الموجودة في مختلف أجزاء ملف الـ PE الموضحة في الصورة رقم 12 يبقى كما هو عند تحميل الملف إلى ذاكرة الكمبيوتر. أي أنك إذا استطعت تحديد مكان معلومة أو نص في ملف الـ PE أثناء وجوده على القرص الصلب باستخدام محرر هيكس أو غيره، فإنك تستطيع تحديد نفس مكان المعلومة عند تحميل الملف في الذاكرة. لكن تجدر الإشارة أنه عند تحميل البرنامج إلى الذاكرة، فإن محمل الويندوز Windows Loader لا يأخذ الأقسام بنفس الترتيب إلى الذاكرة، بل إنه يحدد أي الأجزاء يجب أن يتم تحميلها ثم يقوم بوضع بقية الأجزاء التي لم تُحمل في نهاية كل الأقسام. فمثلاً قد يتم تخصيص أحد الأقسام Sections الموجودة في الصورة رقم 12 لجمع المعلومات الخاصة بمتابعة عمل البرنامج في الذاكرةDebug Information، غالباً ما يعد هذا القسم غير مهم وبالتالي يقوم محمل البرامج في الويندوز بوضعه في نهاية الملف بعد تحميله في الذاكرة. ما زال هناك شيء آخر يجب أن تعرفه بالنسبة لنقل الملفات من القرص الصلب على الذاكرة وهو خاصية ترحيل أجزاء من الذاكرة إلى القرص الصلب Paging. خاصية الترحيل Paging تُعتبر خاصية من خواص إدارة الذاكرة Memory Management والتي يكون نظام التشغيل المستخدم مسئول عنها. تعمل هذه الخاصية جنباً إلى جنب مع خاصية أخرى تدعى الذاكرة الظاهرية Virtual Memory وسوف يتم شرح الخاصيتان .

الذاكرة الظاهرية أو الذاكرة المرئية تُعتبر موضوع مربك جداً للكثير من مستعملي الكمبيوتر وهذا بسبب ضُعف الشرح الذي وفرته مايكروسوفت في هذا الشأن. الذاكرة الظاهرية هي نظام يوفر بيئة وهمية للبرامج بحيث يجعلها لا تعتمد على أجزاء الجهاز الحقيقية. قلنا سابقاً أن أي برنامج يتم فتحه يُنقل بالكامل إلى ذاكرة الكمبيوتر، لكنه لا يعرف أين موقعه بالضبط في الذاكرة الحقيقية. فعند تشغيل أي برنامج، يقوم نظام التشغيل بإهام البرنامج بأن لديه مساحة 2 جيجا بايت في الذاكرة متوفرة له، بغض النظر عن حجم الذاكرة الحقيقي. الصورة التالية توضح الفكرة أكثر:

الصورة رقم 13

الصورة السابقة تُظهر الذاكرة الظاهرية التي ينشئها نظام التشغيل لأي برنامج يتم فتحه، وكيف أن نظام التشغيل هو من يقوم بتحديد مكان هذه الذاكرة الظاهرية في الذاكرة الحقيقية RAM والذي لا يكون عادةً بنفس العنوان أو المكان الحقيقي. الفائدة من ذلك هو عزل البرامج الموجودة في الكمبيوتر ومنعها من التأثير مباشرةً في أجزاء الحاسوب وكذلك منعها من التأثير على بعضها البعض. الصورة توضح أيضاً جانب آخر من هذه العملية. لابد أنك تتساءل الآن، إن كان نظام التشغيل يُخبر كل برنامج بأن لديه مساحة 2 جيجابايت متوفرة للاستخدام، ماذا يحدث إن كان هذا أكثر من المساحة الكلية لذاكرة الحاسوب الحقيقية في حال ما إن كان حجم الرام أقل من 2 جيجابايت أو أن المستخدم قام بتشغيل أكثر من برنامج على نفس الجهاز؟ هنا يأتي دور خاصية الترحيل التي تم ذكرها سابقا ً. ذاكرة الكمبيوتر الحقيقية RAM محدودة بينما الذاكرة الظاهرية ليست كذلك. فقد يقوم المستخدم بتشغيل الكثير من العمليات Processes (العملية Process هي المساحة التي يشغلها أي برنامج من الذاكرة عند تشغيله) كل منها لديه مساحة 2 جيجابايت ظاهرياً. عندما تتعدى مساحة العمليات مساحة الذاكرة الحقيقية فإن نظام التشغيل يقوم بنقل صفحات من الذاكرة Pages إلى القرص الصلب. الصفحة الواحدة عبارة عن 4 كيلوبايت من الذاكرة، يقوم نظام التشغيل بتحديد أي صفحة من الذاكرة أقل استخداماً أو لا تملك الأولوية، فيقوم بنقلها إلى ملف خاص في القرص الصلب يدعى pagefile.sys. بالتالي يسمح للبرنامج ذو الأولوية الأعلى باستخدام تلك المساحة الفارغة. وفي حالة قام البرنامج الذي تم نقل صفحة منه بطلب أو إجراء يحتاج إلى تلك الصفحة فإن نظام التشغيل يقوم بتفريغ صفحة أخرى ذات أولوية منخفضة ليسمح بعودة الصفحة الأولى لمكانها.

عند فتح أي برنامج وإعطاءه ذاكرة ظاهرية فإن نظام التشغيل بالتعاون مع المعالج يقوم تخطيط أو تحديد موقع هذه المساحة الظاهرية في الذاكرة الحقيقية كما هو موضح في الصورة رقم 13.  إذاَ البرامج ترى فقط الذاكرة الظاهرية ولا تعرف شيئاً عن الحقيقية، لكن هذا لا يغير شيئاً في طريقة تعاملنا مع البرنامج أو في طريقة تحليلنا له في القرص الصلب أو الذاكرة. وهذا شيء مريح لأن الفكرة وطريقة تنفيذها قد تكون محيرة أو غير واضحة بالنسبة لك إن لم تكن لديك أي فكرة عن بناء الكمبيوتر Computer Architecture أو المعالجات Microprocessors. لكن كما ذكرتُ سابقاً، نحن سنتعامل مع أي برنامج ونقوم بتحليله كما لو أن الذاكرة ظاهرية وخاصية تحميل صفحات الذاكرة إلى القرص الصلب ليستا موجودتين. فكل هذا يتم في نظام التشغيل والمعالج ولا يراه أو يتأثر فيه المستخدم إلا ربما في أمور بسيطة سيتم ذكرها في حال الوصول إليها، كما أنك لو قمت بتغير جزء من كود البرنامج أثناء وجوده في القرص الصلب أو وتلاعبت به أثناء وجوده بالذاكرة دون أي أخذ في الاعتبار بشأن الذاكرة الظاهرية فإن تصرف البرنامج سيتغير حسب رغبتك دون مشاكل. آخر نقطتين يجب أن تعرفهم في هذا الشأن هما الآتي:

  1. فكرة وجود صفحات في الذاكرة تعتبر ضرورية لملفات الـ PE لأن هنالك صلاحيات مختلفة للأقسام الموجودة في ملف الـ PE كمافي الصورة رقم 12. فقد يملك القسم صلاحية القراءة فقط دون الكتابة أو صلاحية الكتابة والقراءة، وبهذا بقوم نظام التشغيل بتحميل قسم الملف في صفحة ذاكرة معينة ويعطي تلك الصفحة صلاحية مماثلة لصلاحية الملف. طبعاً الرمز أو الكود الذي يحدد صلاحية قسم معين موجود في جدول الأقسام المذكور في الصورة رقم 12 وسيتم شرحه بالتفصيل لاحقاً
  • توزيع الأقسام في الملف على القرص الصلب مختلف عما هو عليه في الذاكرة ، كل صفحة في الذاكرة تأخذ 4 كيلوبايت مما يسهل تفريق الأقسام في الذاكرة، فكل قسم يبدأ عند حدود 4 كيلوبايت جديدة. لكن أثناء تواجد الملف في القرص الصلب فإن إتباع نفس الأسلوب سيكون مضيعة كبيرة للمساحة. لذلك فإن هنالك في واجهة ملف الـ PE خانتان أو عنصران يحددان توزيع الأقسام في الملف أثناء تواجده في القرص الصلب وترتيبه في الذاكرة. نظام التشغيل يستخدم هاتان الخانتان ليتعرف على مكان الأقسام في القرص الصلب ومن ثم يحدد موقعهما الجديد تماماً في الذاكرة. سيأتي شرح هاتان الخانتان مع الأمثلة لاحقاً.

الصورة التالية توضح شكل أجزاء ملف الـ PE المختلفة في القرص الصلب وفي الذاكرة.

صورة رقم 14

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

لنتعمق الآن في الموضوع بشكل أكبر، كما ترى في الصورة السابقة فإن أي ملف PE على جهازك يتكون من أربعة أجزاء رئيسية ثم أقسام الملف من القسم الأول إلى عدد يُحدده المترجم الذي تمت فيه كتابة البرنامج Compiler و تحويله إلى ملف بلغة الآلة. أعتقد أن هذه النقطة تحتاج إلى توضيح أكثر.  لابد أن لديك خلفية برمجية ومنها فأنت تعرف أن مترجم البرامج The Compiler عبارة عن برنامج يأخذ الملف المصدري Source File الذي كُتب به البرنامج بلغة عالية المستوى High Level Language مثل ++C و Delphi ويقوم بتحوله إلى ملف مقروء بلغة الآلة مثل ملفات الـ PE و ELF و APP. من الأمثلة على مترجم البرامج برنامج ++Microsoft Visual C. إذاً عدد الأقسام في الملف يعتمد على مترجم البرامج المستخدم Compiler وعلى المعلومات التي كتبها المبرمج في البرنامج. لكن في كل الأحوال أي ملف PE يحتوي على الأقل على قسمين، أحدهما للكود البرمجي والآخر للمعلومات. أي أن أحدهم يحتوي على التعليمات (الكود البرمجي) التي يجب أن تتم أو تُنفذ والآخر يحتوي على الأسماء أو النصوص المكتوبة في البرنامج (المعلومات). فمثلاً في برنامج بالواجهة التالية:

صورة رقم 15

قسم التعليمات أو الكود البرمجي في هذا البرنامج يأمر بإظهار شاشة للمستخدم، في حال ضغط المستخدم على Use License File فإنه يأمر بإظهار شاشة أخرى للبحث عن الملفات في الجهاز وينتظر أن يستقبل ملف نصي بصيغة معينة،في حال ضغط المستخدم على Cancel فإنه يأمر بإغلاق العملية بالكامل. أما قسم المعلومات في هذا البرنامج فإنه يحتوي على النص المكتوب في داخل الشاشة فقط:

.EAGLE needs to install a license file on your computer in order to work

.Select Use license file if you have a personalized EAGLE license file

…..Select

طبعاً التعليمات في قسم الكود البرمجي تحتوي أيضاً على الأوامر التي تُحدد مكان النص المطلوب إظهاره من قسم المعلومات. وقد تكون الأقسام الموجودة في الملف أكثر من 2، فأي برنامج موجود على نظام تشغيل من عائلة Windows NT مثل ويندوز xp و ويندوز 7 ذو 32 بت لديهم 9 أقسام  مُعرفة مسبقا:

  • قسم الكود البرمجي Executable Code section ويدعى .text عند ترجمته بـ Micro$oft أو يدعى CODE عند ترجمته بـ Borland
    • قسم المعلومات Data section ويدعى .data. ،rdata أو .bss من مترجم مايكروسوفت، أو DATA من مترجم Borland.
    • قسم المصادر Resources Section ويدعى .rsrc
    • قسم البيانات الصادرة Export data section ويدعى .edata
    • قسم البيانات الواردة Import Data Section ويدعى .idata
    • قسم معلومات تتبع البرنامج Debug Information Section ويدعى .debug

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

عند تحميل ملف الـ PE إلى الذاكرة، فإن تلك النسخة الموجودة في الذاكرة تُسمى Module، وأول عنوان يوجد فيه الملف في الذاكرة يُسمى HModule. مصطلح العملية Process يشير إلى المساحة المعزولة في الذاكرة والتي يتم استعمالها لتشغيل الـ Module. الآن وبعد شرح تركيب الملف بشكل عام، سنتعمق بالتفصيل داخل أجزاء الملف المختلفة.

  • واجهة الدوس Dos Header :

كل ملفات الـ PE تبدأ بواجهة الدوس Dos MZ header والتي تشغل أول 64 بايت من الملف. وقد وُضعت هناك في حال ما تم فتح البرنامج من خلال الدوس. في حال انك لا تملك فكرة واضحة عن ماهية الدوس، أو لنقل الـMS-Dos، فإنه نظام تشغيل كان يُستخدم في الماضي في أجهزة الكمبيوتر من IBM حتى تلته أنظمة التشغيل الصورية Graphical user interface OS. وكل نسخ الويندوز تحتوي على نظام الدوس كسطر أوامر فقط Command Line Interface ويمكنك  فتحه من خلال كتابة cmd في سطر البحث الموجود في شريط ابدأ start على زاوية الشاشة من الأسفل.  واجة الدوس موجودة لكي يتعرف الدوس على الملف أنه ملف تنفيذي صالح وبالتالي يقوم بتشغيل الجزء الثاني من الملف “تنصيب البرنامج في الدوس Dos Stub“، في العادة يقوم إلـ Dos Stub بعرض نص على الشاشة مثل التالي:

This program must be run under Microsoft Windows” وتعني “هذا البرنامج يجب أن يتم تشغيله في نظام مايكروسوفت ويندوز”.  ومع ذلك يمكن أن يكون الملف قد صمم لبيئة الدوس وبالتالي لا يقوم بعرض هذه الرسالة بل يبدأ بالعمل كما بُرمج. في واجهة الدوس هنالك 19 خانة أو عنصر  وهم:

صورة رقم 16

ما يهمنا من هذه العناصر هما الأول e_magic والأخير e_lfanew. في كل ملفات الـ PE العنصر Magic يحتوي على القيمتين 5Ah 4Dh، (حرف ال h  في نهاية كل قيمة يدل فقط أن هذه القيمة مكتوبة بالنظام السداسي عشر Hexadecimal).  القيمتان 5Ah 4Dh يساويان الحرفين MZ بنظام الأسكي واللذان يشيران إلى Mark Zbilkowsky. هذا الشخص كان أحد المبدعين الذين ساهموا في تصميم نظام الـ MS-DOS ، وجود هذين الحرفين يدل على أن واجهة الدوس هذه صالحة  للاستخدام. لترى هذين الحرفين قم بفتح أي برنامج بمحرر الهيكس كما في الصورة التي في الأسفل

صورة رقم 17

في الصورة رقم 16 ترى أن حجم العنصر ifanew مًعرف بـ DWORD وهي اختصار لكلمة double word وتساوي 4 بايت، أو 32 بت، أو رقمين بالنظام السداسي عشر. وهذا العنصر موجود في آخر واجهة الدوس وقبل بداية واجهة تنصيب الدوس Dos stup . قيمة هذا العنصر تعبر عن العنوان offset الذي يشير إلى واجهة الملف الذاتي التشغيل (PE Header). ( تذكر أول ثلاث أجزاء من أي ملف PE). الجزء الثاني Dos Stup يختلف حجمه حسب حجم المترجم الذي قام بترجمة الملف إلى لغة الآلة، بالتالي إن كان الملف يعمل تحت بيئة الويندوز فسيقوم نظام التشغيل بتجاهله والانتقال إلى الجزء الذي يليه وهو واجهة ملف الـ PE. ولكي يعرف محمل البرامج أين تقع أو أين تبدأ واجهة ملف الـ PE فإنه يقرأ قيمة العنصر lfanew ومنها يعرف إلى أين يذهب. لكي تعرف أين يقع مكان العنصر ifanew فهو آخر 4 بايت من واجهة الدوس (قلنا سابقاً أن واجهة الدوس تحوي 64 بايت). أو يمكنك أن تعد أربع سطور من بداية الملف كما هو موضح في الصورة 17. الرقم الموجود هناك (مظلل باللون الأزرق في الصورة 17) هو (h)00 01 00 00 ولكن يجب أن تعرف أن الكمبيوتر يقوم بتخزين الأرقام بشكل معكوس Reverse Byte Order وبالتالي يصبح الرقم (h) 00 00 01 00 (قم بعكس اول بايتين مع ثاني بايتين، بعد ذلك إعكس أول بايت مع ثاني بايت، وثالث بايت مع رابع بايت).  كما ترى في الصورة رقم 17، هذا الرقم الجديد يشير إلى رقم الخانة التي تبدأ عندها واجهة ملف الـ PE من بداية الملف.  إن ذهبت إلى تلك الخانة فيجب أن يكون أول أربع بايتات فيها (h) 50 45 00 00 وتساوي الحرفين PE بالآسكي. هذين الحرفين هما توقيع واجهة ملف الـ PE ويدلان أن هذه الواجهة أو هذا الجزء من الملف صالح للعمل. في حال وجدت في تلك الخانة الحرفين NE بدل PE فاعلم أن هذا البرنامج يعمل تحت بيئة ويندوز 16 بت، والحرفان LE يدلان على أن هذا الملف هو تعريف لأحد الأجهزة في ويندوز 32 بت Windows 3.x virtual device driver (VxD). والحرفان LX يدلان على أن برنامج يعمل تحت نظام تشغيل OS/2  وهو نظام تشغيل قديم أُنشئ بالتعاون بين مايكروسوفت و IBM ولم يعد يُسوق بعد الآن. الآن بعد أن رأينا واجهة الدوس وعرفنا أن أول بايتان فيها هما توقيع تلك الواجهة ويشيران إلى اسم احد المبرمجين المشهورين، وعرفنا أن آخر اربع بايتات فيها يشيرون إلى عنوان واجهة الـ PE، فلننتقل إلى دراسة  واجهة الـ PE بالتفصيل .

الذهاب للجزء الثاني