سنتكلم اليوم ان شاء الله عن تنسيق ELF وهو المستخدم فى نظام التشغيل الشهير Linux
ما هو ELF ؟
قد صمم ELF (تنسيق قابل للتنفيذ والربط) من قبل مختبرات نظام يونيكس مع شركة Sun Microsystems
أثناء تطوير وتصميم نظام SVR4 الاصدار الرابع وبالتالي فان اول ظهور لELF كان فى نظام لتشغيل Solairs 2.0 الذى تم تطويره بالاعتماد على نظام التشغيل SVR4
وتنسيق الملف فى ELF شديد التنوع، واختير في وقت لاحق من قبل العديد من أنظمة التشغيل الأخرى على حد سواء لاستخدام الملفات القابلة للتنفيذ والملفات التى بينها مكتبة مشتركة كما. فإنه لا يميز بين البيانات والنصوص وBSS.
اليوم ، تعتبر ELF في شكل موحد على حد سواء أنظمة يونكس. بينما كان لديها بعض العيوب (على سبيل المثال، وذلك باستخدام واحدة من الهدف العام للمسجلات النادرة IA32 عند استخدام رمز مستقل) ،وكذلك يتم دعمه جيدا وتوثيقه .
هيكلة الملف :
ELF هو تنسيق لبرامج تخزين أو أجزاء من البرامج على القرص ، والتي نشأت نتيجة لتجميع وربط. وينقسم ملف ELF إلى أقسام. لبرنامجقابل للتنفيذ، وهذه هي نص القسم لرمز، مقطع البيانات للمتغيراتالعالمية وrodata القسم الذي يحتوي على سلاسل عادة ثابتة. الملفيحتوي على رؤوس ELF التي تصف كيف يجب أن يتم تخزين هذه المقاطع في الذاكرة.
علما بأن اعتمادا على ما إذا كان الملف الخاص بك هو linkable أوملف قابل للتنفيذ، والرؤوس في ملف ELF لن تكون هي نفسها :
process.o, result of gcc -c process.c $SOME_FLAGS
C32/kernel/bin/.process.o
architecture: i386, flags 0x00000011:
HAS_RELOC, HAS_SYMS
start address 0x00000000
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000333 00000000 00000000 00000040 2**4
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
1 .data 00000050 00000000 00000000 00000380 2**5
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000000 00000000 00000000 000003d0 2**2
ALLOC
3 .note 00000014 00000000 00000000 000003d0 2**0
CONTENTS, READONLY
4 .stab 000020e8 00000000 00000000 000003e4 2**2
CONTENTS, RELOC, READONLY, DEBUGGING
5 .stabstr 00008f17 00000000 00000000 000024cc 2**0
CONTENTS, READONLY, DEBUGGING
6 .rodata 000001e4 00000000 00000000 0000b400 2**5
CONTENTS, ALLOC, LOAD, READONLY, DATA
7 .comment 00000023 00000000 00000000 0000b5e4 2**0"Flags" اقول لكم ما هو متاح فعليا في ملف ELF. هنا، لدينا جداول الرمز، وإعادة التوطين : كل ما نحن بحاجة لربط ملف ضد آخر، ولكن عمليا لا توجد معلومات عن كيفية تحميل الملف في الذاكرة (حتى لو كان ذلك يمكن تخمينها). ليس لدينا نقطة دخول البرنامج ، على سبيل المثال ، وليس لدينا جدول أقسام بدلا من رأس البرنامج.
اقتباسText: كما فى الرمز اعلاه objdump -drS , process.سوف ترينا الامر (باستخدام المترجم GCC طبعا)Data: حيث جداول global والمتغيرات .....الخ objdump -s -j , process.o ثم التحويل الى hexdump
bss : لا نبحث عن اجزاء من BSS فى الملف : لاشئ هناك خيث ان المصفوفات الخاصة غير مهيأة ومتغيرة والLoader يتعرف على ذلك ولذلك يجب ملؤها بالاصفار ... ليس هناك نقطة تخزين للمزيد من الاصفار على القرص عندما يكون مهيئا بالفعل
rodata :سلاسل الStrings والاشياء التي تنساها اثناء ربط المصفوفات التي تسبب عدم عمل النواة objdump -s -j .rodata .process.o ستقوم بتحويلها الى النظام السداسي
علما بأن العملية تعتمد على المترجم المستخدم (فى حالتنا هذه نستخدم GCC )
comment & .note : مجرد تعليقات وضعت هناك من قبل المترجم / الرابط (Linker)
.stab & .stabstr : تنقيح المعلومات والمعلومات المماثلة
/bin/bash ملف قابل للتنفيذ الحقيقي
/bin/bash: file format elf32-i386
/bin/bash
architecture: i386, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x08056c40
Program Header:
PHDR off 0x00000034 vaddr 0x08048034 paddr 0x08048034 align 2**2
filesz 0x000000e0 memsz 0x000000e0 flags r-xرأس البرنامج في حد ذاته... مع 224 بايت ، والبدء في تعويض 0x34في الملف
INTERP off 0x00000114 vaddr 0x08048114 paddr 0x08048114 align 2**0
filesz 0x00000013 memsz 0x00000013 flags r--البرنامج الذي يجب أن يستخدم فىالتنفيذ الثنائى هنا ،فى هذه الحالة يصبح نصه كما'/lib/ld-linux.so.2',
وهو ما يعني سوف تكون هناك حاجة لبعض مكتبات الارتباط الحيوي قبل أن يتم تشغيل البرنامج.
LOAD off 0x00000000 vaddr 0x08048000 paddr 0x08048000 align 2**12
filesz 0x0007411c memsz 0x0007411c flags r-xالآن نحن طلبنا لقراءة بايت 7411c، بدءا من بداية الملف (؟) ويجريبايت 7411c كبيرة (وهذا الملف بأكمله تقريبا!)، والتي سوف تكون للقراءة فقط ، بل للتنفيذ. انها سوف تكون لتظهر بدءا من العنوان الظاهري 0x08048000 للبرنامج للعمل بشكل صحيح.
LOAD off 0x00074120 vaddr 0x080bd120 paddr 0x080bd120 align 2**12
filesz 0x000022ac memsz 0x000082d0 flags rw-هناك مزيد من البتات للتحميل ، (من المرجح أن يكون. بيانات المقطع). لاحظ أن"حجم الملف" و "memsize' تختلف، مما يعني أن سوف يكون في الواقع BSS القسم المخصص من خلال هذا البيان، لكنه ترك اصفارا فى حين أن البيانات الحقيقية فقط تقوم باحتلال بايت 0x22ac الاولى ابتداء من العنوان 0x80bd120 العنوان الظاهري.
DYNAMIC off 0x00075f4c vaddr 0x080bef4c paddr 0x080bef4c align 2**2
filesz 0x000000e8 memsz 0x000000e8 flags rw-تستخدم المقاطع الديناميكية لتخزين المعلومات المستخدمة في عملية الربط الديناميكي، مثل المكتبات المطلوبة وقيود النقل.
NOTE off 0x00000128 vaddr 0x08048128 paddr 0x08048128 align 2**2
filesz 0x00000020 memsz 0x00000020 flags r--ملاحظة المقاطع تحتوي على معلومات التي خلفها المبرمج أو الرابط ، وبالنسبة لمعظم البرامج المرتبطة به الرابط Linker الخاص بGNU المسمي "Ld"
EH_FRAME off 0x000740f0 vaddr 0x080bc0f0 paddr 0x080bc0f0 align 2**2
filesz 0x0000002c memsz 0x0000002c flags r--هذا هو معالج استثناء للحصول على معلومات، في حال ينبغي لنا أن يكون الارتباط ضد بعض الثنائيات C + + في التنفيذ (AFAIK).
/bin/bash, loaded (as in /proc/xxxx/maps) 08048000-080bd000 r-xp 00000000 03:06 30574 /bin/bash 080bd000-080c0000 rw-p 00074000 03:06 30574 /bin/bash 080c0000-08103000 rwxp 00000000 00:00 0 40000000-40014000 r-xp 00000000 03:06 27304 /lib/ld-2.3.2.so 40014000-40015000 rw-p 00013000 03:06 27304 /lib/ld-2.3.2.so
يمكننا أن ندرك 'بت الرموز" لدينا و "بت البيانات" ، التي تنص على ضرورة تحميل ثانية واحدة في 0x080bd * 120 * وأنه يبدأ في ملف في 0x00074 * 120 *، ونحن فعلا عليناالحفاظ على تعيين كتل الصفحة إلى القرص (على سبيل المثال إذا كانت صفحة 0 x80bc000 مفقودة ، مجرد كتل إحضار الملف من 0x75000). وهذا يعني، مع ذلك ، أن يتم تعيين جزء من القانون مرتين، ولكن مع أذونات مختلفة. أقترح عليك أن تعطي لهم صفحات فيزيائية مختلفة جدا إذا كنت لا تريد في نهاية المطاف تعديل للرمز
والى اللقاء فى لقاء قريب لتكملة هذا المقال بمقال أخر سنتحدث فيه عن كيفية تحميل الملفات الثنائية لنظامELF