הבנת פורמט קובץ ELF

Understanding Elf File Format



מקוד המקור ועד הקוד הבינארי

התכנות מתחיל עם רעיון חכם וכתיבת קוד המקור בשפת תכנות לפי בחירתך, למשל C, ושמירת קוד המקור בקובץ. בעזרת מהדר מתאים, למשל GCC, קוד המקור שלך מתורגם קודם כל לקוד אובייקט. בסופו של דבר, המקשר מתרגם את קוד האובייקט לקובץ בינארי המקשר בין קוד האובייקט לבין הספריות שהופנו אליהן. קובץ זה מכיל את ההוראות היחידות כקוד מכונה המובנות על ידי המעבד, והן מבוצעות ברגע שהתוכנית המורכבת מופעלת.

הקובץ הבינארי שהוזכר לעיל עוקב אחר מבנה ספציפי, ואחד הנפוצים שבהם נקרא ELF המקצר פורמט הפעלה וקישור. הוא נמצא בשימוש נרחב עבור קבצי הפעלה, קבצי אובייקטים הניתנים להעברה, ספריות משותפות ומזבלות ליבה.







לפני עשרים שנה-בשנת 1999-פרויקט 86open בחר ב- ELF כפורמט הקובץ הבינארי הסטנדרטי למערכות Unix ו- Unix במעבדי x86. למרבה המזל, פורמט ELF תועד בעבר הן בממשק הבינארי של יישום System V והן בתקן ממשק הכלים [4]. עובדה זו פישטה מאוד את ההסכם על סטנדרטיזציה בין הספקים והמפתחים השונים של מערכות הפעלה מבוססות יוניקס.



הסיבה מאחורי החלטה זו הייתה עיצוב ELF-גמישות, הרחבה ותמיכה חוצה פלטפורמות עבור פורמטים וגדלי כתובות שונים. העיצוב של ELF אינו מוגבל למעבד, מערך הוראות או ארכיטקטורת חומרה ספציפית. להשוואה מפורטת של פורמטים של קבצי הפעלה, עיין כאן [3].



מאז, פורמט ELF נמצא בשימוש במספר מערכות הפעלה שונות. בין היתר, זה כולל Linux, Solaris/Illumos, Free-, Net- ו- OpenBSD, QNX, BeOS/Haiku ו- Fuchsia OS [2]. יתר על כן, תוכל למצוא אותו במכשירים ניידים שבהם פועלים מערכת ההפעלה Android, Maemo או Meego OS/Sailfish וכן בקונסולות משחקים כמו ה- PlayStation Portable, Dreamcast ו- Wii.





המפרט אינו מבהיר את סיומת שם הקובץ עבור קבצי ELF. בשימוש מגוון שילובי אותיות, כגון .axf, .bin, .elf, .o, .prx, .puff, .ko, .so, ו- .mod, או אף אחד.

מבנה קובץ ELF

במסוף לינוקס, איש הפקודה elf נותן לך סיכום נוח על מבנה קובץ ELF:



רישום 1: דף העבודה של מבנה ELF

$ איש אחד עשרה

ELF (5) לינוקס מתכנת לינוקס ELF (5)

שֵׁם
elf - פורמט של קבצי הפעלה וקישור (ELF)

תַקצִיר
#לִכלוֹל

תיאור
קובץ הכותרת מגדיר את הפורמט של בינארי הפעלה של ELF
קבצים. בין הקבצים האלה יש קבצי הפעלה רגילים, ניתנים להעברה מחדש
קבצי אובייקטים, קבצי ליבה וספריות משותפות.

קובץ הפעלה באמצעות פורמט קובץ ELF מורכב מכותרת ELF,
ואחריו טבלת כותרת תוכנית או טבלת כותרת מקטע, או שניהם.
כותרת ELF נמצאת תמיד באפס הקיזוז של הקובץ. התכנית
טבלת הכותרות והקיזוז של טבלת כותרת הקטע בקובץ הם
מוגדר בכותרת ELF. שתי הטבלאות מתארות את שאר ה-
המיוחדות של הקובץ.

...

כפי שניתן לראות מהתיאור למעלה, קובץ ELF מורכב משני חלקים - כותרת ELF ונתוני קבצים. קטע נתוני הקבצים יכול להיות מורכב מטבלת כותרת תוכנית המתארת ​​מקטעים אפס או יותר, טבלת כותרת מקטעים המתארת ​​חלקים אפס או יותר, ואחריה נתונים שאליהן מתייחסים ערכים מטבלת כותרת התוכנית וטבלת כותרת המקטע. כל קטע מכיל מידע הדרוש לביצוע הקובץ בזמן ריצה, בעוד שקטעים מכילים נתונים חשובים לקישור והעברה. איור 1 ממחיש זאת באופן סכמטי.

כותרת ELF

אורך הכותרת ELF הוא 32 בתים ומזהה את תבנית הקובץ. זה מתחיל ברצף של ארבעה בתים ייחודיים שהם 0x7F ואחריהם 0x45, 0x4c ו- 0x46 המתורגמים לשלוש האותיות E, L ו- F. בין הערכים האחרים, הכותרת מציינת גם אם מדובר בקובץ ELF עבור 32 או פורמט 64 סיביות, משתמש בקצה קטן או גדול, מציג את גרסת ELF וכן עבור איזו מערכת הפעלה הקובץ נאסף על מנת לפעול בשיתוף פעולה עם הממשק הבינארי הנכון (ABI) וערכת הוראות המעבד.

ה- hexdump של מגע הקובץ הבינארי נראה כדלקמן:

.Risting 2: ה- hexdump של הקובץ הבינארי

$ hd/usr/bin/touch | ראש -5
00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 | .ELF ........... |
00000010 02 00 3e 00 01 00 00 00 e3 25 40 00 00 00 00 00 | ..> ......% @ ..... |
00000020 40 00 00 00 00 00 00 00 28 28 e4 00 00 00 00 00 00 | @ ....... (....... |
00000030 00 00 00 00 40 00 38 00 09 00 40 00 1b 00 1a 00 | [מוגן בדוא'ל] @..... |
00000040 06 00 00 00 05 00 00 00 40 00 00 00 00 00 00 00 | [מוגן בדוא'ל] |

Debian GNU/Linux מציעה את הפקודה readelf המסופקת בחבילת ה- GNU 'binutils'. מלווה במתג -h (גרסה קצרה ל- –file -header) הוא מציג יפה את הכותרת של קובץ ELF. רישום 3 ממחיש זאת עבור מגע הפקודה.

.3 רשימה: הצגת הכותרת של קובץ ELF

$ readelf -h/usr/bin/touch
כותרת ELF:
קסם: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
מחלקה: ELF64
נתונים: השלמה של 2, אנדיאן קטן
גרסה: 1 (נוכחי)
מערכת הפעלה / ABI: UNIX - מערכת V
גרסת ABI: 0
סוג: EXEC (קובץ הפעלה)
מכונה: התקני מיקרו מתקדמים X86-64
גרסה: 0x1
כתובת נקודת כניסה: 0x4025e3
התחלת כותרות התוכנית: 64 (בתים לקובץ)
תחילת כותרות מדורים: 58408 (בתים לקובץ)
דגלים: 0x0
גודל כותרת זו: 64 (בתים)
גודל כותרות התוכנית: 56 (בתים)
מספר כותרות התוכנית: 9
גודל כותרות המדור: 64 (בתים)
מספר כותרות המדור: 27
אינדקס טבלת מחרוזות בכותרת המדור: 26

כותרת התוכנית

כותרת התוכנית מציגה את הקטעים המשמשים בזמן ריצה, ומספרת למערכת כיצד ליצור תמונת תהליך. הכותרת מרישום 2 מראה שקובץ ELF מורכב מ -9 כותרות תוכניות בעלות גודל של 56 בתים כל אחת, והכותרת הראשונה מתחילה בבייט 64.

שוב, הפקודה readelf מסייעת לחלץ את המידע מקובץ ELF. המתג -l (קיצור של –כותרות -תכניות או –מגזרים) חושף פרטים נוספים כפי שמוצג ברישום 4.

.רשימה 4: הצג מידע על כותרות התוכנית

$ readelf -l/usr/bin/touch

סוג קובץ האלף הוא EXEC (קובץ הפעלה)
נקודת כניסה 0x4025e3
ישנם 9 כותרות תוכניות, המתחילות ב- offset 64

ראשי התוכנית:
הקלד קיזוז VirtAddr PhysAddr
יישור הדגלים של FileSiz MemSiz
PHDR 0x0000000000000040 0x0000000000400040 0x0000000000400040
0x00000000000001f8 0x00000000000001f8 R E 8
INTERP 0x0000000000000238 0x0000000000400238 0x0000000000400238
0x000000000000001c 0x000000000000001c R 1
[מבקש מתורגמן לתוכנית: /lib64/ld-linux-x86-64.so.2]
טען 0x0000000000000000 0x0000000000400000 0x0000000000400000
0x000000000000d494 0x000000000000d494 R E 200000
טען 0x000000000000de10 0x000000000060de10 0x000000000060de10
0x0000000000000524 0x0000000000000748 RW 200000
DYNAMIC 0x000000000000de28 0x000000000060de28 0x000000000060de28
0x00000000000001d0 0x00000000000001d0 RW 8
הערה 0x0000000000000254 0x0000000000400254 0x0000000000400254
0x0000000000000044 0x0000000000000044 R 4
GNU_EH_FRAME 0x000000000000b40 0x000000000040bc40 0x000000000040bc40
0x00000000000003a4 0x00000000000003a4 R 4
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RW 10
GNU_RELRO 0x000000000000de10 0x000000000060de10 0x000000000060de10
0x00000000000001f0 0x00000000000001f0 R 1

מיפוי מקטע לפלח:
קטעי קטעים ...
00
01 .interp
02 .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .text .fini. rodata .eh_frame_hdr .eh_frame
03 .init_array .fini_array .jcr .dynamic .got .got.plt .data .bss
04. דינמי
05 .note.ABI-tag .note.gnu.build-id
06 .eh_frame_hdr
07
08 .init_array .fini_array .jcr .dynamic .got

כותרת המדור

החלק השלישי של מבנה ELF הוא כותרת המדור. הוא נועד לרשום את החלקים היחידים של הבינארי. המתג -S (קיצור של –כותרות -חלקים או –סעיפים) מפרט את הכותרות השונות. באשר לפקודת המגע, יש 27 כותרות מקטעים, ורישום 5 מציג את ארבע הראשונות שלהן בתוספת זו האחרונה, רק. כל שורה מכסה את גודל המדור, סוג המדור וכן את כתובתו וקיזוז הזיכרון.

.רשימה 5: פרטי החלק שנחשפו על ידי קריאה עצמית

$ readelf -S/usr/bin/touch
ישנם 27 כותרות מדורים, החל מאוזן 0xe428:

כותרות מדורים:
[Nr] סוג שם כתובת קיזוז
גודל EntSize דגלים מידע קישור יישור
[0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[1] .interp PROGBITS 0000000000400238 00000238
000000000000001c 0000000000000000 A 0 0 1
[2] .note.ABI-tag NOTE 0000000000400254 00000254
0000000000000020 0000000000000000 A 0 0 4
[3] .note.gnu.build-i NOTE 0000000000400274 00000274
...
...
[26] .shstrtab STRTAB 0000000000000000 0000e334
00000000000000ef 0000000000000000 0 0 1
מפתח לדגלים:
W (כתיבה), A (הקצאה), X (ביצוע), M (מיזוג), S (מחרוזות), l (גדול)
I (מידע), L (סדר קישורים), G (קבוצה), T (TLS), E (לא כולל), x (לא ידוע)
O (נדרש עיבוד מערכת הפעלה נוספת) o (ספציפית למערכת ההפעלה), p (ספציפית למעבד)

כלים לניתוח קובץ ELF

כפי שציינת אולי מהדוגמאות לעיל, GNU/Linux מורכב ממספר כלים שימושיים שעוזרים לך לנתח קובץ ELF. המועמד הראשון שנבחן הוא כלי הקבצים.

קובץ מציג מידע בסיסי על קבצי ELF, כולל ארכיטקטורת מערך ההוראות שאליו מיועד הקוד בקובץ אובייקט הניתן להעברה, הפעלה או משותף. ברשימה 6 הוא אומר לך ש/bin/touch הוא קובץ הפעלה של 64 סיביות בעקבות בסיס Linux Standard (LSB), המקושר באופן דינמי, ונבנה עבור גרסת הגרעין 2.6.32 של GNU/Linux.

.רשימה 6: מידע בסיסי באמצעות קובץ

$ file /bin /touch
/bin/touch: הפעלה LSB 64 סיביות ELB, x86-64, גירסה 1 (SYSV), מקושרת באופן דינמי, מתורגמן/lib64/l,
עבור GNU/Linux 2.6.32, BuildID [sha1] = ec08d609e9e8e73d4be6134541a472ad0ea34502, מופשט
$

המועמד השני הוא קריאה עצמית. הוא מציג מידע מפורט על קובץ ELF. רשימת המתגים ארוכה יחסית, ומכסה את כל ההיבטים של פורמט ELF. שימוש במתג -n (קיצור של –ערות) רישום 7 מציג את קטעי ההערות, רק, הקיימים במגע הקובץ -תג גרסת ABI, ומחרוזת סיביות ה- build build.

. רשימה 7: הצגת חלקים נבחרים של קובץ ELF

$ readelf -n/usr/bin/touch

מציג פתקים שנמצאו בתיקון קיזוז 0x00000254 באורך 0x00000020:
גודל נתוני הבעלים תיאור
GNU 0x00000010 NT_GNU_ABI_TAG (תג גרסה ABI)
מערכת הפעלה: Linux, ABI: 2.6.32

מציג הערות שנמצאו בתיקון קיזוז 0x00000274 באורך 0x00000024:
גודל נתוני הבעלים תיאור
GNU 0x00000014 NT_GNU_BUILD_ID (מחרוזת bit bit ייחודית)
מזהה Build: ec08d609e9e8e73d4be6134541a472ad0ea34502

שים לב כי תחת Solaris ו- FreeBSD, השירות elfdump [7] מתכתב עם קריאה עצמית. נכון לשנת 2019, לא הייתה גרסה או עדכון חדש מאז 2003.

מספר שלוש היא החבילה בשם elfutils [6] הזמינה אך ורק עבור לינוקס. הוא מספק כלים חלופיים ל- GNU Binutils, ומאפשר גם אימות קבצי ELF. שים לב שכל שמות השירותים המסופקים בחבילה מתחילים ב- eu עבור 'כלי שד'.

אחרון חביב נזכיר objdump. כלי זה דומה לקריאה עצמית אך מתמקד בקבצי אובייקטים. הוא מספק מגוון מידע דומה על קבצי ELF ופורמטים של אובייקטים אחרים.

.רשימה 8: מידע על קבצים שחולץ על ידי objdump

$ objdump -f /bin /touch

/bin/touch: פורמט קובץ elf64-x86-64
אדריכלות: i386: x86-64, דגלים 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
כתובת התחלה 0x00000000004025e3

$

יש גם חבילת תוכנה בשם 'elfkickers' [9] המכילה כלים לקריאת התוכן של קובץ ELF וכן מניפולציה שלו. לרוע המזל, מספר המהדורות הוא נמוך למדי, ולכן אנו פשוט מזכירים זאת ואיננו מציגים דוגמאות נוספות.

כמפתח אתה יכול להסתכל על 'pax-utils' [10,11], במקום זאת. מערך זה של כלי עזר מספק מספר כלים המסייעים באימות קבצי ELF. כדוגמה, dumpelf מנתח את קובץ ELF ומחזיר קובץ כותרת C המכיל את הפרטים - ראה איור 2.

סיכום

הודות לשילוב של עיצוב חכם ותיעוד מצוין פורמט ELF עובד טוב מאוד, והוא עדיין בשימוש לאחר 20 שנה. השירותים המוצגים למעלה מאפשרים לך מבט על קובץ ELF ומאפשרים לך להבין מה תוכנית עושה. אלו הם השלבים הראשונים לניתוח תוכנות - פריצה מאושרת!

קישורים והפניות
הכרות

הסופר רוצה להודות לאקסל בקרט על תמיכתו בהכנת מאמר זה.