RELOCATION
relocation 实验
- 跟第一个参考文章有一点小区别,比如 section name, 但不重要
- 重点是研究
puts@ptl
找到 puts
的过程
- gcc, gdb , hd, objdump
// Build with: gcc -m32 -no-pie -g -o plt plt.c
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
puts("Hello world!");
exit(0);
}
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[13] .plt PROGBITS 08049030 001030 000040 04 AX 0 0 16
[14] .plt.sec PROGBITS 08049070 001070 000030 10 AX 0 0 16
[15] .text PROGBITS 080490a0 0010a0 0001c9 00 AX 0 0 16
[23] .got PROGBITS 0804bffc 002ffc 000004 04 WA 0 0 4
[24] .got.plt PROGBITS 0804c000 003000 000018 04 WA 0 0 4
// .plt: 08049030 ~ 08049070(08049030+0x40) 几个小代码段
└─[$] hd plt -s $((16#001030)) -n $((16#40)) [14:43:47]
00001030 ff 35 04 c0 04 08 ff 25 08 c0 04 08 0f 1f 40 00 |.5.....%......@.|
00001040 f3 0f 1e fb 68 00 00 00 00 e9 e2 ff ff ff 66 90 |....h.........f.|
00001050 f3 0f 1e fb 68 08 00 00 00 e9 d2 ff ff ff 66 90 |....h.........f.|
00001060 f3 0f 1e fb 68 10 00 00 00 e9 c2 ff ff ff 66 90 |....h.........f.|
00001070
└─[$] objdump -j .plt -d plt -M intel
08049030 <.plt>:
8049030: ff 35 04 c0 04 08 push DWORD PTR ds:0x804c004
8049036: ff 25 08 c0 04 08 jmp DWORD PTR ds:0x804c008
804903c: 0f 1f 40 00 nop DWORD PTR [eax+0x0]
8049040: f3 0f 1e fb endbr32
8049044: 68 00 00 00 00 push 0x0
8049049: e9 e2 ff ff ff jmp 8049030 <.plt>
804904e: 66 90 xchg ax,ax
8049050: f3 0f 1e fb endbr32
8049054: 68 08 00 00 00 push 0x8
8049059: e9 d2 ff ff ff jmp 8049030 <.plt>
804905e: 66 90 xchg ax,ax
8049060: f3 0f 1e fb endbr32
8049064: 68 10 00 00 00 push 0x10
8049069: e9 c2 ff ff ff jmp 8049030 <.plt>
804906e: 66 90 xchg ax,ax
// .plt.sec: 08049070 ~ 0x80490a0(0x08049070 + 0x30)
└─[$] objdump -j .plt.sec -d plt -M intel [14:47:26]
Disassembly of section .plt.sec:
08049070 <puts@plt>:
8049070: f3 0f 1e fb endbr32
8049074: ff 25 0c c0 04 08 jmp DWORD PTR ds:0x804c00c
804907a: 66 0f 1f 44 00 00 nop WORD PTR [eax+eax*1+0x0]
08049080 <exit@plt>:
8049080: f3 0f 1e fb endbr32
8049084: ff 25 10 c0 04 08 jmp DWORD PTR ds:0x804c010
804908a: 66 0f 1f 44 00 00 nop WORD PTR [eax+eax*1+0x0]
08049090 <__libc_start_main@plt>:
8049090: f3 0f 1e fb endbr32
8049094: ff 25 14 c0 04 08 jmp DWORD PTR ds:0x804c014
804909a: 66 0f 1f 44 00 00 nop WORD PTR [eax+eax*1+0x0]
// .got 保存外部全局变量地址
└─[$] objdump -j .got -s plt
Contents of section .got:
804bffc 00000000
// .got.plt: 0x0804c000 ~ 0x804c018(0x0804c000 + 0x18) // 指向真正的函数的address table
0804c000 <_GLOBAL_OFFSET_TABLE_>:
804c000: 14 bf 04 08 00 00 00 00 00 00 00 00 40 90 04 08 ............@...
804c010: 50 90 04 08 60 90 04 08 P...`...
Dump of assembler code for function main:
...
0x080491de <+40>: call 0x8049070 <puts@plt> // [1]
1: x/5i $pc
=> 0x8049070 <puts@plt>: endbr32
0x8049074 <puts@plt+4>: jmp DWORD PTR ds:0x804c00c // [2]
0x804907a <puts@plt+10>: nop WORD PTR [eax+eax*1+0x0]
(gdb) x/1xw 0x804c00c
0x804c00c <[email protected]>: 0x08049040 // [3]
****
(gdb) x/5i 0x08049040
0x8049040: endbr32
0x8049044: push 0x0
0x8049049: jmp 0x8049030 // [4]
**** 0x804904e: xchg ax,ax
0x8049050: endbr32
(gdb) x/10i 0x8049030
0x8049030: push DWORD PTR ds:0x804c004 // [5]
0x8049036: jmp DWORD PTR ds:0x804c008 // [6]
0x804903c: nop DWORD PTR [eax+0x0]
(gdb) x/1xw 0x804c004
0x804c004: 0xf7ffd9a0 // [7]
(gdb) x/1xw 0x804c008
0x804c008: 0xf7fe7500 // [8]
(gdb) bt
#0 0xf7fe7500 in ?? () from /lib/ld-linux.so.2
#1 0x080491e3 in main (argc=1, argv=0xffffd4f4) at plt.c:5
// 执行完 ld-linux.so 函数的 ret 指令后
(gdb) x/1xw 0x804c00c // [3]
0x804c00c <[email protected]>: 0xf7e27da0 // [9]
****(gdb) info symbol 0xf7e27da0
puts in section .text of /lib/i386-linux-gnu/libc.so.6
(gdb) x/10i 0xf7e27da0
0xf7e27da0 <puts>: endbr32
0xf7e27da4 <puts+4>: push ebp
0xf7e27da5 <puts+5>: mov ebp,esp
0xf7e27da7 <puts+7>: push edi
...
cat /proc/xxx/maps
...
f7fd0000-f7fd1000 r--p 00000000 08:05 8153880 /usr/lib/i386-linux-gnu/ld-2.32.so
**f7fd1000-f7ff0000 r-xp 00001000 08:05 8153880 /usr/lib/i386-linux-gnu/ld-2.32.so**
f7ff0000-f7ffb000 r--p 00020000 08:05 8153880 /usr/lib/i386-linux-gnu/ld-2.32.so
f7ffc000-f7ffd000 r--p 0002b000 08:05 8153880 /usr/lib/i386-linux-gnu/ld-2.32.so
f7ffd000-f7ffe000 rw-p 0002c000 08:05 8153880 /usr/lib/i386-linux-gnu/ld-2.32.so
...
f7db6000-f7dd3000 r--p 00000000 08:05 8153884 /usr/lib/i386-linux-gnu/libc-2.32.so
**f7dd3000-f7f34000 r-xp 0001d000 08:05 8153884 /usr/lib/i386-linux-gnu/libc-2.32.so**
f7f34000-f7fa7000 r--p 0017e000 08:05 8153884 /usr/lib/i386-linux-gnu/libc-2.32.so
f7fa7000-f7fa9000 r--p 001f0000 08:05 8153884 /usr/lib/i386-linux-gnu/libc-2.32.so
f7fa9000-f7fab000 rw-p 001f2000 08:05 8153884 /usr/lib/i386-linux-gnu/libc-2.32.so
- 第一个地址
puts@plt: 0x8049070
位于 .plt.sec: 08049070 ~ 0x80490a0
- 第二个地址
0x804c00c
保存 jmp 目标的指针,位于 .got.plt: 0x0804c000 ~ 0x804c018(0x0804c000 + 0x18)
- 第三个地址
0x08049040
即 0x804c00c
保存的地址,位于.plt: 08049030 ~ 08049070(08049030+0x40)
,第二个 stub
- 第四个地址
0x8049030
,stup jmp 的目标,位于 .plt: 08049030 ~ 08049070(08049030+0x40)
,第一个 stub
- 第五/六个地址 0x804c004 和 0x804c008,位于
.got.plt: 0x0804c000 ~ 0x804c018(0x0804c000 + 0x18)
, 分别保存了 0xf7ffd9a0 和 0xf7fe7500
0xf7fe7500
位于 ld-linux.so.2