$ gcc -g -o got got.c $ gdb ./got (gdb) l 5
#include 6 7 #define GOT 0x8049614 8 9
int main(int argc, char *argv[]) 10 { 11 long
got2, got3; 12 long old_addr, new_addr; 13 14
got2=*(long *)(GOT+4); (gdb) l 15 got3=*(long
*)(GOT+8); 16 old_addr=*(long *)(GOT+24); 17 18
printf("Hello World\n"); 19 20 new_addr=*(long
*)(GOT+24); 21 22 printf("got2: 0x%0x, got3: 0x%0x,
old_addr: 0x%0x, new_addr: 0x%0x\n", 23
got2, got3, old_addr, new_addr); 24 (gdb) break 18
#在第一个printf处设置一个断点 Breakpoint 1 at 0x80483c3: file got.c, line 18. (gdb)
break 22 #在第二个printf处设置一个断点 Breakpoint 2 at 0x80483dd: file
got.c, line 22. (gdb) r #运行到第一个printf之前会停止 Starting
program: /mnt/hda8/Temp/c/program/got
Breakpoint 1, main () at
got.c:18 18 printf("Hello World\n"); (gdb) x/8x
0x8049614 #查看执行printf之前的全局偏移表内容 0x8049614
<_GLOBAL_OFFSET_TABLE_>: 0x08049548 0xb7f3c6d8
0xb7f33f10 0x080482aa 0x8049624
<_GLOBAL_OFFSET_TABLE_+16>: 0xb7ddbd20 0x080482ca
0x080482da 0x00000000 (gdb) disassemble 0x080482da
#查看GOT表项的最有一项,发现刚好是PLT表中push指令的地址,说明此时还没有进行进行符号的重定位,不过发现并非printf,而是
puts(1) Dump of assembler code for function puts@plt: 0x080482d4 :
jmp *0x804962c 0x080482da : push $0x18 0x080482df
: jmp 0x8048294 <_init+24> (gdb)
disassemble 0xb7f33f10 #查看GOT第三项的内容,刚好是dl-linux对应的代码,
#可通过nm /lib/ld-linux.so.2 | grep _dl_runtime_resolve进行确认 Dump of
assembler code for function _dl_runtime_resolve: 0xb7f33f10
<_dl_runtime_resolve+0>: push %eax 0xb7f33f11
<_dl_runtime_resolve+1>: push %ecx 0xb7f33f12
<_dl_runtime_resolve+2>: push %edx (gdb) x/8x
0xb7f3c6d8 #查看GOT表第二项处的内容,看不出什么特别的信息,反编译时提示无法反编译 0xb7f3c6d8:
0x00000000 0xb7f39c3d 0x08049548 0xb7f3c9b8 0xb7f3c6e8:
0x00000000 0xb7f3c6d8 0x00000000 0xb7f3c9a4 (gdb)
break *(0xb7f33f10) #在*(0xb7f33f10)指向的代码处设置一个断点,确认它是否被执行 break
*(0xb7f33f10) Breakpoint 3 at 0xb7f3cf10 (gdb) c Continuing.
Breakpoint
3, 0xb7f3cf10 in _dl_runtime_resolve () from /lib/ld-linux.so.2 (gdb)
c #继续运行,直到第二次调用printf Continuing. Hello World
Breakpoint
2, main () at got.c:22 22 printf("got2: 0x%0x, got3:
0x%0x, old_addr: 0x%0x, new_addr: 0x%0x\n", (gdb) x/8x 0x8049614
#再次查看GOT表项,发现GOT表的最后一项的值应该被修改 0x8049614
<_GLOBAL_OFFSET_TABLE_>: 0x08049548 0xb7f3c6d8
0xb7f33f10 0x080482aa 0x8049624
<_GLOBAL_OFFSET_TABLE_+16>: 0xb7ddbd20 0x080482ca
0xb7e1ea20 0x00000000 (gdb) disassemble 0xb7e1ea20
#查看GOT表最后一项,发现变成了puts函数的代码,说明进行了符号puts的重定位(2) Dump of assembler code
for function puts: 0xb7e1ea20 : push %ebp 0xb7e1ea21 :
mov %esp,%ebp 0xb7e1ea23 : sub $0x1c,%esp
|