日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

elf文件格式实例解析

發(fā)布時(shí)間:2025/3/11 编程问答 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 elf文件格式实例解析 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

?

試驗(yàn)環(huán)境:archlinux 速龍3000+(即x86兼容32位處理器)

必須軟件:gcc binutils

參考資料:

System V application binary interface

ELF Format (mirror txt format )

Hello,world in less than 20 bytes

Tutorial on creating teensy ELF file on linux (中文翻譯版本 ,also see (smallest elf32 hello,world ))

Introduction to reverse engineering on linux ? (also see crackz reverse engineering page(windows),resources )

Deconstructing an ELF file

The ELF virus writing howto

Playing with binary format

ELF hackery (many links)

ELF or assembly reference (on skyeye)

linkers and loaders

linkers(part 1 ,part 2 , part 3 , part 4 , part 5 , part 6 , part 7 , part 8 ,part 9 ,part 10

????? part 11 ,part 12 , part 13 , part 14 , part 15 , part 16 , part 17 , part 18 , part 19 , part 20 )

hacker's wisdom

還可用百度搜索"ELF site:ibm.com",能搜索到很多關(guān)于ELF中文翻譯教程,其中文后的參考文獻(xiàn)也很值得看。

pe(window下的庫文件和可執(zhí)行文件格式)相關(guān)鏈接可以在wikipedia上找到 。

?

ELF 文件分為三類:(1)可重定位文件(目標(biāo)文件或者靜態(tài)庫文件,即linux通常后綴為.a和.o的文件) (2)可執(zhí)行文件(即可以運(yùn)行的二進(jìn)制文件,例如bash,gcc等)(3)共享目標(biāo)文件(即linux下后綴為so的文件)。Elf文件格式(參見System V Application Binary interface 第46頁)的布局如下:

?

-----------------------------

ELF文件頭(即ELF Header)

----------------------------

程序文件頭表(Program header table)

-----------------------------------

Section 1

-----------------------------------

???? ...

-----------------------------------

Section n

----------------------------------

???? ...

----------------------------------

段表(Section header table)

-----------------------------------

?

其中程序文件頭表對于可重定位文件是可選項(xiàng)(對另外兩類文件是必需項(xiàng)),而段表對于可執(zhí)行文件是可選項(xiàng)(對另外兩類文件是必需項(xiàng))。另外,Section可以是.text,.data,.bss(即代碼段,數(shù)據(jù)段(用來存放已經(jīng)初始化的全局變量和靜態(tài)變量)和BSS段(用來存放未初始化的全局變量和靜態(tài)變量))等

?

使用《程序員的自我修養(yǎng)--鏈接 裝載和庫》中第三章的例子來說明elf的具體格式

/** SimpleSection.c* * Linux:* gcc -c SimpleSection.c* Windows:* cl SimpleSection.c /c /Za*/ int printf(const char* format, ...); int global_init_var = 84; int global_uinit_var;void func1(int i) {printf("%d\n", i); }int main(void) {static int static_var = 85;static int static_var2;int a = 1;int b;func1(static_var + static_var2 + a + b);return a; }

?使用下面命令來編譯:

?

gcc -c SimpleSection.c

?再使用下面命令來顯示生成的目標(biāo)文件(SimpleSection.c)的類型

?

file SimpleSection.o

?輸出下列內(nèi)容:

SimpleSection.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped

?說明SimpleSection.o是一個(gè)重定位文件

使用下面命令查看SimpleSection.o的大小:

?

ls -l SimpleSection.o

?輸出結(jié)果為:

?

-rw-r--r-- 1 host users 1092 11月 5 14:38 SimpleSection.o

?根據(jù)輸出結(jié)果可以知道,SimpleSection.o大小為1092字節(jié)。

使用下面命令用16進(jìn)制的數(shù)字來顯示SimpleSection.o的內(nèi)容(也可以用od -x SimpleSection.o命令)

?

hexdump -x SimpleSection.o

?輸出結(jié)果為:

0000000 457f 464c 0101 0001 0000 0000 0000 0000 0000010 0001 0003 0001 0000 0000 0000 0000 0000 0000020 010c 0000 0000 0000 0034 0000 0000 0028 0000030 000b 0008 8955 83e5 18ec 458b 8908 2444 0000040 c704 2404 0000 0000 fce8 ffff c9ff 55c3 0000050 e589 e483 83f0 20ec 44c7 1c24 0001 0000 0000060 158b 0004 0000 00a1 0000 8d00 0204 4403 0000070 1c24 4403 1824 0489 e824 fffc ffff 448b 0000080 1c24 c3c9 0054 0000 0055 0000 6425 000a? 0000090 4700 4343 203a 4728 554e 2029 2e34 2e35 00000a0 2032 3032 3131 3130 3732 2820 7270 7265 00000b0 6c65 6165 6573 0029 2e00 7973 746d 6261 00000c0 2e00 7473 7472 6261 2e00 6873 7473 7472 00000d0 6261 2e00 6572 2e6c 6574 7478 2e00 6164 00000e0 6174 2e00 7362 0073 722e 646f 7461 0061 00000f0 632e 6d6f 656d 746e 2e00 6f6e 6574 472e 0000100 554e 732d 6174 6b63 0000 0000 0000 0000 0000110 0000 0000 0000 0000 0000 0000 0000 0000 * 0000130 0000 0000 001f 0000 0001 0000 0006 0000 0000140 0000 0000 0034 0000 0050 0000 0000 0000 0000150 0000 0000 0004 0000 0000 0000 001b 0000 0000160 0009 0000 0000 0000 0000 0000 041c 0000 0000170 0028 0000 0009 0000 0001 0000 0004 0000 0000180 0008 0000 0025 0000 0001 0000 0003 0000 0000190 0000 0000 0084 0000 0008 0000 0000 0000 00001a0 0000 0000 0004 0000 0000 0000 002b 0000 00001b0 0008 0000 0003 0000 0000 0000 008c 0000 00001c0 0004 0000 0000 0000 0000 0000 0004 0000 00001d0 0000 0000 0030 0000 0001 0000 0002 0000 00001e0 0000 0000 008c 0000 0004 0000 0000 0000 00001f0 0000 0000 0001 0000 0000 0000 0038 0000 0000200 0001 0000 0030 0000 0000 0000 0090 0000 0000210 0028 0000 0000 0000 0000 0000 0001 0000 0000220 0001 0000 0041 0000 0001 0000 0000 0000 0000230 0000 0000 00b8 0000 0000 0000 0000 0000 0000240 0000 0000 0001 0000 0000 0000 0011 0000 0000250 0003 0000 0000 0000 0000 0000 00b8 0000 0000260 0051 0000 0000 0000 0000 0000 0001 0000 0000270 0000 0000 0001 0000 0002 0000 0000 0000 0000280 0000 0000 02c4 0000 00f0 0000 000a 0000 0000290 000a 0000 0004 0000 0010 0000 0009 0000 00002a0 0003 0000 0000 0000 0000 0000 03b4 0000 00002b0 0065 0000 0000 0000 0000 0000 0001 0000 00002c0 0000 0000 0000 0000 0000 0000 0000 0000 00002d0 0000 0000 0001 0000 0000 0000 0000 0000 00002e0 0004 fff1 0000 0000 0000 0000 0000 0000 00002f0 0003 0001 0000 0000 0000 0000 0000 0000 0000300 0003 0003 0000 0000 0000 0000 0000 0000 0000310 0003 0004 0000 0000 0000 0000 0000 0000 0000320 0003 0005 0011 0000 0004 0000 0004 0000 0000330 0001 0003 0021 0000 0000 0000 0004 0000 0000340 0001 0004 0000 0000 0000 0000 0000 0000 0000350 0003 0007 0000 0000 0000 0000 0000 0000 0000360 0003 0006 0032 0000 0000 0000 0004 0000 0000370 0011 0003 0042 0000 0004 0000 0004 0000 0000380 0011 fff2 0053 0000 0000 0000 001b 0000 0000390 0012 0001 0059 0000 0000 0000 0000 0000 00003a0 0010 0000 0060 0000 001b 0000 0035 0000 00003b0 0012 0001 5300 6d69 6c70 5365 6365 6974 00003c0 6e6f 632e 7300 6174 6974 5f63 6176 2e72 00003d0 3231 3232 7300 6174 6974 5f63 6176 3272 00003e0 312e 3232 0033 6c67 626f 6c61 695f 696e 00003f0 5f74 6176 0072 6c67 626f 6c61 755f 6e69 0000400 7469 765f 7261 6600 6e75 3163 7000 6972 0000410 746e 0066 616d 6e69 0000 0000 0010 0000 0000420 0501 0000 0015 0000 0d02 0000 002e 0000 0000430 0301 0000 0033 0000 0401 0000 0046 0000 0000440 0c02 0000 0000444

?上面的數(shù)據(jù)均為16進(jìn)制數(shù)據(jù)(因?yàn)槭褂昧?x選項(xiàng)),并且第一列為偏移地址。

使用下面命令來顯示SimpleSection.o中各個(gè)段相關(guān)信息:

?

objdump -x SimpleSection.o

?輸出結(jié)果為:

?

SimpleSection.o: file format elf32-i386 SimpleSection.o architecture: i386, flags 0x00000011: HAS_RELOC, HAS_SYMS start address 0x00000000Sections: Idx Name Size VMA LMA File off Algn0 .text 00000050 00000000 00000000 00000034 2**2CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE1 .data 00000008 00000000 00000000 00000084 2**2CONTENTS, ALLOC, LOAD, DATA2 .bss 00000004 00000000 00000000 0000008c 2**2ALLOC3 .rodata 00000004 00000000 00000000 0000008c 2**0CONTENTS, ALLOC, LOAD, READONLY, DATA4 .comment 00000028 00000000 00000000 00000090 2**0CONTENTS, READONLY5 .note.GNU-stack 00000000 00000000 00000000 000000b8 2**0CONTENTS, READONLY SYMBOL TABLE: 00000000 l df *ABS* 00000000 SimpleSection.c 00000000 l d .text 00000000 .text 00000000 l d .data 00000000 .data 00000000 l d .bss 00000000 .bss 00000000 l d .rodata 00000000 .rodata 00000004 l O .data 00000004 static_var.1222 00000000 l O .bss 00000004 static_var2.1223 00000000 l d .note.GNU-stack 00000000 .note.GNU-stack 00000000 l d .comment 00000000 .comment 00000000 g O .data 00000004 global_init_var 00000004 O *COM* 00000004 global_uinit_var 00000000 g F .text 0000001b func1 00000000 *UND* 00000000 printf 0000001b g F .text 00000035 mainRELOCATION RECORDS FOR [.text]: OFFSET TYPE VALUE 00000010 R_386_32 .rodata 00000015 R_386_PC32 printf 0000002e R_386_32 .data 00000033 R_386_32 .bss 00000046 R_386_PC32 func1

也可以用下面的命令來查看各個(gè)段信息:

?

readelf -a SimpleSection.o

? 輸出結(jié)果為:

?

ELF Header:Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 Class: ELF32Data: 2's complement, little endianVersion: 1 (current)OS/ABI: UNIX - System VABI Version: 0Type: REL (Relocatable file)Machine: Intel 80386Version: 0x1Entry point address: 0x0Start of program headers: 0 (bytes into file)Start of section headers: 268 (bytes into file)Flags: 0x0Size of this header: 52 (bytes)Size of program headers: 0 (bytes)Number of program headers: 0Size of section headers: 40 (bytes)Number of section headers: 11Section header string table index: 8Section Headers:[Nr] Name Type Addr Off Size ES Flg Lk Inf Al[ 0] NULL 00000000 000000 000000 00 0 0 0[ 1] .text PROGBITS 00000000 000034 000050 00 AX 0 0 4[ 2] .rel.text REL 00000000 00041c 000028 08 9 1 4[ 3] .data PROGBITS 00000000 000084 000008 00 WA 0 0 4[ 4] .bss NOBITS 00000000 00008c 000004 00 WA 0 0 4[ 5] .rodata PROGBITS 00000000 00008c 000004 00 A 0 0 1[ 6] .comment PROGBITS 00000000 000090 000028 01 MS 0 0 1[ 7] .note.GNU-stack PROGBITS 00000000 0000b8 000000 00 0 0 1[ 8] .shstrtab STRTAB 00000000 0000b8 000051 00 0 0 1[ 9] .symtab SYMTAB 00000000 0002c4 0000f0 10 10 10 4[10] .strtab STRTAB 00000000 0003b4 000065 00 0 0 1 Key to Flags:W (write), A (alloc), X (execute), M (merge), S (strings)I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)O (extra OS processing required) o (OS specific), p (processor specific)There are no section groups in this file.There are no program headers in this file.Relocation section '.rel.text' at offset 0x41c contains 5 entries:Offset Info Type Sym.Value Sym. Name 00000010 00000501 R_386_32 00000000 .rodata 00000015 00000d02 R_386_PC32 00000000 printf 0000002e 00000301 R_386_32 00000000 .data 00000033 00000401 R_386_32 00000000 .bss 00000046 00000c02 R_386_PC32 00000000 func1There are no unwind sections in this file.Symbol table '.symtab' contains 15 entries:Num: Value Size Type Bind Vis Ndx Name0: 00000000 0 NOTYPE LOCAL DEFAULT UND 1: 00000000 0 FILE LOCAL DEFAULT ABS SimpleSection.c2: 00000000 0 SECTION LOCAL DEFAULT 1 3: 00000000 0 SECTION LOCAL DEFAULT 3 4: 00000000 0 SECTION LOCAL DEFAULT 4 5: 00000000 0 SECTION LOCAL DEFAULT 5 6: 00000004 4 OBJECT LOCAL DEFAULT 3 static_var.12227: 00000000 4 OBJECT LOCAL DEFAULT 4 static_var2.12238: 00000000 0 SECTION LOCAL DEFAULT 7 9: 00000000 0 SECTION LOCAL DEFAULT 6 10: 00000000 4 OBJECT GLOBAL DEFAULT 3 global_init_var11: 00000004 4 OBJECT GLOBAL DEFAULT COM global_uinit_var12: 00000000 27 FUNC GLOBAL DEFAULT 1 func113: 00000000 0 NOTYPE GLOBAL DEFAULT UND printf14: 0000001b 53 FUNC GLOBAL DEFAULT 1 mainNo version information found in this file. ?

?下面分析SimpleSection.o文件內(nèi)容

? 首先是Elf文件頭,其定義為(在/usr/include/elf.h中)

#define EI_NIDENT (16) typedef struct {unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */Elf32_Half e_type; /* Object file type */Elf32_Half e_machine; /* Architecture */Elf32_Word e_version; /* Object file version */Elf32_Addr e_entry; /* Entry point virtual address */Elf32_Off e_phoff; /* Program header table file offset */Elf32_Off e_shoff; /* Section header table file offset */Elf32_Word e_flags; /* Processor-specific flags */Elf32_Half e_ehsize; /* ELF header size in bytes */Elf32_Half e_phentsize; /* Program header table entry size */Elf32_Half e_phnum; /* Program header table entry count */Elf32_Half e_shentsize; /* Section header table entry size */Elf32_Half e_shnum; /* Section header table entry count */Elf32_Half e_shstrndx; /* Section header string table index */ } Elf32_Ehdr;

?大小為52個(gè)字節(jié)(16進(jìn)制表示為0x34),因此SimpleSection.o前52個(gè)字節(jié)內(nèi)容為ELF文件頭,其二進(jìn)制表示為:

0000000 457f 464c 0101 0001 0000 0000 0000 0000 0000010 0001 0003 0001 0000 0000 0000 0000 0000 0000020 010c 0000 0000 0000 0034 0000 0000 0028 0000030 000b 0008

?因?yàn)閕ntel及其兼容處理器使用了小端法,此處的-x命令選項(xiàng)是一次性輸出兩個(gè)字節(jié),所以457f實(shí)際表示了7f45,而464c實(shí)際上是4c46,依次類推。

其前16個(gè)字節(jié)(第一行,對應(yīng)e_ident[EI_NIDENT])實(shí)際表示內(nèi)容為7f454c46010101000000000000000000,前四個(gè)字節(jié)7f454c46(0x45,0x4c,0x46是'e','l','f'對應(yīng)的ascii編碼)是一個(gè)魔數(shù)(magic number),表示這是一個(gè)ELF對象。接下來的一個(gè)字節(jié)01表示是一個(gè)32位對象,接下來的一個(gè)字節(jié)01表示是小端法表示,再接下來的一個(gè)字節(jié)01表示文件頭版本。剩下的默認(rèn)都設(shè)置為0.

接下來(第二行)e_type(兩個(gè)字節(jié))值為0x0001,表示是一個(gè)重定位文件。e_machine(兩個(gè)字節(jié))值為0x0003,表示是intel80386處理器體系結(jié)構(gòu)。e_version(四個(gè)字節(jié))值為0x00000001,表示是當(dāng)前版本。e_entry(四個(gè)字節(jié))值為0x00000000,表示沒有入口點(diǎn)。e_phoff(四個(gè)字節(jié))值為0x00000000,表示沒有程序頭表。

接下來(第三行)e_shoff(四個(gè)字節(jié))值為0x0000010c,表示段表的偏移地址。e_flags(四個(gè)字節(jié))值為0x00000000,表示未知處理器特定標(biāo)志(#define EF_SH_UNKNOWN??? ??? 0x0)。e_ehsize(兩個(gè)字節(jié))值為0034,表示elf文件頭大小(正好是52個(gè)字節(jié))。e_phentsize(兩個(gè)字節(jié))和e_phnum(兩個(gè)字節(jié))的值均為0x0000,因?yàn)橹囟ㄎ晃募]有程序頭表。e_ehentsize(兩個(gè)字節(jié))值為0x0028表示段頭大小為40個(gè)字節(jié)。

接下來(第四行)e_shnum(兩個(gè)字節(jié))值為0x000b,表示段表入口有11個(gè)。e_shstrndx(兩個(gè)字節(jié))值為0x0008,表示段名串表的在段表中的索引號(hào)。

?

SimpleSection.o中緊接著ELF頭的部分是代碼段(.text)。使用下面命令對SimpleSection.o的文本段進(jìn)行反匯編:

?

objdump -d SimpleSection.o

?輸出結(jié)果為:

00000000 <func1>:0: 55 push %ebp1: 89 e5 mov %esp,%ebp3: 83 ec 18 sub $0x18,%esp6: 8b 45 08 mov 0x8(%ebp),%eax9: 89 44 24 04 mov %eax,0x4(%esp)d: c7 04 24 00 00 00 00 movl $0x0,(%esp)14: e8 fc ff ff ff call 15 <func1+0x15>19: c9 leave 1a: c3 ret 0000001b <main>:1b: 55 push %ebp1c: 89 e5 mov %esp,%ebp1e: 83 e4 f0 and $0xfffffff0,%esp21: 83 ec 20 sub $0x20,%esp24: c7 44 24 1c 01 00 00 movl $0x1,0x1c(%esp)2b: 00 2c: 8b 15 04 00 00 00 mov 0x4,%edx32: a1 00 00 00 00 mov 0x0,%eax37: 8d 04 02 lea (%edx,%eax,1),%eax3a: 03 44 24 1c add 0x1c(%esp),%eax3e: 03 44 24 18 add 0x18(%esp),%eax42: 89 04 24 mov %eax,(%esp)45: e8 fc ff ff ff call 46 <main+0x2b>4a: 8b 44 24 1c mov 0x1c(%esp),%eax4e: c9 leave 4f: c3 ret

?代碼段剛好對應(yīng)SimpleSection.o緊接著ELF頭的80(0x50)個(gè)字節(jié)代碼。即

? ? ? 8955 83e5 18ec 458b 8908 2444 0000040 c704 2404 0000 0000 fce8 ffff c9ff 55c3 0000050 e589 e483 83f0 20ec 44c7 1c24 0001 0000 0000060 158b 0004 0000 00a1 0000 8d00 0204 4403 0000070 1c24 4403 1824 0489 e824 fffc ffff 448b 0000080 1c24 c3c9 ?

?這段代碼是func1和main函數(shù)對應(yīng)的匯編代碼

?

?

?緊接著代碼段是數(shù)據(jù)段(.data)的內(nèi)容(8個(gè)字節(jié),16進(jìn)制表示為0x08),即0x00000084地址開始8個(gè)字節(jié)內(nèi)容:

?

0054 0000 0055 0000

?數(shù)據(jù)段是全局和靜態(tài)變量初始化數(shù)據(jù)的存放地。其中g(shù)lobal_init_var(int類型,四個(gè)字節(jié)) 值為84(16進(jìn)制表示為0x00000054),對應(yīng)0054 0000.而static_var(static int類型,四個(gè)字節(jié))值為85(16進(jìn)制表示為0x00000055),對應(yīng)0055 0000.

?

?

緊接著數(shù)據(jù)段的是.bss和.rodata(只讀數(shù)據(jù)段,用于存放常數(shù)串等,此處與.bss段重疊)段,大小為4個(gè)字節(jié)對應(yīng)0x0000008c地址開始四個(gè)字節(jié)內(nèi)容:

6425 000a

?恰好是字符串"%d\n"的二進(jìn)制表示(0x64對應(yīng)字符'd',0x25對應(yīng)字符'%',0x0a對應(yīng)字符LF(換行符號(hào),unix/linux下'\n'用與LF相對應(yīng),而在為window則需要用CR(回車)和LF兩個(gè)符號(hào)來對應(yīng)與'\n'),0x00對應(yīng)字符'\0'來作為串的終止符號(hào))。

緊接著.rodata段的是.comment段,它用來存放編譯器版本信息等,此處對應(yīng)0x00000090地址開始的40個(gè)字節(jié)(16進(jìn)制下為0x28):

0000090 4700 4343 203a 4728 554e 2029 2e34 2e35 00000a0 2032 3032 3131 3130 3732 2820 7270 7265 00000b0 6c65 6165 6573 0029

?實(shí)際對應(yīng)于一個(gè)字符串"\0GCC: (GNU) 4.5.2 20110127 (prerelease)\0"(感興趣的話,可以自己將上面的16進(jìn)制ascii值轉(zhuǎn)換成字符試試,剛好與使用gcc -v命令的得到的結(jié)果一致(這個(gè)結(jié)果是使用od -c SimpleSection.o和上面使用-x選項(xiàng)的結(jié)果對比得到的,該命令在我的電腦上輸出結(jié)果中最后一行為:gcc 版本 4.5.2 20110127 (prerelease) (GCC) )

?

?

緊接著.note.GNU-Stack段(該段大小為0,所以沒有對應(yīng)的實(shí)質(zhì)性內(nèi)容)

?緊接著從0x000000b8地址開始81(0x51)個(gè)字節(jié)是.shstrtab段,用來存放段的名稱。對應(yīng)內(nèi)容為:

2e00 7973 746d 6261 00000c0 2e00 7473 7472 6261 2e00 6873 7473 7472 00000d0 6261 2e00 6572 2e6c 6574 7478 2e00 6164 00000e0 6174 2e00 7362 0073 722e 646f 7461 0061 00000f0 632e 6d6f 656d 746e 2e00 6f6e 6574 472e 0000100 554e 732d 6174 6b63 00

?其對應(yīng)字符串為"\0.symtab\0.strtab\0.shstrtab\0.rel.text\0.data\0.bss\0.rodata\0.comment\0.note.GNU-Stack\0"(雙引號(hào)是我手動(dòng)添加的,為了看起來更好看,這個(gè)字符串是我用od -c SimpleSection.o得到的結(jié)果與前面使用-x選項(xiàng)得到結(jié)果對比得到的。)

?

?

緊接著.shstrtab段的是段表(Section table),從前面對ELF頭的解析可以知道段表的地址是從0x0000010c(e_shoff項(xiàng))開始,而上面的.shstrtab的開始地址為0xb8,大小為0x51,所以此處段表應(yīng)該是0x109開始,但是從前面使用readelf得出結(jié)果可以知道,段表對齊要求是4個(gè)字節(jié)對齊,所以地址最后兩位必須是00,這就導(dǎo)致是從0x10c開始,留下了三個(gè)字節(jié)的空洞(英文為hole)。再根據(jù)e_shnum=11和ehentsize=40可知,有11個(gè)段,每個(gè)段占40個(gè)字節(jié)大小,總共占據(jù)440個(gè)字節(jié)(16進(jìn)制為0x1b8)。段入口的類型定義如下(/usr/include/elf.h):

typedef struct {Elf32_Word sh_name; /* Section name (string tbl index) */Elf32_Word sh_type; /* Section type */Elf32_Word sh_flags; /* Section flags */Elf32_Addr sh_addr; /* Section virtual addr at execution */Elf32_Off sh_offset; /* Section file offset */Elf32_Word sh_size; /* Section size in bytes */Elf32_Word sh_link; /* Link to another section */Elf32_Word sh_info; /* Additional section information */Elf32_Word sh_addralign; /* Section alignment */Elf32_Word sh_entsize; /* Entry size if section holds table */ } Elf32_Shdr;

?恰好占據(jù)了40個(gè)字節(jié)。

從0x0000010c開始有11個(gè)段,每個(gè)段占40個(gè)字節(jié)大小。

第一個(gè)段為0x0000010c-0x00000133,其中內(nèi)容全部為0,所以不表示任何段。

第二個(gè)段為0x00000134-0x0000015b,對應(yīng)內(nèi)容為:

001f 0000 0001 0000 0006 0000 0000140 0000 0000 0034 0000 0050 0000 0000 0000 0000150 0000 0000 0004 0000 0000 0000

?段中每個(gè)成員均為4個(gè)字節(jié),所以分析起來相對簡單一些。

?sh_name值為0x0000001f,它表示該段名稱在.shstrtab中偏移量,通過計(jì)算可知該名稱為.text。sh_type值為0x00000001(對應(yīng)SHT_PROGBITS),表示這個(gè)段擁有程序所定義的信息,其格式和含義完全有該程序確定。sh_flags值為0x00000006(對應(yīng)于SHF_ALLOC和SHF_EXECINSTR)。sh_addr值為0x00000000,表示這個(gè)段不會(huì)出現(xiàn)在進(jìn)程的地址鏡像中。

sh_offset值為0x00000034(偏移地址),sh_size值為0x00000050,表示代碼段大小為80(0x50)個(gè)字節(jié)。sh_link值為0x00000000,表示沒有鏈接信息。sh_info值為0x00000000,表示沒有輔助信息。sh_addalign值為0x00000004,表示4個(gè)字節(jié)對齊,sh_entsize值為0x00000000,表示沒有入口。

第三個(gè)段為0x0000015c-0x00000184,對應(yīng)內(nèi)容為:

001b 0000 0000160 0009 0000 0000 0000 0000 0000 041c 0000 0000170 0028 0000 0009 0000 0001 0000 0004 0000 0000180 0008 0000

?該段為.rel.text段(偏移量為0x0000001b),sh_type為0x00000009(對應(yīng)SHT_REL),sh_offset為0x0000041c,sh_size為0x00000028(40個(gè)字節(jié))。sh_link和sh_info分別為9和1,分別表示相關(guān)符號(hào)表索引和重定位應(yīng)用段的段頭索引。其余段的內(nèi)容不再詳細(xì)分析,可以自己分析并于前面readelf輸出結(jié)果相對照。

第四個(gè)段為0x00000184-0x000001ac(0x25,即.shstrtab第37個(gè)字節(jié)偏移處,即.data段),對應(yīng)內(nèi)容:

0025 0000 0001 0000 0003 0000 0000190 0000 0000 0084 0000 0008 0000 0000 0000 00001a0 0000 0000 0004 0000 0000 0000

第五個(gè)段為0x000001ac-0x00001d4(0x2b,即第43個(gè)字節(jié)偏移處,即.bss段),對應(yīng)內(nèi)容為:

002b 0000 00001b0 0008 0000 0003 0000 0000 0000 008c 0000 00001c0 0004 0000 0000 0000 0000 0000 0004 0000 00001d0 0000 0000 ?

第六個(gè)段為0x000001d4-0x000001fc(0x30,即第48個(gè)字節(jié)偏移處,即.rodata段),對應(yīng)內(nèi)容為:

0030 0000 0001 0000 0002 0000 00001e0 0000 0000 008c 0000 0004 0000 0000 0000 00001f0 0000 0000 0001 0000 0000 0000 ?

第七個(gè)段為0x000001fc-0x00000224(0x38,即第56個(gè)字節(jié)偏移處,即.comment段),對應(yīng)內(nèi)容為:

0038 0000 0000200 0001 0000 0030 0000 0000 0000 0090 0000 0000210 0028 0000 0000 0000 0000 0000 0001 0000 0000220 0001 0000

第八個(gè)段為0x00000224-0x0000024c(0x41,即第65個(gè)字節(jié)偏移處,即.note.GNU-Stack段),對應(yīng)內(nèi)容為:

? ? ? ? ? ? ? ? ? ? ? ? ? 0041 0000 0001 0000 0000 0000 0000230 0000 0000 00b8 0000 0000 0000 0000 0000 0000240 0000 0000 0001 0000 0000 0000

第九個(gè)段為0x0000024c-0x00000274(0x11,即第17個(gè)字節(jié)偏移處,即.shstrtab段),對應(yīng)內(nèi)容為:

0011 0000 0000250 0003 0000 0000 0000 0000 0000 00b8 0000 0000260 0051 0000 0000 0000 0000 0000 0001 0000 0000270 0000 0000 ?

第十個(gè)段為0x00000274-0x0000029c(0x01,即第1個(gè)字節(jié)偏移處,即.symtab段),對應(yīng)內(nèi)容為:

0001 0000 0002 0000 0000 0000 0000280 0000 0000 02c4 0000 00f0 0000 000a 0000 0000290 000a 0000 0004 0000 0010 0000 ?

第十一個(gè)段為0x0000029c-0x000002c4(0x9,即第9個(gè)字節(jié)偏移處,即.strtab段),對應(yīng)內(nèi)容為:

0009 0000 00002a0 0003 0000 0000 0000 0000 0000 03b4 0000 00002b0 0065 0000 0000 0000 0000 0000 0001 0000 00002c0 0000 0000

所以段表中表示的段從偏移地址1開始(1-10,因?yàn)榈谝粋€(gè)段全為空)依次為.text, .rel.text, .data, .bss, .rodata, .comment, .note.GNU-Stack, .shstrtab, .symtab, .strtab)

?

?從0x000002c4開始為.symtab(符號(hào)表)段,大小為0xf0(240個(gè)字節(jié)),對應(yīng)內(nèi)容為:

?

0000 0000 0000 0000 0000 0000 00002d0 0000 0000 0001 0000 0000 0000 0000 0000 00002e0 0004 fff1 0000 0000 0000 0000 0000 0000 00002f0 0003 0001 0000 0000 0000 0000 0000 0000 0000300 0003 0003 0000 0000 0000 0000 0000 0000 0000310 0003 0004 0000 0000 0000 0000 0000 0000 0000320 0003 0005 0011 0000 0004 0000 0004 0000 0000330 0001 0003 0021 0000 0000 0000 0004 0000 0000340 0001 0004 0000 0000 0000 0000 0000 0000 0000350 0003 0007 0000 0000 0000 0000 0000 0000 0000360 0003 0006 0032 0000 0000 0000 0004 0000 0000370 0011 0003 0042 0000 0004 0000 0004 0000 0000380 0011 fff2 0053 0000 0000 0000 001b 0000 0000390 0012 0001 0059 0000 0000 0000 0000 0000 00003a0 0010 0000 0060 0000 001b 0000 0035 0000 00003b0 0012 0001

?符號(hào)表結(jié)構(gòu)定義(/usr/include/elf.h):

?

typedef struct {Elf32_Word st_name; /* Symbol name (string tbl index) */Elf32_Addr st_value; /* Symbol value */Elf32_Word st_size; /* Symbol size */unsigned char st_info; /* Symbol type and binding */unsigned char st_other; /* Symbol visibility */Elf32_Section st_shndx; /* Section index */ } Elf32_Sym;

? 該結(jié)構(gòu)大小為16個(gè)字節(jié),而整個(gè)符號(hào)表段大小為240個(gè)字節(jié),所以總共可以分成15個(gè)符號(hào)(有些符號(hào)未使用)。這15個(gè)符號(hào)剛好和前面objdump輸出的符號(hào)表(14個(gè)符號(hào),第一個(gè)符號(hào)為空,所以被忽略)結(jié)果相對應(yīng):

?

SYMBOL TABLE: 00000000 l df *ABS* 00000000 SimpleSection.c 00000000 l d .text 00000000 .text 00000000 l d .data 00000000 .data 00000000 l d .bss 00000000 .bss 00000000 l d .rodata 00000000 .rodata 00000004 l O .data 00000004 static_var.1222 00000000 l O .bss 00000004 static_var2.1223 00000000 l d .note.GNU-stack 00000000 .note.GNU-stack 00000000 l d .comment 00000000 .comment 00000000 g O .data 00000004 global_init_var 00000004 O *COM* 00000004 global_uinit_var 00000000 g F .text 0000001b func1 00000000 *UND* 00000000 printf 0000001b g F .text 00000035 main

? 也和使用readelf中符號(hào)表相關(guān)內(nèi)容對應(yīng)(readelf命令輸出結(jié)果比objdump輸出結(jié)果看起來更好看一些):

?

Symbol table '.symtab' contains 15 entries:Num: Value Size Type Bind Vis Ndx Name0: 00000000 0 NOTYPE LOCAL DEFAULT UND 1: 00000000 0 FILE LOCAL DEFAULT ABS SimpleSection.c2: 00000000 0 SECTION LOCAL DEFAULT 1 3: 00000000 0 SECTION LOCAL DEFAULT 3 4: 00000000 0 SECTION LOCAL DEFAULT 4 5: 00000000 0 SECTION LOCAL DEFAULT 5 6: 00000004 4 OBJECT LOCAL DEFAULT 3 static_var.12227: 00000000 4 OBJECT LOCAL DEFAULT 4 static_var2.12238: 00000000 0 SECTION LOCAL DEFAULT 7 9: 00000000 0 SECTION LOCAL DEFAULT 6 10: 00000000 4 OBJECT GLOBAL DEFAULT 3 global_init_var11: 00000004 4 OBJECT GLOBAL DEFAULT COM global_uinit_var12: 00000000 27 FUNC GLOBAL DEFAULT 1 func113: 00000000 0 NOTYPE GLOBAL DEFAULT UND printf14: 0000001b 53 FUNC GLOBAL DEFAULT 1 main ?

15個(gè)符號(hào)中分析比較重要的符號(hào),其他部分可以自己分析。

首先是0x000002d4-0x000002e3,對應(yīng)內(nèi)容:

?

0001 0000 0000 0000 0000 0000 00002e0 0004 fff1

?該部分內(nèi)容中st_name值為0x00000001,表示在常數(shù)串表中偏移量為1,即SimpleSection.c的首地址。st_info值為0x04,表示是文件名和局部符號(hào)。st_shndx值為0xfff1(即SHN_ABS),寶石該付好包含了一個(gè)絕對值。其他成員值為0.

接下來64個(gè)字節(jié)(地址0x000002e4-0x00000323,每個(gè)符號(hào)占16個(gè)字節(jié),4個(gè)符號(hào))對應(yīng)內(nèi)容為:

?

0000 0000 0000 0000 0000 0000 00002f0 0003 0001 0000 0000 0000 0000 0000 0000 0000300 0003 0003 0000 0000 0000 0000 0000 0000 0000310 0003 0004 0000 0000 0000 0000 0000 0000 0000320 0003 0005

? 這四個(gè)符號(hào)除了值有st_shndx成員的值不同(分別為1,3,4,5),其他成員均相同。而其他成員值有st_info的值有實(shí)際含義,均為0x03,表示該符號(hào)是一個(gè)段,所以1,3,4,5分別對應(yīng)段的偏移,分別表示.text,.data,.bss,.rodata(可以查看readelf -a輸出結(jié)果,其中段表部分第一列即為偏移量)。

接下來比較重要的符號(hào)是0x00000324-0x00000333,對應(yīng)內(nèi)容:

?

0011 0000 0004 0000 0004 0000 0000330 0001 0003

?這部分內(nèi)容st_name值為0x00000011,表示在常數(shù)串表中偏移量為0x00000011(17),即static_var.1222的首地址。st_size的值均為0x00000004(int類型),分別表示符號(hào)值和符號(hào)大小。st_info值為0x01,表示是一個(gè)局部變量。st_value值為0x00000004,st_shndx值為0x0003,表示偏移為4的段(即.data段)中偏移地址為3的位置。

接下來的重要符號(hào)地址為0x00000334-0x00000343,對應(yīng)內(nèi)容:

?

0021 0000 0000 0000 0004 0000 0000340 0001 0004

?該部分內(nèi)容st_name值為0x00000021,表示常數(shù)串中偏移量為0x00000021(33),即static_var2.1223的首地址。st_size值為0x00000004(int類型)。st_info值為0x01,表示是一個(gè)局部變量.st_shndx值為0x0003,st_value值為0x00000000,表示偏移為0的段中偏移地址為4的未知。

另一個(gè)重要符號(hào)地址為0x00000364-0x00000373,對應(yīng)內(nèi)容:

?

0032 0000 0000 0000 0004 0000 0000370 0011 0003

?該部分st_name值為0x00000032,表示常數(shù)串中偏移量為0x00000032(50),即global_init_var的首地址。st_info值為0x11,表示全局變量。其他成員含義與上一個(gè)符號(hào)類似。

還有一個(gè)重要符號(hào)地址為0x00000374-0x00000383,對應(yīng)內(nèi)容:

?

0042 0000 0004 0000 0004 0000 0000380 0011 fff2

?該部分st_name值為0x00000042,表示常數(shù)串中偏移量為0x0000042(66),即global_uint_var的首地址。st_shndx值為0xfff2,表示該符號(hào)是common類型符號(hào)。st_value值為0x00000004,表示是4個(gè)字節(jié)對齊。st_size值為0x00000004,表示大小為4(int類型)。

還有重要符號(hào)地址為0x00000384-0x00000393,對應(yīng)內(nèi)容:

?

0053 0000 0000 0000 001b 0000 0000390 0012 0001

?該部分st_name值為0x00000053,表示對應(yīng)func1首地址。st_info值為0x12,表示是全局函數(shù)。st_value值為0x0000000,st_size值為0x0000001b,故表示偏移為0(.text)的段中28個(gè)字節(jié)。

?

?

從 0x000003b4開始為.strtab(字符串表)段,大小為0x65(101個(gè)字節(jié)),對應(yīng)內(nèi)容為:

?

? ? ? ? ? ? ? ? ? ? ? ? ?? 5300 6d69 6c70 5365 6365 6974 00003c0 6e6f 632e 7300 6174 6974 5f63 6176 2e72 00003d0 3231 3232 7300 6174 6974 5f63 6176 3272 00003e0 312e 3232 0033 6c67 626f 6c61 695f 696e 00003f0 5f74 6176 0072 6c67 626f 6c61 755f 6e69 0000400 7469 765f 7261 6600 6e75 3163 7000 6972 0000410 746e 0066 616d 6e69 00

?對應(yīng)字符串為"\0SimpleSection.c\0static_var.1222\0static_var2.1223\0global_init_var\0global_uint_var\0func1\0printf\0main\0"(使用od -c SimpleSection.o與-x選項(xiàng)得到結(jié)果對比即可)

?

?

從0x0000041c開始為.rel.text段(重定位表),大小為0x28(40個(gè)字節(jié)),對應(yīng)內(nèi)容為:

0010 0000 0000420 0501 0000 0015 0000 0d02 0000 002e 0000 0000430 0301 0000 0033 0000 0401 0000 0046 0000 0000440 0c02 0000

重定位表數(shù)據(jù)結(jié)構(gòu)(/usr/include/elf.h):

typedef struct {Elf32_Addr r_offset; /* Address */Elf32_Word r_info; /* Relocation type and symbol index */ } Elf32_Rel;

?該數(shù)據(jù)結(jié)構(gòu)大小為8個(gè)字節(jié),所以40個(gè)字節(jié)應(yīng)該包含5個(gè)這樣的結(jié)構(gòu)。

?而需要重定位的符號(hào)可以使用下面的命令列出:

objdump -r SimpleSection.o

?輸出結(jié)果:

?

SimpleSection.o: file format elf32-i386RELOCATION RECORDS FOR [.text]: OFFSET TYPE VALUE 00000010 R_386_32 .rodata 00000015 R_386_PC32 printf 0000002e R_386_32 .data 00000033 R_386_32 .bss 00000046 R_386_PC32 func1

?剛好是5個(gè)符號(hào)。

?

根據(jù)上面內(nèi)容,SimpleSection.o的結(jié)構(gòu)形式如下:

????????? ------------------------------------- 0x00000000

????????? |?? ELF Header(e_shoff=0x10c)?????

????????? ------------------------------------- 0x00000034

0x50? | .text?????????????

????????? ------------------------------------- 0x00000084

0x08? | .data

????????? ------------------------------------- 0x0000008c

0x04? | .rodata

????????? ------------------------------------- 0x00000090

0x28? | .comment

????????? ------------------------------------- 0x000000b8

0x51? | .shsttab

????????? ------------------------------------- 0x00000109

?????????? --------------------------------------0x0000010c

0x1b8 | Section Table

?????????? -------------------------------------- 0x000002c4

0xf0?? |? .symtab

????????? -------------------------------------- 0x000003b4

0x65? | ? .strtab

????????? -------------------------------------- 0x0000041c

0x28? |?? .rel.text

????????? --------------------------------------- 0x00000444

?

根據(jù)上面的實(shí)例觀察可知,分析一個(gè)elf文件的內(nèi)部構(gòu)造,可以先找到elf頭,并找到其中幾個(gè)關(guān)鍵成員e_shoff(段表偏移地址), e_shentnum(段的個(gè)數(shù)), e_shsize(每個(gè)段的大小)。這樣可以到段表中再分析每個(gè)段相關(guān)信息。另外,這個(gè)例子中elf文件是重定位文件,它缺乏elf中的一個(gè)重要段(程序文件頭表),這個(gè)表只存在于可執(zhí)行文件或動(dòng)態(tài)鏈接庫文件中。它可以通過elf頭的e_phoff(文件頭表偏移地址),e_phnum(文件頭表個(gè)數(shù))和e_phsize(每個(gè)表大小)來確定該文件頭表的位置及大小。分析方式和elf頭類似。文件頭表類型定義(/usr/include/elf.h):

?

typedef struct {Elf32_Word p_type; /* Segment type */Elf32_Off p_offset; /* Segment file offset */Elf32_Addr p_vaddr; /* Segment virtual address */Elf32_Addr p_paddr; /* Segment physical address */Elf32_Word p_filesz; /* Segment size in file */Elf32_Word p_memsz; /* Segment size in memory */Elf32_Word p_flags; /* Segment flags */Elf32_Word p_align; /* Segment alignment */ } Elf32_Phdr;/* Special value for e_phnum. This indicates that the real number ofprogram headers is too large to fit into e_phnum. Instead the realvalue is in the field sh_info of section 0. */#define PN_XNUM 0xffff/* Legal values for p_type (segment type). */#define PT_NULL 0 /* Program header table entry unused */ #define PT_LOAD 1 /* Loadable program segment */ #define PT_DYNAMIC 2 /* Dynamic linking information */ #define PT_INTERP 3 /* Program interpreter */ #define PT_NOTE 4 /* Auxiliary information */ #define PT_SHLIB 5 /* Reserved */ #define PT_PHDR 6 /* Entry for header table itself */ #define PT_TLS 7 /* Thread-local storage segment */ #define PT_NUM 8 /* Number of defined types */ #define PT_LOOS 0x60000000 /* Start of OS-specific */ #define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */ #define PT_GNU_STACK 0x6474e551 /* Indicates stack executability */ #define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */ #define PT_LOSUNW 0x6ffffffa #define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */ #define PT_SUNWSTACK 0x6ffffffb /* Stack segment */ #define PT_HISUNW 0x6fffffff #define PT_HIOS 0x6fffffff /* End of OS-specific */ #define PT_LOPROC 0x70000000 /* Start of processor-specific */ #define PT_HIPROC 0x7fffffff /* End of processor-specific *//* Legal values for p_flags (segment flags). */#define PF_X (1 << 0) /* Segment is executable */ #define PF_W (1 << 1) /* Segment is writable */ #define PF_R (1 << 2) /* Segment is readable */ #define PF_MASKOS 0x0ff00000 /* OS-specific */ #define PF_MASKPROC 0xf0000000 /* Processor-specific */

?感興趣的可以自己分析,并和readelf -a得到結(jié)果對比來加深理解。

例如我寫的一個(gè)小測試程序:

?

#include <stdio.h> #include <elf.h> int main(void) {printf("%d\n",sizeof(Elf32_Sym));printf("Hello, World\n");return 0; }

?使用下面命令編譯:

?

gcc -o test test.c

?得到一個(gè)名為test的可執(zhí)行文件。

使用下面命令得到test文件文件頭表相關(guān)部分的結(jié)構(gòu):

?

readelf -l test

?該命令輸出:

?

Elf file type is EXEC (Executable file) Entry point 0x8048340 There are 8 program headers, starting at offset 52Program Headers:Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg AlignPHDR 0x000034 0x08048034 0x08048034 0x00100 0x00100 R E 0x4INTERP 0x000134 0x08048134 0x08048134 0x00013 0x00013 R 0x1[Requesting program interpreter: /lib/ld-linux.so.2]LOAD 0x000000 0x08048000 0x08048000 0x005b8 0x005b8 R E 0x1000LOAD 0x0005b8 0x080495b8 0x080495b8 0x0010c 0x00114 RW 0x1000DYNAMIC 0x0005cc 0x080495cc 0x080495cc 0x000d0 0x000d0 RW 0x4NOTE 0x000148 0x08048148 0x08048148 0x00020 0x00020 R 0x4GNU_EH_FRAME 0x000514 0x08048514 0x08048514 0x00024 0x00024 R 0x4GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4Section to Segment mapping:Segment Sections...00 01 .interp 02 .interp .note.ABI-tag .hash .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame 03 .ctors .dtors .jcr .dynamic .got .got.plt .data .bss 04 .dynamic 05 .note.ABI-tag 06 .eh_frame_hdr 07

?使用hexdump得到test文件前308個(gè)字節(jié)(前52個(gè)字節(jié)為ELF頭內(nèi)容,后面256個(gè)字節(jié)(這部分是文件頭表,可以從0000001c地址開始四個(gè)字節(jié)值0x00000034(e_phoff)知道文件頭表偏移地址是從第52個(gè)字節(jié)開始,每個(gè)表32(e_phentsize,0x0000002a地址開始的2個(gè)字節(jié),0x0020)個(gè)字節(jié),共8(e_phnum,0x0000002c地址開始的2個(gè)字節(jié),對應(yīng)0x0008)個(gè)表)內(nèi)容:

?

hexdump -x test -n 308

?輸出結(jié)果:

?

0000000 457f 464c 0101 0001 0000 0000 0000 0000 0000010 0002 0003 0001 0000 8340 0804 0034 0000 0000020 07e8 0000 0000 0000 0034 0020 0008 0028 0000030 001e 001b 0006 0000 0034 0000 8034 0804 0000040 8034 0804 0100 0000 0100 0000 0005 0000 0000050 0004 0000 0003 0000 0134 0000 8134 0804 0000060 8134 0804 0013 0000 0013 0000 0004 0000 0000070 0001 0000 0001 0000 0000 0000 8000 0804 0000080 8000 0804 05b8 0000 05b8 0000 0005 0000 0000090 1000 0000 0001 0000 05b8 0000 95b8 0804 00000a0 95b8 0804 010c 0000 0114 0000 0006 0000 00000b0 1000 0000 0002 0000 05cc 0000 95cc 0804 00000c0 95cc 0804 00d0 0000 00d0 0000 0006 0000 00000d0 0004 0000 0004 0000 0148 0000 8148 0804 00000e0 8148 0804 0020 0000 0020 0000 0004 0000 00000f0 0004 0000 e550 6474 0514 0000 8514 0804 0000100 8514 0804 0024 0000 0024 0000 0004 0000 0000110 0004 0000 e551 6474 0000 0000 0000 0000 0000120 0000 0000 0000 0000 0000 0000 0006 0000 0000130 0004 0000 0000134

?文件頭段第一個(gè)表(0x00000034-0x00000053)內(nèi)容:

0006 0000 0034 0000 8034 0804 0000040 8034 0804 0100 0000 0100 0000 0005 0000 0000050 0004 0000

?剛好有8個(gè)成員,每個(gè)成員4個(gè)字節(jié)。

?p_type值為0x00000006,表示文件頭表入口。p_offset值為0x00000034,表示其偏移地址。p_vaddr值為0x08048034,表示虛擬地址。p_paddr值為0x08048034,表示物理地址。p_filesz值為0x00000100,表示文件中段的大小256個(gè)字節(jié)。p_memsz值為0x00000100,表示內(nèi)存中段大小為256個(gè)字節(jié)。p_flags值為0x00000005,表示該段可讀并且可執(zhí)行。p_align值為0x00000004表示該段是4字節(jié)對齊。這個(gè)段表剛好對應(yīng)文件頭段的256個(gè)字節(jié)。

其他內(nèi)容不再詳細(xì)分析,感興趣的可以自己探索研究

總結(jié)

以上是生活随笔為你收集整理的elf文件格式实例解析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。