一、目標文件
在 UNIX® 和 Linux® 中,任何事物都是文件。UNIX 和 Linux 編程實際上是編寫處理各種文件的代碼。系統由許多類型的文件組成,但目標文件具有一種特殊的設計,提供了靈活和多樣的用途。
目標文件是包含帶有附加地址和值的助記符號的路線圖。這些符號可以用來對各種代碼段和數據段進行命名,包括經過初始化的和未初始化的。它們也可以用來定位嵌入的調試信息,就像語義 Web,非常適合由程序進行閱讀。
編譯器可以將我們在代碼編輯器中創建的文本轉換為目標文件。最初,目標文件被稱為代碼的中間表示形式,因為它用作連接編輯器(即連接器)的輸入,而連接編輯器最終完成整個任務並生成可執行的程序作為輸出。
從代碼到可執行代碼的轉換過程經過了良好的定義並實現了自動化,而目標文件是這個鏈中有機的連接性環節。在這個轉換過程中,目標文件作為連接編輯器所使用的映象,使得它們能夠解析各種符號並將不同的代碼和數據段連接在一起形成統一的整體。
1.1 目標文件的格式
計算機編程領域中存在許多著名的目標文件格式。DOS 系列包括 COM、OBJ 和 EXE 格式。UNIX 和 Linux 使用 a.out、COFF 和 ELF。Microsoft® Windows® 使用可移植的執行文件 (PE) 格式,而 Macintosh 使用 PEF、Mach-O 和其他文件格式。
最初,各種類型的計算機具有自己獨特的目標文件格式,但隨着 UNIX 和其他在不同硬件平台上提供可移植性的操作系統的出現,一些常用的文件格式上升為通用的標准。其中包括 a.out、COFF 和 ELF 格式。
要了解目標文件,需要一組可以讀取目標文件中不同部分並以更易於讀取的格式顯示這些內容的工具。
1.2 UNIX 目標文件
寫一個簡單的程序:hello.c
C 編譯器的正常輸出是用於所指定的目標處理器的匯編代碼。匯編代碼是匯編器的輸入,在缺省情況下,匯編器將生成所有目標文件的祖先,即 a.out 文件。這個名稱本身表示匯編輸出 (Assembler Output)。要創建 a.out 文件,可以在 shell 窗口中輸入下面的命令:gcc hello.c
最新的 C 編譯器將編譯和匯編步驟組合成一個步驟。我們可以指定不同開關選項以查看 C 編譯器的匯編輸出。通過輸入下面的命令,我們可以看到 C 編譯器的匯編輸出:gcc -S hello.c
在當前目錄下會生成 hello.s 文件,即為匯編輸入文本。
-
接下來研究目標文件,其中使用的有價值的工具有:
- nm:列出目標文件中的符號。
- objdump:顯示目標文件中的詳細信息。
- readelf:顯示關於 ELF 目標文件的信息。
1.2.1 nm:列出目標文件中的符號
執行命令:nm a.out
這些包含可執行代碼的段稱為正文段。同樣地,數據段包含了不可執行的信息或數據。另一種類型的段,稱為 BSS 段,它包含以符號數據開頭的塊。
對於 nm 命令列出的每個符號,它們的值使用十六進制來表示(缺省行為),並且在該符號前面加上了一個表示符號類型的編碼字符。
-
常見的各種編碼包括:
- A 表示絕對 (absolute),這意味着不能將該值更改為其他的連接;
- B 表示 BSS 段中的符號;
- C 表示引用未初始化的數據的一般符號。
可以將目標文件中所包含的不同的部分划分為段。段可以包含可執行代碼、符號名稱、初始數據值和許多其他類型的數據。
1.2.2 objdump:顯示目標文件中的詳細信息
通過輸入下面的命令,可以看到目標文件中包含可執行代碼的每個段的匯編清單。
objdump -d a.out
命令生成的代碼如下所示:

1 a.out: file format elf64-x86-64 2 3 4 Disassembly of section .init: 5 6 00000000004003c8 <_init>: 7 4003c8: 48 83 ec 08 sub $0x8,%rsp 8 4003cc: 48 8b 05 25 0c 20 00 mov 0x200c25(%rip),%rax # 600ff8 <_DYNAMIC+0x1d0> 9 4003d3: 48 85 c0 test %rax,%rax 10 4003d6: 74 05 je 4003dd <_init+0x15> 11 4003d8: e8 43 00 00 00 callq 400420 <__libc_start_main@plt+0x10> 12 4003dd: 48 83 c4 08 add $0x8,%rsp 13 4003e1: c3 retq 14 15 Disassembly of section .plt: 16 17 00000000004003f0 <puts@plt-0x10>: 18 4003f0: ff 35 12 0c 20 00 pushq 0x200c12(%rip) # 601008 <_GLOBAL_OFFSET_TABLE_+0x8> 19 4003f6: ff 25 14 0c 20 00 jmpq *0x200c14(%rip) # 601010 <_GLOBAL_OFFSET_TABLE_+0x10> 20 4003fc: 0f 1f 40 00 nopl 0x0(%rax) 21 22 0000000000400400 <puts@plt>: 23 400400: ff 25 12 0c 20 00 jmpq *0x200c12(%rip) # 601018 <_GLOBAL_OFFSET_TABLE_+0x18> 24 400406: 68 00 00 00 00 pushq $0x0 25 40040b: e9 e0 ff ff ff jmpq 4003f0 <_init+0x28> 26 27 0000000000400410 <__libc_start_main@plt>: 28 400410: ff 25 0a 0c 20 00 jmpq *0x200c0a(%rip) # 601020 <_GLOBAL_OFFSET_TABLE_+0x20> 29 400416: 68 01 00 00 00 pushq $0x1 30 40041b: e9 d0 ff ff ff jmpq 4003f0 <_init+0x28> 31 32 Disassembly of section .plt.got: 33 34 0000000000400420 <.plt.got>: 35 400420: ff 25 d2 0b 20 00 jmpq *0x200bd2(%rip) # 600ff8 <_DYNAMIC+0x1d0> 36 400426: 66 90 xchg %ax,%ax 37 38 Disassembly of section .text: 39 40 0000000000400430 <_start>: 41 400430: 31 ed xor %ebp,%ebp 42 400432: 49 89 d1 mov %rdx,%r9 43 400435: 5e pop %rsi 44 400436: 48 89 e2 mov %rsp,%rdx 45 400439: 48 83 e4 f0 and $0xfffffffffffffff0,%rsp 46 40043d: 50 push %rax 47 40043e: 54 push %rsp 48 40043f: 49 c7 c0 c0 05 40 00 mov $0x4005c0,%r8 49 400446: 48 c7 c1 50 05 40 00 mov $0x400550,%rcx 50 40044d: 48 c7 c7 26 05 40 00 mov $0x400526,%rdi 51 400454: e8 b7 ff ff ff callq 400410 <__libc_start_main@plt> 52 400459: f4 hlt 53 40045a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) 54 55 0000000000400460 <deregister_tm_clones>: 56 400460: b8 3f 10 60 00 mov $0x60103f,%eax 57 400465: 55 push %rbp 58 400466: 48 2d 38 10 60 00 sub $0x601038,%rax 59 40046c: 48 83 f8 0e cmp $0xe,%rax 60 400470: 48 89 e5 mov %rsp,%rbp 61 400473: 76 1b jbe 400490 <deregister_tm_clones+0x30> 62 400475: b8 00 00 00 00 mov $0x0,%eax 63 40047a: 48 85 c0 test %rax,%rax 64 40047d: 74 11 je 400490 <deregister_tm_clones+0x30> 65 40047f: 5d pop %rbp 66 400480: bf 38 10 60 00 mov $0x601038,%edi 67 400485: ff e0 jmpq *%rax 68 400487: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1) 69 40048e: 00 00 70 400490: 5d pop %rbp 71 400491: c3 retq 72 400492: 0f 1f 40 00 nopl 0x0(%rax) 73 400496: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1) 74 40049d: 00 00 00 75 76 00000000004004a0 <register_tm_clones>: 77 4004a0: be 38 10 60 00 mov $0x601038,%esi 78 4004a5: 55 push %rbp 79 4004a6: 48 81 ee 38 10 60 00 sub $0x601038,%rsi 80 4004ad: 48 c1 fe 03 sar $0x3,%rsi 81 4004b1: 48 89 e5 mov %rsp,%rbp 82 4004b4: 48 89 f0 mov %rsi,%rax 83 4004b7: 48 c1 e8 3f shr $0x3f,%rax 84 4004bb: 48 01 c6 add %rax,%rsi 85 4004be: 48 d1 fe sar %rsi 86 4004c1: 74 15 je 4004d8 <register_tm_clones+0x38> 87 4004c3: b8 00 00 00 00 mov $0x0,%eax 88 4004c8: 48 85 c0 test %rax,%rax 89 4004cb: 74 0b je 4004d8 <register_tm_clones+0x38> 90 4004cd: 5d pop %rbp 91 4004ce: bf 38 10 60 00 mov $0x601038,%edi 92 4004d3: ff e0 jmpq *%rax 93 4004d5: 0f 1f 00 nopl (%rax) 94 4004d8: 5d pop %rbp 95 4004d9: c3 retq 96 4004da: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) 97 98 00000000004004e0 <__do_global_dtors_aux>: 99 4004e0: 80 3d 51 0b 20 00 00 cmpb $0x0,0x200b51(%rip) # 601038 <__TMC_END__> 100 4004e7: 75 11 jne 4004fa <__do_global_dtors_aux+0x1a> 101 4004e9: 55 push %rbp 102 4004ea: 48 89 e5 mov %rsp,%rbp 103 4004ed: e8 6e ff ff ff callq 400460 <deregister_tm_clones> 104 4004f2: 5d pop %rbp 105 4004f3: c6 05 3e 0b 20 00 01 movb $0x1,0x200b3e(%rip) # 601038 <__TMC_END__> 106 4004fa: f3 c3 repz retq 107 4004fc: 0f 1f 40 00 nopl 0x0(%rax) 108 109 0000000000400500 <frame_dummy>: 110 400500: bf 20 0e 60 00 mov $0x600e20,%edi 111 400505: 48 83 3f 00 cmpq $0x0,(%rdi) 112 400509: 75 05 jne 400510 <frame_dummy+0x10> 113 40050b: eb 93 jmp 4004a0 <register_tm_clones> 114 40050d: 0f 1f 00 nopl (%rax) 115 400510: b8 00 00 00 00 mov $0x0,%eax 116 400515: 48 85 c0 test %rax,%rax 117 400518: 74 f1 je 40050b <frame_dummy+0xb> 118 40051a: 55 push %rbp 119 40051b: 48 89 e5 mov %rsp,%rbp 120 40051e: ff d0 callq *%rax 121 400520: 5d pop %rbp 122 400521: e9 7a ff ff ff jmpq 4004a0 <register_tm_clones> 123 124 0000000000400526 <main>: 125 400526: 55 push %rbp 126 400527: 48 89 e5 mov %rsp,%rbp 127 40052a: 48 83 ec 10 sub $0x10,%rsp 128 40052e: 89 7d fc mov %edi,-0x4(%rbp) 129 400531: 48 89 75 f0 mov %rsi,-0x10(%rbp) 130 400535: bf d4 05 40 00 mov $0x4005d4,%edi 131 40053a: e8 c1 fe ff ff callq 400400 <puts@plt> 132 40053f: b8 00 00 00 00 mov $0x0,%eax 133 400544: c9 leaveq 134 400545: c3 retq 135 400546: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1) 136 40054d: 00 00 00 137 138 0000000000400550 <__libc_csu_init>: 139 400550: 41 57 push %r15 140 400552: 41 56 push %r14 141 400554: 41 89 ff mov %edi,%r15d 142 400557: 41 55 push %r13 143 400559: 41 54 push %r12 144 40055b: 4c 8d 25 ae 08 20 00 lea 0x2008ae(%rip),%r12 # 600e10 <__frame_dummy_init_array_entry> 145 400562: 55 push %rbp 146 400563: 48 8d 2d ae 08 20 00 lea 0x2008ae(%rip),%rbp # 600e18 <__init_array_end> 147 40056a: 53 push %rbx 148 40056b: 49 89 f6 mov %rsi,%r14 149 40056e: 49 89 d5 mov %rdx,%r13 150 400571: 4c 29 e5 sub %r12,%rbp 151 400574: 48 83 ec 08 sub $0x8,%rsp 152 400578: 48 c1 fd 03 sar $0x3,%rbp 153 40057c: e8 47 fe ff ff callq 4003c8 <_init> 154 400581: 48 85 ed test %rbp,%rbp 155 400584: 74 20 je 4005a6 <__libc_csu_init+0x56> 156 400586: 31 db xor %ebx,%ebx 157 400588: 0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1) 158 40058f: 00 159 400590: 4c 89 ea mov %r13,%rdx 160 400593: 4c 89 f6 mov %r14,%rsi 161 400596: 44 89 ff mov %r15d,%edi 162 400599: 41 ff 14 dc callq *(%r12,%rbx,8) 163 40059d: 48 83 c3 01 add $0x1,%rbx 164 4005a1: 48 39 eb cmp %rbp,%rbx 165 4005a4: 75 ea jne 400590 <__libc_csu_init+0x40> 166 4005a6: 48 83 c4 08 add $0x8,%rsp 167 4005aa: 5b pop %rbx 168 4005ab: 5d pop %rbp 169 4005ac: 41 5c pop %r12 170 4005ae: 41 5d pop %r13 171 4005b0: 41 5e pop %r14 172 4005b2: 41 5f pop %r15 173 4005b4: c3 retq 174 4005b5: 90 nop 175 4005b6: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1) 176 4005bd: 00 00 00 177 178 00000000004005c0 <__libc_csu_fini>: 179 4005c0: f3 c3 repz retq 180 181 Disassembly of section .fini: 182 183 00000000004005c4 <_fini>: 184 4005c4: 48 83 ec 08 sub $0x8,%rsp 185 4005c8: 48 83 c4 08 add $0x8,%rsp 186 4005cc: c3 retq
每個可執行代碼段將在需要特定的事件時執行,這些事件包括庫的初始化和該程序本身主入口點。
對於着迷於底層編程細節的程序員來說,這是一個功能非常強大的工具,可用於研究編譯器和匯編器的輸出。細節信息,比如這段代碼中所顯示的這些信息,可以揭示有關本地處理器本身運行方式的很多內容。對該處理器制造商提供的技術文檔進行深入的研究,我們可以收集關於一些有價值的信息,通過這些信息可以深入地了解內部的運行機制,因為功能程序提供了清晰的輸出。
1.2.3 readelf:顯示關於 ELF 目標文件的信息
readelf 程序也可以清楚地列出目標文件中的內容。輸入下面的命令,可以看到這一點:
readelf -all a.out
輸出如下:

1 ELF Header: 2 Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 3 Class: ELF64 4 Data: 2's complement, little endian 5 Version: 1 (current) 6 OS/ABI: UNIX - System V 7 ABI Version: 0 8 Type: EXEC (Executable file) 9 Machine: Advanced Micro Devices X86-64 10 Version: 0x1 11 Entry point address: 0x400430 12 Start of program headers: 64 (bytes into file) 13 Start of section headers: 6616 (bytes into file) 14 Flags: 0x0 15 Size of this header: 64 (bytes) 16 Size of program headers: 56 (bytes) 17 Number of program headers: 9 18 Size of section headers: 64 (bytes) 19 Number of section headers: 31 20 Section header string table index: 28 21 22 Section Headers: 23 [Nr] Name Type Address Offset 24 Size EntSize Flags Link Info Align 25 [ 0] NULL 0000000000000000 00000000 26 0000000000000000 0000000000000000 0 0 0 27 [ 1] .interp PROGBITS 0000000000400238 00000238 28 000000000000001c 0000000000000000 A 0 0 1 29 [ 2] .note.ABI-tag NOTE 0000000000400254 00000254 30 0000000000000020 0000000000000000 A 0 0 4 31 [ 3] .note.gnu.build-i NOTE 0000000000400274 00000274 32 0000000000000024 0000000000000000 A 0 0 4 33 [ 4] .gnu.hash GNU_HASH 0000000000400298 00000298 34 000000000000001c 0000000000000000 A 5 0 8 35 [ 5] .dynsym DYNSYM 00000000004002b8 000002b8 36 0000000000000060 0000000000000018 A 6 1 8 37 [ 6] .dynstr STRTAB 0000000000400318 00000318 38 000000000000003d 0000000000000000 A 0 0 1 39 [ 7] .gnu.version VERSYM 0000000000400356 00000356 40 0000000000000008 0000000000000002 A 5 0 2 41 [ 8] .gnu.version_r VERNEED 0000000000400360 00000360 42 0000000000000020 0000000000000000 A 6 1 8 43 [ 9] .rela.dyn RELA 0000000000400380 00000380 44 0000000000000018 0000000000000018 A 5 0 8 45 [10] .rela.plt RELA 0000000000400398 00000398 46 0000000000000030 0000000000000018 AI 5 24 8 47 [11] .init PROGBITS 00000000004003c8 000003c8 48 000000000000001a 0000000000000000 AX 0 0 4 49 [12] .plt PROGBITS 00000000004003f0 000003f0 50 0000000000000030 0000000000000010 AX 0 0 16 51 [13] .plt.got PROGBITS 0000000000400420 00000420 52 0000000000000008 0000000000000000 AX 0 0 8 53 [14] .text PROGBITS 0000000000400430 00000430 54 0000000000000192 0000000000000000 AX 0 0 16 55 [15] .fini PROGBITS 00000000004005c4 000005c4 56 0000000000000009 0000000000000000 AX 0 0 4 57 [16] .rodata PROGBITS 00000000004005d0 000005d0 58 0000000000000011 0000000000000000 A 0 0 4 59 [17] .eh_frame_hdr PROGBITS 00000000004005e4 000005e4 60 0000000000000034 0000000000000000 A 0 0 4 61 [18] .eh_frame PROGBITS 0000000000400618 00000618 62 00000000000000f4 0000000000000000 A 0 0 8 63 [19] .init_array INIT_ARRAY 0000000000600e10 00000e10 64 0000000000000008 0000000000000000 WA 0 0 8 65 [20] .fini_array FINI_ARRAY 0000000000600e18 00000e18 66 0000000000000008 0000000000000000 WA 0 0 8 67 [21] .jcr PROGBITS 0000000000600e20 00000e20 68 0000000000000008 0000000000000000 WA 0 0 8 69 [22] .dynamic DYNAMIC 0000000000600e28 00000e28 70 00000000000001d0 0000000000000010 WA 6 0 8 71 [23] .got PROGBITS 0000000000600ff8 00000ff8 72 0000000000000008 0000000000000008 WA 0 0 8 73 [24] .got.plt PROGBITS 0000000000601000 00001000 74 0000000000000028 0000000000000008 WA 0 0 8 75 [25] .data PROGBITS 0000000000601028 00001028 76 0000000000000010 0000000000000000 WA 0 0 8 77 [26] .bss NOBITS 0000000000601038 00001038 78 0000000000000008 0000000000000000 WA 0 0 1 79 [27] .comment PROGBITS 0000000000000000 00001038 80 0000000000000035 0000000000000001 MS 0 0 1 81 [28] .shstrtab STRTAB 0000000000000000 000018cc 82 000000000000010c 0000000000000000 0 0 1 83 [29] .symtab SYMTAB 0000000000000000 00001070 84 0000000000000648 0000000000000018 30 47 8 85 [30] .strtab STRTAB 0000000000000000 000016b8 86 0000000000000214 0000000000000000 0 0 1 87 Key to Flags: 88 W (write), A (alloc), X (execute), M (merge), S (strings), l (large) 89 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown) 90 O (extra OS processing required) o (OS specific), p (processor specific) 91 92 There are no section groups in this file. 93 94 Program Headers: 95 Type Offset VirtAddr PhysAddr 96 FileSiz MemSiz Flags Align 97 PHDR 0x0000000000000040 0x0000000000400040 0x0000000000400040 98 0x00000000000001f8 0x00000000000001f8 R E 8 99 INTERP 0x0000000000000238 0x0000000000400238 0x0000000000400238 100 0x000000000000001c 0x000000000000001c R 1 101 [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2] 102 LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000 103 0x000000000000070c 0x000000000000070c R E 200000 104 LOAD 0x0000000000000e10 0x0000000000600e10 0x0000000000600e10 105 0x0000000000000228 0x0000000000000230 RW 200000 106 DYNAMIC 0x0000000000000e28 0x0000000000600e28 0x0000000000600e28 107 0x00000000000001d0 0x00000000000001d0 RW 8 108 NOTE 0x0000000000000254 0x0000000000400254 0x0000000000400254 109 0x0000000000000044 0x0000000000000044 R 4 110 GNU_EH_FRAME 0x00000000000005e4 0x00000000004005e4 0x00000000004005e4 111 0x0000000000000034 0x0000000000000034 R 4 112 GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000 113 0x0000000000000000 0x0000000000000000 RW 10 114 GNU_RELRO 0x0000000000000e10 0x0000000000600e10 0x0000000000600e10 115 0x00000000000001f0 0x00000000000001f0 R 1 116 117 Section to Segment mapping: 118 Segment Sections... 119 00 120 01 .interp 121 02 .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .plt.got .text .fini .rodata .eh_frame_hdr .eh_frame 122 03 .init_array .fini_array .jcr .dynamic .got .got.plt .data .bss 123 04 .dynamic 124 05 .note.ABI-tag .note.gnu.build-id 125 06 .eh_frame_hdr 126 07 127 08 .init_array .fini_array .jcr .dynamic .got 128 129 Dynamic section at offset 0xe28 contains 24 entries: 130 Tag Type Name/Value 131 0x0000000000000001 (NEEDED) Shared library: [libc.so.6] 132 0x000000000000000c (INIT) 0x4003c8 133 0x000000000000000d (FINI) 0x4005c4 134 0x0000000000000019 (INIT_ARRAY) 0x600e10 135 0x000000000000001b (INIT_ARRAYSZ) 8 (bytes) 136 0x000000000000001a (FINI_ARRAY) 0x600e18 137 0x000000000000001c (FINI_ARRAYSZ) 8 (bytes) 138 0x000000006ffffef5 (GNU_HASH) 0x400298 139 0x0000000000000005 (STRTAB) 0x400318 140 0x0000000000000006 (SYMTAB) 0x4002b8 141 0x000000000000000a (STRSZ) 61 (bytes) 142 0x000000000000000b (SYMENT) 24 (bytes) 143 0x0000000000000015 (DEBUG) 0x0 144 0x0000000000000003 (PLTGOT) 0x601000 145 0x0000000000000002 (PLTRELSZ) 48 (bytes) 146 0x0000000000000014 (PLTREL) RELA 147 0x0000000000000017 (JMPREL) 0x400398 148 0x0000000000000007 (RELA) 0x400380 149 0x0000000000000008 (RELASZ) 24 (bytes) 150 0x0000000000000009 (RELAENT) 24 (bytes) 151 0x000000006ffffffe (VERNEED) 0x400360 152 0x000000006fffffff (VERNEEDNUM) 1 153 0x000000006ffffff0 (VERSYM) 0x400356 154 0x0000000000000000 (NULL) 0x0 155 156 Relocation section '.rela.dyn' at offset 0x380 contains 1 entries: 157 Offset Info Type Sym. Value Sym. Name + Addend 158 000000600ff8 000300000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start__ + 0 159 160 Relocation section '.rela.plt' at offset 0x398 contains 2 entries: 161 Offset Info Type Sym. Value Sym. Name + Addend 162 000000601018 000100000007 R_X86_64_JUMP_SLO 0000000000000000 puts@GLIBC_2.2.5 + 0 163 000000601020 000200000007 R_X86_64_JUMP_SLO 0000000000000000 __libc_start_main@GLIBC_2.2.5 + 0 164 165 The decoding of unwind sections for machine type Advanced Micro Devices X86-64 is not currently supported. 166 167 Symbol table '.dynsym' contains 4 entries: 168 Num: Value Size Type Bind Vis Ndx Name 169 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND 170 1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND puts@GLIBC_2.2.5 (2) 171 2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (2) 172 3: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__ 173 174 Symbol table '.symtab' contains 67 entries: 175 Num: Value Size Type Bind Vis Ndx Name 176 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND 177 1: 0000000000400238 0 SECTION LOCAL DEFAULT 1 178 2: 0000000000400254 0 SECTION LOCAL DEFAULT 2 179 3: 0000000000400274 0 SECTION LOCAL DEFAULT 3 180 4: 0000000000400298 0 SECTION LOCAL DEFAULT 4 181 5: 00000000004002b8 0 SECTION LOCAL DEFAULT 5 182 6: 0000000000400318 0 SECTION LOCAL DEFAULT 6 183 7: 0000000000400356 0 SECTION LOCAL DEFAULT 7 184 8: 0000000000400360 0 SECTION LOCAL DEFAULT 8 185 9: 0000000000400380 0 SECTION LOCAL DEFAULT 9 186 10: 0000000000400398 0 SECTION LOCAL DEFAULT 10 187 11: 00000000004003c8 0 SECTION LOCAL DEFAULT 11 188 12: 00000000004003f0 0 SECTION LOCAL DEFAULT 12 189 13: 0000000000400420 0 SECTION LOCAL DEFAULT 13 190 14: 0000000000400430 0 SECTION LOCAL DEFAULT 14 191 15: 00000000004005c4 0 SECTION LOCAL DEFAULT 15 192 16: 00000000004005d0 0 SECTION LOCAL DEFAULT 16 193 17: 00000000004005e4 0 SECTION LOCAL DEFAULT 17 194 18: 0000000000400618 0 SECTION LOCAL DEFAULT 18 195 19: 0000000000600e10 0 SECTION LOCAL DEFAULT 19 196 20: 0000000000600e18 0 SECTION LOCAL DEFAULT 20 197 21: 0000000000600e20 0 SECTION LOCAL DEFAULT 21 198 22: 0000000000600e28 0 SECTION LOCAL DEFAULT 22 199 23: 0000000000600ff8 0 SECTION LOCAL DEFAULT 23 200 24: 0000000000601000 0 SECTION LOCAL DEFAULT 24 201 25: 0000000000601028 0 SECTION LOCAL DEFAULT 25 202 26: 0000000000601038 0 SECTION LOCAL DEFAULT 26 203 27: 0000000000000000 0 SECTION LOCAL DEFAULT 27 204 28: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c 205 29: 0000000000600e20 0 OBJECT LOCAL DEFAULT 21 __JCR_LIST__ 206 30: 0000000000400460 0 FUNC LOCAL DEFAULT 14 deregister_tm_clones 207 31: 00000000004004a0 0 FUNC LOCAL DEFAULT 14 register_tm_clones 208 32: 00000000004004e0 0 FUNC LOCAL DEFAULT 14 __do_global_dtors_aux 209 33: 0000000000601038 1 OBJECT LOCAL DEFAULT 26 completed.7594 210 34: 0000000000600e18 0 OBJECT LOCAL DEFAULT 20 __do_global_dtors_aux_fin 211 35: 0000000000400500 0 FUNC LOCAL DEFAULT 14 frame_dummy 212 36: 0000000000600e10 0 OBJECT LOCAL DEFAULT 19 __frame_dummy_init_array_ 213 37: 0000000000000000 0 FILE LOCAL DEFAULT ABS hello.c 214 38: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c 215 39: 0000000000400708 0 OBJECT LOCAL DEFAULT 18 __FRAME_END__ 216 40: 0000000000600e20 0 OBJECT LOCAL DEFAULT 21 __JCR_END__ 217 41: 0000000000000000 0 FILE LOCAL DEFAULT ABS 218 42: 0000000000600e18 0 NOTYPE LOCAL DEFAULT 19 __init_array_end 219 43: 0000000000600e28 0 OBJECT LOCAL DEFAULT 22 _DYNAMIC 220 44: 0000000000600e10 0 NOTYPE LOCAL DEFAULT 19 __init_array_start 221 45: 00000000004005e4 0 NOTYPE LOCAL DEFAULT 17 __GNU_EH_FRAME_HDR 222 46: 0000000000601000 0 OBJECT LOCAL DEFAULT 24 _GLOBAL_OFFSET_TABLE_ 223 47: 00000000004005c0 2 FUNC GLOBAL DEFAULT 14 __libc_csu_fini 224 48: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTab 225 49: 0000000000601028 0 NOTYPE WEAK DEFAULT 25 data_start 226 50: 0000000000000000 0 FUNC GLOBAL DEFAULT UND puts@@GLIBC_2.2.5 227 51: 0000000000601038 0 NOTYPE GLOBAL DEFAULT 25 _edata 228 52: 00000000004005c4 0 FUNC GLOBAL DEFAULT 15 _fini 229 53: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@@GLIBC_ 230 54: 0000000000601028 0 NOTYPE GLOBAL DEFAULT 25 __data_start 231 55: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__ 232 56: 0000000000601030 0 OBJECT GLOBAL HIDDEN 25 __dso_handle 233 57: 00000000004005d0 4 OBJECT GLOBAL DEFAULT 16 _IO_stdin_used 234 58: 0000000000400550 101 FUNC GLOBAL DEFAULT 14 __libc_csu_init 235 59: 0000000000601040 0 NOTYPE GLOBAL DEFAULT 26 _end 236 60: 0000000000400430 42 FUNC GLOBAL DEFAULT 14 _start 237 61: 0000000000601038 0 NOTYPE GLOBAL DEFAULT 26 __bss_start 238 62: 0000000000400526 32 FUNC GLOBAL DEFAULT 14 main 239 63: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses 240 64: 0000000000601038 0 OBJECT GLOBAL HIDDEN 25 __TMC_END__ 241 65: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMCloneTable 242 66: 00000000004003c8 0 FUNC GLOBAL DEFAULT 11 _init 243 244 Version symbols section '.gnu.version' contains 4 entries: 245 Addr: 0000000000400356 Offset: 0x000356 Link: 5 (.dynsym) 246 000: 0 (*local*) 2 (GLIBC_2.2.5) 2 (GLIBC_2.2.5) 0 (*local*) 247 248 Version needs section '.gnu.version_r' contains 1 entries: 249 Addr: 0x0000000000400360 Offset: 0x000360 Link: 6 (.dynstr) 250 000000: Version: 1 File: libc.so.6 Cnt: 1 251 0x0010: Name: GLIBC_2.2.5 Flags: none Version: 2 252 253 Displaying notes found at file offset 0x00000254 with length 0x00000020: 254 Owner Data size Description 255 GNU 0x00000010 NT_GNU_ABI_TAG (ABI version tag) 256 OS: Linux, ABI: 2.6.32 257 258 Displaying notes found at file offset 0x00000274 with length 0x00000024: 259 Owner Data size Description 260 GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring) 261 Build ID: c0f3db4f9706877127ed96aa53ddd338e1632814
ELF Header 為該文件中所有段入口顯示了詳細的摘要。在列舉出這些 Header 中的內容之前,可以看到 Header 的具體數目。在研究一個較大的目標文件時,該信息可能非常有用。
從該輸出中看到的,簡單的 a.out Hello World 文件中包含了大量有價值的細節信息,包括版本信息、柱狀圖、各種符號類型的表格,等等。
除了所有這些段之外,編譯器可以將調試信息放入到目標文件中,並且還可以顯示這些信息。輸入下面的命令,仔細分析編譯器的輸出(假設您扮演了調試程序的角色):readelf --debug-dump a.out | less
1.3 目標文件
在 UNIX 中,可執行文件是目標文件,並且我們可以像對 a.out 文件那樣對它們進行分析。
如果傾向於使用編譯器和其他的語言工具,那么您可以對組成計算機系統的各種目標文件進行仔細研究。UNIX 操作系統具有許多層次,那些通過工具查看目標文件所公開的層次,非常接近底層硬件。通過這種方式,可以真實地接觸到系統。