对PIC(position independent code)的探究

2019-04-15 13:05发布

示例: static int a=2; extern int b; extern void test(); int glo=2; void bar() { a=1; b=2; glo=3; } void foo() { bar(); test(); } 在这个例子中 ,有局部变量a 外部全局变量b 本地全局变量glo 本地全局函数bar() 外部全局函数test()
编译: gcc -m32 -fPIC -c test.c -o test.o 汇编代码 objdump -d test.o: Disassembly of section .text: 00000000 : 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: e8 fc ff ff ff call 4 0x4> 8: 05 01 00 00 00 add $0x1,%eax d: c7 80 00 00 00 00 01 movl $0x1,0x0(%eax) 14: 00 00 00 17: 8b 90 00 00 00 00 mov 0x0(%eax),%edx 1d: c7 02 02 00 00 00 movl $0x2,(%edx) 23: 8b 80 00 00 00 00 mov 0x0(%eax),%eax 29: c7 00 03 00 00 00 movl $0x3,(%eax) 2f: 90 nop 30: 5d pop %ebp 31: c3 ret 00000032 : 32: 55 push %ebp 33: 89 e5 mov %esp,%ebp 35: 53 push %ebx 36: 83 ec 04 sub $0x4,%esp 39: e8 fc ff ff ff call 3a 0x8> 3e: 81 c3 02 00 00 00 add $0x2,%ebx 44: e8 fc ff ff ff call 45 0x13> 49: e8 fc ff ff ff call 4a 0x18> 4e: 90 nop 4f: 83 c4 04 add $0x4,%esp 52: 5b pop %ebx 53: 5d pop %ebp 54: c3 ret Disassembly of section .text.__x86.get_pc_thunk.ax: 00000000 <__x86.get_pc_thunk.ax>: 0: 8b 04 24 mov (%esp),%eax 3: c3 ret Disassembly of section .text.__x86.get_pc_thunk.bx: 00000000 <__x86.get_pc_thunk.bx>: 0: 8b 1c 24 mov (%esp),%ebx 3: c3 ret

elf信息: readelf -a test.o

ELF 头: Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 Class: ELF32 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: REL (可重定位文件) Machine: Intel 80386 Version: 0x1 入口点地址: 0x0 程序头起点: 0 (bytes into file) Start of section headers: 1044 (bytes into file) 标志: 0x0 本头的大小: 52 (字节) 程序头大小: 0 (字节) Number of program headers: 0 节头大小: 40 (字节) 节头数量: 16 字符串表索引节头: 13 节头: [Nr] Name Type Addr Off Size ES Flg Lk Inf Al [ 0] NULL 00000000 000000 000000 00 0 0 0 [ 1] .group GROUP 00000000 000034 000008 04 14 15 4 [ 2] .group GROUP 00000000 00003c 000008 04 14 19 4 [ 3] .text PROGBITS 00000000 000044 000055 00 AX 0 0 1 [ 4] .rel.text REL 00000000 0003ac 000048 08 I 14 3 4 [ 5] .data PROGBITS 00000000 00009c 000008 00 WA 0 0 4 [ 6] .bss NOBITS 00000000 0000a4 000000 00 WA 0 0 1 [ 7] .text.__x86.get_p PROGBITS 00000000 0000a4 000004 00 AXG 0 0 1 [ 8] .text.__x86.get_p PROGBITS 00000000 0000a8 000004 00 AXG 0 0 1 [ 9] .comment PROGBITS 00000000 0000ac 00002e 01 MS 0 0 1 [10] .note.GNU-stack PROGBITS 00000000 0000da 000000 00 0 0 1 [11] .eh_frame PROGBITS 00000000 0000dc 000084 00 A 0 0 4 [12] .rel.eh_frame REL 00000000 0003f4 000020 08 I 14 11 4 [13] .shstrtab STRTAB 00000000 000160 000096 00 0 0 1 [14] .symtab SYMTAB 00000000 0001f8 000150 10 15 13 4 [15] .strtab STRTAB 00000000 000348 000062 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) COMDAT group section [ 1] `.group' [__x86.get_pc_thunk.ax] contains 1 sections: [Index] Name [ 7] .text.__x86.get_pc_thunk.ax COMDAT group section [ 2] `.group' [__x86.get_pc_thunk.bx] contains 1 sections: [Index] Name [ 8] .text.__x86.get_pc_thunk.bx 本文件中没有程序头。 重定位节 '.rel.text' 位于偏移量 0x3ac 含有 9 个条目: Offset Info Type Sym.Value Sym. Name 00000004 00000f02 R_386_PC32 00000000 __x86.get_pc_thunk.ax 00000009 0000100a R_386_GOTPC 00000000 _GLOBAL_OFFSET_TABLE_ 0000000f 00000309 R_386_GOTOFF 00000000 .data 00000019 00001103 R_386_GOT32 00000000 b 00000025 00000d03 R_386_GOT32 00000004 glo 0000003a 00001302 R_386_PC32 00000000 __x86.get_pc_thunk.bx 00000040 0000100a R_386_GOTPC 00000000 _GLOBAL_OFFSET_TABLE_ 00000045 00000e04 R_386_PLT32 00000000 bar 0000004a 00001404 R_386_PLT32 00000000 test 重定位节 '.rel.eh_frame' 位于偏移量 0x3f4 含有 4 个条目: Offset Info Type Sym.Value Sym. Name 00000020 00000202 R_386_PC32 00000000 .text 00000040 00000202 R_386_PC32 00000000 .text 00000064 00000602 R_386_PC32 00000000 .text.__x86.get_pc_thu 00000078 00000702 R_386_PC32 00000000 .text.__x86.get_pc_thu The decoding of unwind sections for machine type Intel 80386 is not currently supported. Symbol table '.symtab' contains 21 entries: Num: Value Size Type Bind Vis Ndx Name 0: 00000000 0 NOTYPE LOCAL DEFAULT UND 1: 00000000 0 FILE LOCAL DEFAULT ABS testpic.c 2: 00000000 0 SECTION LOCAL DEFAULT 3 3: 00000000 0 SECTION LOCAL DEFAULT 5 4: 00000000 0 SECTION LOCAL DEFAULT 6 5: 00000000 4 OBJECT LOCAL DEFAULT 5 a 6: 00000000 0 SECTION LOCAL DEFAULT 7 7: 00000000 0 SECTION LOCAL DEFAULT 8 8: 00000000 0 SECTION LOCAL DEFAULT 10 9: 00000000 0 SECTION LOCAL DEFAULT 11 10: 00000000 0 SECTION LOCAL DEFAULT 9 11: 00000000 0 SECTION LOCAL DEFAULT 1 12: 00000000 0 SECTION LOCAL DEFAULT 2 13: 00000004 4 OBJECT GLOBAL DEFAULT 5 glo 14: 00000000 50 FUNC GLOBAL DEFAULT 3 bar 15: 00000000 0 FUNC GLOBAL HIDDEN 7 __x86.get_pc_thunk.ax 16: 00000000 0 NOTYPE GLOBAL DEFAULT UND _GLOBAL_OFFSET_TABLE_ 17: 00000000 0 NOTYPE GLOBAL DEFAULT UND b 18: 00000032 35 FUNC GLOBAL DEFAULT 3 foo 19: 00000000 0 FUNC GLOBAL HIDDEN 8 __x86.get_pc_thunk.bx 20: 00000000 0 NOTYPE GLOBAL DEFAULT UND test No version information found in this file. R_386_PC32 符号地址+重定位处值-重定位地址
R_386_GOTPC got.plt地址(GOT)+重定位处值-重定位地址 用于确定
R_386_GOTOFF 符号地址-GOT 局部变量位于.data中利用相对GOT的值修改局部变量值 用于全局静态变量
R_386_GOT32 符号地址(在.got中) 全局变量在.got中的偏移 全局变量
R_386_PLT32 函数在.plt地址(bar@plt)+重定位处值-重定位地址 函数