$ gcc -g -o got got.c $ gdb ./got (gdb) l 5 #include <stdio.h> 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 #在第一個(gè)printf處設(shè)置一個(gè)斷點(diǎn) Breakpoint 1 at 0x80483c3: file got.c, line 18. (gdb) break 22 #在第二個(gè)printf處設(shè)置一個(gè)斷點(diǎn) Breakpoint 2 at 0x80483dd: file got.c, line 22. (gdb) r #運(yùn)行到第一個(gè)printf之前會(huì)停止 Starting program: /mnt/hda8/Temp/c/program/got
Breakpoint 1, main () at got.c:18 18 printf("Hello World\n"); (gdb) x/8x 0x8049614 #查看執(zhí)行printf之前的全局偏移表內(nèi)容 0x8049614 <_GLOBAL_OFFSET_TABLE_>: 0x08049548 0xb7f3c6d8 0xb7f33f10 0x080482aa 0x8049624 <_GLOBAL_OFFSET_TABLE_+16>: 0xb7ddbd20 0x080482ca 0x080482da 0x00000000 (gdb) disassemble 0x080482da #查看GOT表項(xiàng)的最有一項(xiàng),發(fā)現(xiàn)剛好是PLT表中push指令的地址,說明此時(shí)還沒有進(jìn)行進(jìn)行符號(hào)的重定位,不過發(fā)現(xiàn)并非printf,而是puts(1) Dump of assembler code for function puts@plt: 0x080482d4 <puts@plt+0>: jmp *0x804962c 0x080482da <puts@plt+6>: push $0x18 0x080482df <puts@plt+11>: jmp 0x8048294 <_init+24> (gdb) disassemble 0xb7f33f10 #查看GOT第三項(xiàng)的內(nèi)容,剛好是dl-linux對(duì)應(yīng)的代碼, #可通過nm /lib/ld-linux.so.2 | grep _dl_runtime_resolve進(jìn)行確認(rèn) 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表第二項(xiàng)處的內(nèi)容,看不出什么特別的信息,反編譯時(shí)提示無法反編譯 0xb7f3c6d8: 0x00000000 0xb7f39c3d 0x08049548 0xb7f3c9b8 0xb7f3c6e8: 0x00000000 0xb7f3c6d8 0x00000000 0xb7f3c9a4 (gdb) break *(0xb7f33f10) #在*(0xb7f33f10)指向的代碼處設(shè)置一個(gè)斷點(diǎn),確認(rèn)它是否被執(zhí)行 break *(0xb7f33f10) Breakpoint 3 at 0xb7f3cf10 (gdb) c Continuing.
Breakpoint 3, 0xb7f3cf10 in _dl_runtime_resolve () from /lib/ld-linux.so.2 (gdb) c #繼續(xù)運(yùn)行,直到第二次調(diào)用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表項(xiàng),發(fā)現(xiàn)GOT表的最后一項(xiàng)的值應(yīng)該被修改 0x8049614 <_GLOBAL_OFFSET_TABLE_>: 0x08049548 0xb7f3c6d8 0xb7f33f10 0x080482aa 0x8049624 <_GLOBAL_OFFSET_TABLE_+16>: 0xb7ddbd20 0x080482ca 0xb7e1ea20 0x00000000 (gdb) disassemble 0xb7e1ea20 #查看GOT表最后一項(xiàng),發(fā)現(xiàn)變成了puts函數(shù)的代碼,說明進(jìn)行了符號(hào)puts的重定位(2) Dump of assembler code for function puts: 0xb7e1ea20 <puts+0>: push %ebp 0xb7e1ea21 <puts+1>: mov %esp,%ebp 0xb7e1ea23 <puts+3>: sub $0x1c,%esp
|