http://blog.sina.com.cn/s/blog_54f82cc201011orc.html
2f7: e8 00 00 00 00 call 2fc <ok+0xc> 2fc: 5b pop �x 2fd: 81 c3 b0 10 00 00 add $0x10b0,�x |
这里的2f7中的call 2fc <ok+0xc>和2fc处的pop�x,得到运行时的eip地址,存入ebx寄存器中。
后面的add$0x10b0,�x又是什么用处?如果我们这里假定在内存中的地址是2fc,那加上10b0之后的值是0x13ac了,看在这里是什么呢?
Disassembly of section .got: 000013ac <.got>: 13ac: 34 13 xor $0x13,%al ... |
-------------------------
一个例子
对于加了-fPIC选项的共享库,如:gcc-shared -fPIC -o libhello.so hello.c,// hello.c #include <stdio.h> #include <stdlib.h> int count; char ch; struct _s { int s1; int s2; } s; void say_hello() { printf("Hello:%x\n", ++count); printf("Hello:%x\n", ++ch); printf("Hello:%x\n", ++s.s1); printf("Hello:%x\n", ++s.s2); }
jfo@lab:~/test$ gcc -ggdb -shared -fPIC -o libhello.so hello.c jfo@lab:~/test$ readelf -x.got libhello.so Hex dump of section '.got': 0x000016a0 00000000 00000000 00000000 00000000 ................ 0x000016b0 00000000 00000000 ........ jfo@lab:~/test$ readelf -x.got.plt libhello.so Hex dump of section '.got.plt': 0x000016b8 d8150000 00000000 00000000 9e030000 ................ 0x000016c8 ae030000 be030000 ........ jfo@lab:~/test$ objdump -S -j.plt libhello.so libhello.so: file format elf32-i386 Disassembly of section .plt: 00000388 <__gmon_start__@plt-0x10>: 388: ff b3 04 00 00 00 pushl 0x4(�x) 38e: ff a3 08 00 00 00 jmp *0x8(�x) 394: 00 00 add %al,(�x) ... 00000398 <__gmon_start__@plt>: 398: ff a3 0c 00 00 00 jmp *0xc(�x) 39e: 68 00 00 00 00 push $0x0 3a3: e9 e0 ff ff ff jmp 388 <_init+0x30> 000003a8 <printf@plt>: 3a8: ff a3 10 00 00 00 jmp *0x10(�x) 3ae: 68 08 00 00 00 push $0x8 3b3: e9 d0 ff ff ff jmp 388 <_init+0x30> 000003b8 <__cxa_finalize@plt>: 3b8: ff a3 14 00 00 00 jmp *0x14(�x) 3be: 68 10 00 00 00 push $0x10 3c3: e9 c0 ff ff ff jmp 388 <_init+0x30> jfo@lab:~/test$ objdump -S -j.text libhello.so ... void say_hello() { 48c: 55 push �p 48d: 89 e5 mov %esp,�p 48f: 53 push �x 490: 83 ec 14 sub $0x14,%esp 493: e8 ef ff ff ff call 487 <__i686.get_pc_thunk.bx> 498: 81 c3 20 12 00 00 add $0x1220,�x printf("Hello:%x\n", ++count); 49e: 8b 83 f8 ff ff ff mov -0x8(�x),�x 4a4: 8b 00 mov (�x),�x 4a6: 8d 50 01 lea 0x1(�x),�x 4a9: 8b 83 f8 ff ff ff mov -0x8(�x),�x 4af: 89 10 mov �x,(�x) 4b1: 8b 83 f8 ff ff ff mov -0x8(�x),�x 4b7: 8b 00 mov (�x),�x 4b9: 89 44 24 04 mov �x,0x4(%esp) 4bd: 8d 83 fc ee ff ff lea -0x1104(�x),�x 4c3: 89 04 24 mov �x,(%esp) 4c6: e8 dd fe ff ff call 3a8 <printf@plt> printf("Hello:%x\n", ++ch); 4cb: 8b 83 f4 ff ff ff mov -0xc(�x),�x 4d1: 0f b6 00 movzbl (�x),�x 4d4: 8d 50 01 lea 0x1(�x),�x 4d7: 8b 83 f4 ff ff ff mov -0xc(�x),�x 4dd: 88 10 mov %dl,(�x) 4df: 8b 83 f4 ff ff ff mov -0xc(�x),�x 4e5: 0f b6 00 movzbl (�x),�x 4e8: 0f be c0 movsbl %al,�x 4eb: 89 44 24 04 mov �x,0x4(%esp) 4ef: 8d 83 fc ee ff ff lea -0x1104(�x),�x 4f5: 89 04 24 mov �x,(%esp) 4f8: e8 ab fe ff ff call 3a8 <printf@plt> printf("Hello:%x\n", ++s.s1); 4fd: 8b 83 e8 ff ff ff mov -0x18(�x),�x 503: 8b 00 mov (�x),�x 505: 8d 50 01 lea 0x1(�x),�x 508: 8b 83 e8 ff ff ff mov -0x18(�x),�x 50e: 89 10 mov �x,(�x) 510: 8b 83 e8 ff ff ff mov -0x18(�x),�x 516: 8b 00 mov (�x),�x 518: 89 44 24 04 mov �x,0x4(%esp) 51c: 8d 83 fc ee ff ff lea -0x1104(�x),�x 522: 89 04 24 mov �x,(%esp) 525: e8 7e fe ff ff call 3a8 <printf@plt> printf("Hello:%x\n", ++s.s2); 52a: 8b 83 e8 ff ff ff mov -0x18(�x),�x 530: 8b 40 04 mov 0x4(�x),�x 533: 8d 50 01 lea 0x1(�x),�x 536: 8b 83 e8 ff ff ff mov -0x18(�x),�x 53c: 89 50 04 mov �x,0x4(�x) 53f: 8b 83 e8 ff ff ff mov -0x18(�x),�x 545: 8b 40 04 mov 0x4(�x),�x 548: 89 44 24 04 mov �x,0x4(%esp) 54c: 8d 83 fc ee ff ff lea -0x1104(�x),�x 552: 89 04 24 mov �x,(%esp) 555: e8 4e fe ff ff call 3a8 <printf@plt> } ... jfo@lab:~/test$ readelf -a libhello.so ... Relocation section '.rel.dyn' at offset 0x308 contains 7 entries: Offset Info Type Sym.Value Sym. Name 000016d0 00000008 R_386_RELATIVE 000016a0 00000806 R_386_GLOB_DAT 000016dc s //offset -0x18(ebx) 000016a4 00000106 R_386_GLOB_DAT 00000000 __gmon_start__ //offset -0x14(ebx) 000016a8 00000206 R_386_GLOB_DAT 00000000 _Jv_RegisterClasses //offset -0x10(ebx) 000016ac 00000d06 R_386_GLOB_DAT 000016e4 ch //offset -0xc(ebx) 000016b0 00000906 R_386_GLOB_DAT 000016e8 count //offset -0x8(ebx) 000016b4 00000406 R_386_GLOB_DAT 00000000 __cxa_finalize //offset -0x4(ebx) //Offset000016a0、000016ac、000016b0位于.got section //Sym.Value000016dc、000016e4、000016e8对应.bss段变量的地址 Relocation section '.rel.plt' at offset 0x340 contains 3 entries: Offset Info Type Sym.Value Sym. Name 000016c4 00000107 R_386_JUMP_SLOT 00000000 __gmon_start__ //offset 0xc(ebx) 000016c8 00000307 R_386_JUMP_SLOT 00000000 printf //offset 0x10(ebx) 000016cc 00000407 R_386_JUMP_SLOT 00000000 __cxa_finalize //offset 0x14(ebx) //Offset000016c4、000016c8、000016cc位于.got.plt section There are no unwind sections in this file. Symbol table '.dynsym' contains 14 entries: Num: Value Size Type Bind Vis Ndx Name 0: 00000000 0 NOTYPE LOCAL DEFAULT UND 1: 00000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__ 2: 00000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses 3: 00000000 54 FUNC GLOBAL DEFAULT UND printf@GLIBC_2.0 (2) 4: 00000000 267 FUNC WEAK DEFAULT UND __cxa_finalize@GLIBC_2.1.3 (3) 5: 0000048c 212 FUNC GLOBAL DEFAULT 11 say_hello 6: 000016ec 0 NOTYPE GLOBAL DEFAULT ABS _end 7: 000016d4 0 NOTYPE GLOBAL DEFAULT ABS _edata 8: 000016dc 8 OBJECT GLOBAL DEFAULT 22 s 9: 000016e8 4 OBJECT GLOBAL DEFAULT 22 count 10: 000016d4 0 NOTYPE GLOBAL DEFAULT ABS __bss_start 11: 00000358 0 FUNC GLOBAL DEFAULT 9 _init 12: 00000598 0 FUNC GLOBAL DEFAULT 12 _fini 13: 000016e4 1 OBJECT GLOBAL DEFAULT 22 ch Section Headers: [Nr] Name Type Addr Off Size ES Flg Lk Inf Al [ 0] NULL 00000000 000000 000000 00 0 0 0 [ 1] .hash HASH 000000b4 0000b4 00004c 04 A 3 0 4 [ 2] .gnu.hash GNU_HASH 00000100 000100 000048 04 A 3 0 4 [ 3] .dynsym DYNSYM 00000148 000148 0000e0 10 A 4 1 4 [ 4] .dynstr STRTAB 00000228 000228 000091 00 A 0 0 1 [ 5] .gnu.version VERSYM 000002ba 0002ba 00001c 02 A 3 0 2 [ 6] .gnu.version_r VERNEED 000002d8 0002d8 000030 00 A 4 1 4 [ 7] .rel.dyn REL 00000308 000308 000038 08 A 3 0 4 [ 8] .rel.plt REL 00000340 000340 000018 08 A 3 10 4 [ 9] .init PROGBITS 00000358 000358 000030 00 AX 0 0 4 [10] .plt PROGBITS 00000388 000388 000040 04 AX 0 0 4 [11] .text PROGBITS 000003d0 0003d0 0001c8 00 AX 0 0 16 [12] .fini PROGBITS 00000598 000598 00001c 00 AX 0 0 4 [13] .rodata PROGBITS 000005b4 0005b4 00000a 00 A 0 0 1 [14] .eh_frame PROGBITS 000005c0 0005c0 000004 00 A 0 0 4 [15] .ctors PROGBITS 000015c4 0005c4 000008 00 WA 0 0 4 [16] .dtors PROGBITS 000015cc 0005cc 000008 00 WA 0 0 4 [17] .jcr PROGBITS 000015d4 0005d4 000004 00 WA 0 0 4 [18] .dynamic DYNAMIC 000015d8 0005d8 0000c8 08 WA 4 0 4 [19] .got PROGBITS 000016a0 0006a0 000018 04 WA 0 0 4 [20] .got.plt PROGBITS 000016b8 0006b8 000018 04 WA 0 0 4 [21] .data PROGBITS 000016d0 0006d0 000004 00 WA 0 0 4 [22] .bss NOBITS 000016d4 0006d4 000018 00 WA 0 0 4 [23] .comment PROGBITS 00000000 0006d4 00005a 00 0 0 1 [24] .debug_aranges PROGBITS 00000000 000730 000070 00 0 0 8 [25] .debug_pubnames PROGBITS 00000000 0007a0 000037 00 0 0 1 [26] .debug_info PROGBITS 00000000 0007d7 0001a8 00 0 0 1 [27] .debug_abbrev PROGBITS 00000000 00097f 0000aa 00 0 0 1 [28] .debug_line PROGBITS 00000000 000a29 00013c 00 0 0 1 [29] .debug_frame PROGBITS 00000000 000b68 000030 00 0 0 4 [30] .debug_str PROGBITS 00000000 000b98 000083 01 MS 0 0 1 [31] .debug_loc PROGBITS 00000000 000c1b 00002c 00 0 0 1 [32] .debug_ranges PROGBITS 00000000 000c48 000040 00 0 0 8 [33] .shstrtab STRTAB 00000000 000c88 00013b 00 0 0 1 [34] .symtab SYMTAB 00000000 001364 000430 10 35 54 4 [35] .strtab STRTAB 00000000 001794 00019e 00 0 0 1
// test.c
#include <stdio.h>
#include <stdlib.h>
extern int count;
int main()
{
say_hello();
printf("count is %x\n", count);
return 0;
}
jfo@lab:~/test$ gcc -ggdb -o test test.c -L. -lhello -Wl,-rpath,. jfo@lab:~/test$ objdump -S test ... int main() { 80484e4: 8d 4c 24 04 lea 0x4(%esp),�x 80484e8: 83 e4 f0 and $0xfffffff0,%esp 80484eb: ff 71 fc pushl -0x4(�x) 80484ee: 55 push �p 80484ef: 89 e5 mov %esp,�p 80484f1: 51 push �x 80484f2: 83 ec 14 sub $0x14,%esp say_hello(); 80484f5: e8 02 ff ff ff call 80483fc <say_hello@plt> printf("count is %x\n", count); 80484fa: a1 08 97 04 08 mov 0x8049708,�x //变量cout的地址固定!!! 80484ff: 89 44 24 04 mov �x,0x4(%esp) 8048503: c7 04 24 e0 85 04 08 movl $0x80485e0,(%esp) 804850a: e8 0d ff ff ff call 804841c <printf@plt> return 0; 804850f: b8 00 00 00 00 mov $0x0,�x } 8048514: 83 c4 14 add $0x14,%esp 8048517: 59 pop �x 8048518: 5d pop �p 8048519: 8d 61 fc lea -0x4(�x),%esp 804851c: c3 ret 804851d: 90 nop 804851e: 90 nop 804851f: 90 nop ... jfo@lab:~/test$ readelf -a test ... Relocation section '.rel.dyn' at offset 0x37c contains 2 entries: Offset Info Type Sym.Value Sym. Name 080496e0 00000106 R_386_GLOB_DAT 00000000 __gmon_start__ 08049708 00000905 R_386_COPY 08049708 count Relocation section '.rel.plt' at offset 0x38c contains 4 entries: Offset Info Type Sym.Value Sym. Name 080496f0 00000107 R_386_JUMP_SLOT 00000000 __gmon_start__ 080496f4 00000307 R_386_JUMP_SLOT 00000000 say_hello 080496f8 00000407 R_386_JUMP_SLOT 00000000 __libc_start_main 080496fc 00000507 R_386_JUMP_SLOT 00000000 printf ...