RELOCATION

relocation 实验

// 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