一 概述
二 类型
三 语句
四 函数
五 数据
六 内存
七 代码
附录
文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
5. 目标文件
现在流行的可执行文件(executable)格式基本都是 COFF(common file format)变种,如 Windows/PE、Linux/ELF 等。
$ file ./test ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, with debug_info, not stripped
示例:
#include <stdio.h> int X = 1; int Y; void test() { char *s = "X = %d, Y = %d\n"; printf(s, X, Y); } int main (int argc, char *argv[]) { test(); return 0; }
$ gcc -g -O2 -no-pie -o ./test main.c
$ readelf -h ./test ELF Header: Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class: ELF64 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: EXEC (Executable file) Machine: Advanced Micro Devices X86-64 Version: 0x1 Entry point address: 0x401080 Start of program headers: 64 (bytes into file) Start of section headers: 18040 (bytes into file) Flags: 0x0 Size of this header: 64 (bytes) Size of program headers: 56 (bytes) Number of program headers: 13 Size of section headers: 64 (bytes) Number of section headers: 38 Section header string table index: 37
目标文件由机器代码、数据、符号表、调试信息、字符串等内容组成。信息按不同属性,以段(section)方式分类存储。如果将整个文件看作一个数据库(database),那么每个段就相当于一个数据表(table)。
- .text : 代码段。
- .data : 已初始化的全局变量和静态局部变量(值存储)。
- .bss : 未初始化的全局变量和静态局部变量(分配零值内存,但不占用文件空间)。
- .rodata : 只读数据(比如字符串字面量和 const 修饰的只读变量)。
- .symtab : 符号表(定义和引用的函数、全局变量信息)。
- .debug : 调试信息(-g)。
$ size ./test text data bss dec hex filename 1370 548 12 1930 78a ./test
$ readelf -S ./test There are 38 section headers, starting at offset 0x4678: Section Headers: [Nr] Name Type Address Offset Size EntSize Flags Link Info Align [15] .text PROGBITS 0000000000401050 00001050 00000000000001c5 0000000000000000 AX 0 0 16 [17] .rodata PROGBITS 0000000000402000 00002000 0000000000000014 0000000000000000 A 0 0 4 [25] .data PROGBITS 0000000000404020 00003020 0000000000000014 0000000000000000 WA 0 0 8 [26] .bss NOBITS 0000000000404034 00003034 000000000000000c 0000000000000000 WA 0 0 4 [29] .debug_info PROGBITS 0000000000000000 0000309e 000000000000048d 0000000000000000 0 0 1 [35] .symtab SYMTAB 0000000000000000 00003c48 00000000000006d8 0000000000000018 36 52 8 Key to Flags: W (write), A (alloc), X (execute), M (merge), S (strings), I (info), L (link order), O (extra OS processing required), G (group), T (TLS), C (compressed), x (unknown), o (OS specific), E (exclude), l (large), p (processor specific)
查看符号表:
$ readelf -s ./test Symbol table '.symtab' contains 73 entries: Num: Value Size Type Bind Vis Ndx Name 35: 0000000000000000 0 FILE LOCAL DEFAULT ABS main.c 54: 0000000000404030 4 OBJECT GLOBAL DEFAULT 25 X 63: 0000000000404038 4 OBJECT GLOBAL DEFAULT 26 Y 68: 0000000000401050 46 FUNC GLOBAL DEFAULT 15 main 72: 0000000000401170 35 FUNC GLOBAL DEFAULT 15 test
查看只读数据:
$ readelf -x .rodata ./test Hex dump of section '.rodata': 0x00402000 01000200 58203d20 25642c20 59203d20 ....X = %d, Y = 0x00402010 25640a00 %d..
查看代码:
$ readelf -x .text ./test Hex dump of section '.text': 0x00401050 f30f1efa 4883ec08 8b0dda2f 00008b15 ....H....../.... 0x00401060 cc2f0000 31c0488d 35970f00 00bf0100 ./..1.H.5....... 0x00401070 0000e8c9 ffffff31 c04883c4 08c36690 .......1.H....f. 0x00401080 f30f1efa 31ed4989 d15e4889 e24883e4 ....1.I..^H..H.. 0x00401090 f0505449 c7c01012 400048c7 c1a01140 .PTI....@.H....@ 0x004010a0 0048c7c7 50104000 ff15422f 0000f490 .H..P.@...B/.... $ xxd -s 0x1050 -g 4 -l 100 ./test // section offset 00001050: f30f1efa 4883ec08 8b0dda2f 00008b15 ....H....../.... 00001060: cc2f0000 31c0488d 35970f00 00bf0100 ./..1.H.5....... 00001070: 0000e8c9 ffffff31 c04883c4 08c36690 .......1.H....f. 00001080: f30f1efa 31ed4989 d15e4889 e24883e4 ....1.I..^H..H.. 00001090: f0505449 c7c01012 400048c7 c1a01140 .PTI....@.H....@ 000010a0: 0048c7c7 50104000 ff15422f 0000f490 .H..P.@...B/....
可用 strip 删除符号表和调试段。使用 GNU 扩展
__attribute__((section("NAME"))) int x;
自定义段。或用 objcopy 将数据嵌入到自定义段内。
$ objcopy --add-section .abc=data.txt --set-section-flags .abc=noload,readonly src dst $ objcopy --update-section .abc=data2.txt dst $ objcopy --rename-section .abc=.demo dst $ objcopy --remove-section .demo dst
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论