我們接續 loader v0.4 的工作,強化一下輸出結果的可讀性;先來比較一下 loader v0.4 與 loader v0.5 的輸出畫面。
$ ./loader-0.4 loader-0.4 | $ ./loader-0.5 loader-0.4 |
ELF Identification Class: 32-bit objects Machine: Intel 80386 Num of secionts: 34 .interp .note.ABI-tag .hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt .init .plt .text .fini .rodata .eh_frame .data .dynamic .ctors .dtors .jcr .got .bss .comment .debug_aranges .debug_pubnames .debug_info .debug_abbrev .debug_line .debug_frame .debug_str .shstrtab .symtab .strtab |
ELF Identification Class: 32-bit objects Machine: Intel 80386 Name Size FileOff [01] .interp 19 244 [02] .note.ABI-tag 32 264 [03] .hash 56 296 [04] .dynsym 144 352 [05] .dynstr 98 496 [06] .gnu.version 18 594 [07] .gnu.version_r 32 612 [08] .rel.dyn 8 644 [09] .rel.plt 48 652 [10] .init 23 700 [11] .plt 112 724 [12] .text 1292 836 [13] .fini 27 2128 [14] .rodata 348 2156 [15] .eh_frame 4 2504 [16] .data 12 2508 [17] .dynamic 200 2520 [18] .ctors 8 2720 [19] .dtors 8 2728 [20] .jcr 4 2736 [21] .got 40 2740 [22] .bss 4 2780 [23] .comment 306 2780 [24] .debug_aranges 120 3088 [25] .debug_pubnames 37 3208 [26] .debug_info 2692 3245 [27] .debug_abbrev 312 5937 [28] .debug_line 636 6249 [29] .debug_frame 20 6888 [30] .debug_str 1722 6908 [31] .shstrtab 299 8630 [32] .symtab 1856 10292 [33] .strtab 1132 12148 |
Cool!做出了 'objdump -x' 的部份功能。頗為有趣,那麼用 objdump 來互相比較一下看看。
loader v0.5 v.s. objdump v.s. readelf
$ objdump -x loader-0.4(只擷取 section 輸出結果) | $ ./loader-0.5 loader-0.4 |
Sections: Idx Name Size VMA LMA File off Algn 0 .interp 00000013 080480f4 080480f4 000000f4 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA 1 .note.ABI-tag 00000020 08048108 08048108 00000108 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 2 .hash 00000038 08048128 08048128 00000128 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 3 .dynsym 00000090 08048160 08048160 00000160 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 4 .dynstr 00000062 080481f0 080481f0 000001f0 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA 5 .gnu.version 00000012 08048252 08048252 00000252 2**1 CONTENTS, ALLOC, LOAD, READONLY, DATA 6 .gnu.version_r 00000020 08048264 08048264 00000264 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 7 .rel.dyn 00000008 08048284 08048284 00000284 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 8 .rel.plt 00000030 0804828c 0804828c 0000028c 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 9 .init 00000017 080482bc 080482bc 000002bc 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 10 .plt 00000070 080482d4 080482d4 000002d4 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 11 .text 0000050c 08048344 08048344 00000344 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 12 .fini 0000001b 08048850 08048850 00000850 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE 13 .rodata 0000015c 0804886c 0804886c 0000086c 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 14 .eh_frame 00000004 080489c8 080489c8 000009c8 2**2 CONTENTS, ALLOC, LOAD, READONLY, DATA 15 .data 0000000c 080499cc 080499cc 000009cc 2**2 CONTENTS, ALLOC, LOAD, DATA 16 .dynamic 000000c8 080499d8 080499d8 000009d8 2**2 CONTENTS, ALLOC, LOAD, DATA 17 .ctors 00000008 08049aa0 08049aa0 00000aa0 2**2 CONTENTS, ALLOC, LOAD, DATA 18 .dtors 00000008 08049aa8 08049aa8 00000aa8 2**2 CONTENTS, ALLOC, LOAD, DATA 19 .jcr 00000004 08049ab0 08049ab0 00000ab0 2**2 CONTENTS, ALLOC, LOAD, DATA 20 .got 00000028 08049ab4 08049ab4 00000ab4 2**2 CONTENTS, ALLOC, LOAD, DATA 21 .bss 00000004 08049adc 08049adc 00000adc 2**2 ALLOC 22 .comment 00000132 00000000 00000000 00000adc 2**0 CONTENTS, READONLY 23 .debug_aranges 00000078 00000000 00000000 00000c10 2**3 CONTENTS, READONLY, DEBUGGING 24 .debug_pubnames 00000025 00000000 00000000 00000c88 2**0 CONTENTS, READONLY, DEBUGGING 25 .debug_info 00000a84 00000000 00000000 00000cad 2**0 CONTENTS, READONLY, DEBUGGING 26 .debug_abbrev 00000138 00000000 00000000 00001731 2**0 CONTENTS, READONLY, DEBUGGING 27 .debug_line 0000027c 00000000 00000000 00001869 2**0 CONTENTS, READONLY, DEBUGGING 28 .debug_frame 00000014 00000000 00000000 00001ae8 2**2 CONTENTS, READONLY, DEBUGGING 29 .debug_str 000006ba 00000000 00000000 00001afc 2**0 CONTENTS, READONLY, DEBUGGING |
ELF Identification Class: 32-bit objects Machine: Intel 80386 Name Size FileOff [00] .interp 19 244 [01] .note.ABI-tag 32 264 [02] .hash 56 296 [03] .dynsym 144 352 [04] .dynstr 98 496 [05] .gnu.version 18 594 [06] .gnu.version_r 32 612 [07] .rel.dyn 8 644 [08] .rel.plt 48 652 [09] .init 23 700 [10] .plt 112 724 [11] .text 1292 836 [12] .fini 27 2128 [13] .rodata 348 2156 [14] .eh_frame 4 2504 [15] .data 12 2508 [16] .dynamic 200 2520 [17] .ctors 8 2720 [18] .dtors 8 2728 [19] .jcr 4 2736 [20] .got 40 2740 [21] .bss 4 2780 [22] .comment 306 2780 [23] .debug_aranges 120 3088 [24] .debug_pubnames 37 3208 [25] .debug_info 2692 3245 [26] .debug_abbrev 312 5937 [27] .debug_line 636 6249 [28] .debug_frame 20 6888 [29] .debug_str 1722 6908 [30] .shstrtab 299 8630 [31] .symtab 1856 10292 [32] .strtab 1132 12148 |
不過事情好像有點怪異,我們的 loader v0.5 怎麼在最後多出 3 個 section 呢?被附身了。
不過,原來是 objdump 不會把最後這 3 個 section 印出來啦,這 3 個 section 分別是:
1) .shstrtab:section header straing table
2) .symtab:symbol table
3) .strtab:string table
哇塞!原來 symbol table 藏在這裡啊。但是,如果我們改用 readelf 來讀 ELF,就可以看到完整的 ELF headers 了,而且輸出的畫面也比較具可讀性:
$ readelf -S loader-0.4
There are 34 section headers, starting at offset 0x22e4: Section Headers: [Nr] Name Type Addr Off Size ES Flg Lk Inf Al [ 0] NULL 00000000 000000 000000 00 0 0 0 [ 1] .interp PROGBITS 080480f4 0000f4 000013 00 A 0 0 1 [ 2] .note.ABI-tag NOTE 08048108 000108 000020 00 A 0 0 4 [ 3] .hash HASH 08048128 000128 000038 04 A 4 0 4 [ 4] .dynsym DYNSYM 08048160 000160 000090 10 A 5 1 4 [ 5] .dynstr STRTAB 080481f0 0001f0 000062 00 A 0 0 1 [ 6] .gnu.version VERSYM 08048252 000252 000012 02 A 4 0 2 [ 7] .gnu.version_r VERNEED 08048264 000264 000020 00 A 5 1 4 [ 8] .rel.dyn REL 08048284 000284 000008 08 A 4 0 4 [ 9] .rel.plt REL 0804828c 00028c 000030 08 A 4 b 4 [10] .init PROGBITS 080482bc 0002bc 000017 00 AX 0 0 4 [11] .plt PROGBITS 080482d4 0002d4 000070 04 AX 0 0 4 [12] .text PROGBITS 08048344 000344 00050c 00 AX 0 0 4 [13] .fini PROGBITS 08048850 000850 00001b 00 AX 0 0 4 [14] .rodata PROGBITS 0804886c 00086c 00015c 00 A 0 0 4 [15] .eh_frame PROGBITS 080489c8 0009c8 000004 00 A 0 0 4 [16] .data PROGBITS 080499cc 0009cc 00000c 00 WA 0 0 4 [17] .dynamic DYNAMIC 080499d8 0009d8 0000c8 08 WA 5 0 4 [18] .ctors PROGBITS 08049aa0 000aa0 000008 00 WA 0 0 4 [19] .dtors PROGBITS 08049aa8 000aa8 000008 00 WA 0 0 4 [20] .jcr PROGBITS 08049ab0 000ab0 000004 00 WA 0 0 4 [21] .got PROGBITS 08049ab4 000ab4 000028 04 WA 0 0 4 [22] .bss NOBITS 08049adc 000adc 000004 00 WA 0 0 4 [23] .comment PROGBITS 00000000 000adc 000132 00 0 0 1 [24] .debug_aranges PROGBITS 00000000 000c10 000078 00 0 0 8 [25] .debug_pubnames PROGBITS 00000000 000c88 000025 00 0 0 1 [26] .debug_info PROGBITS 00000000 000cad 000a84 00 0 0 1 [27] .debug_abbrev PROGBITS 00000000 001731 000138 00 0 0 1 [28] .debug_line PROGBITS 00000000 001869 00027c 00 0 0 1 [29] .debug_frame PROGBITS 00000000 001ae8 000014 00 0 0 4 [30] .debug_str PROGBITS 00000000 001afc 0006ba 01 MS 0 0 1 [31] .shstrtab STRTAB 00000000 0021b6 00012b 00 0 0 1 [32] .symtab SYMTAB 00000000 002834 000740 10 33 54 4 [33] .strtab STRTAB 00000000 002f74 00046c 00 0 0 1 Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings) I (info), L (link order), G (group), x (unknown) O (extra OS processing required) o (OS specific), p (processor specific)
原來這是工具的問題。嗯!好吧,以後都改用 readelf 來玩吧。
Index 0: undefined
還有一點就是,ELF headers index 0 在 SysV ABI 裡的定義是「undefined」,readelf 把它輸出成 NULL,我們的範例跟 objdump 一樣,直接跳過!
readelf 輸出的其它 column 分述如下。
Type
「type」欄位的話就是在「ELF(Executable and Linking Format)格式教學文件, #7: 讀 ELF 的 Section Name(透過 strtab)」裡介紹到的 sh_type。
Addr
這個好玩,不過目前先跳過。(>_<)
Off、Size
跟我們的 loader v0.5 輸出結果一樣,分別代表 section 在 ELF object 裡的 file offset 與其大小(bytes)。readelf 是用十六進位輸出,我們的範例是用十進位輸出。
範例程式一樣可以由「http://tw.jollen.org/elf-programming/」下載。
Also See |
Jollen's Blog 使用 Github issues 與讀者交流討論。請點擊上方的文章專屬 issue,或 open a new issue
您可透過電子郵件 jollen@jollen.org,或是 Linkedin 與我連絡。更歡迎使用微信,請搜尋 WeChat ID:jollentw