调试下的plt&got

源码

// 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);
}

setions信息

@ubuntu:~$ readelf -S plt
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [12] .plt              PROGBITS        080482f0 0002f0 000040 04  AX  0   0 16
  [14] .text             PROGBITS        08048340 000340 000192 00  AX  0   0 16
  [23] .got              PROGBITS        08049ffc 000ffc 000004 04  WA  0   0  4
  [24] .got.plt          PROGBITS        0804a000 001000 000018 04  WA  0   0  4

以下是原图:

gdb-peda:put@plt首探

gdb-peda$ disass main
Dump of assembler code for function main:
   0x0804843b <+0>:	lea    ecx,[esp+0x4]
   0x0804843f <+4>:	and    esp,0xfffffff0
   0x08048442 <+7>:	push   DWORD PTR [ecx-0x4]
   0x08048445 <+10>:	push   ebp
   0x08048446 <+11>:	mov    ebp,esp
   0x08048448 <+13>:	push   ecx
   0x08048449 <+14>:	sub    esp,0x4
   0x0804844c <+17>:	sub    esp,0xc
   0x0804844f <+20>:	push   0x80484f0
   0x08048454 <+25>:	call   0x8048300 <puts@plt>
   0x08048459 <+30>:	add    esp,0x10
   0x0804845c <+33>:	sub    esp,0xc
   0x0804845f <+36>:	push   0x0
   0x08048461 <+38>:	call   0x8048310 <exit@plt>
End of assembler dump.
gdb-peda$ break * 0x08048454
Breakpoint 1 at 0x8048454: file plt.c, line 5.
gdb-peda$ r
...
gdb-peda$ x/i $eip
=> 0x8048454 <main+25>:	call   0x8048300 <puts@plt>

结合.plt section信息 0x8048300就在.plt section,puts@plt是特殊符号名称

gdb-peda$ set $eip = 0x8048300
gdb-peda$ p $eip
$1 = (void (*)()) 0x8048300 <puts@plt>
gdb-peda$ x/i $eip
=> 0x8048300 <puts@plt>:	jmp    DWORD PTR ds:0x804a00c

0x804a00c(指针)在.got.plt节这里

gdb-peda$ b *0x8048300
Note: breakpoint 3 also set at pc 0x8048300.
Breakpoint 4 at 0x8048300
gdb-peda$ j *0x8048300
gdb-peda$ x/wx 0x804a00c
0x804a00c:	0x08048306
...
=> 0x8048300 <puts@plt>:	jmp    DWORD PTR ds:0x804a00c
 | 0x8048306 <puts@plt+6>:	push   0x0
 | 0x804830b <puts@plt+11>:	jmp    0x80482f0
 | 0x8048310 <exit@plt>:	jmp    DWORD PTR ds:0x804a010
 | 0x8048316 <exit@plt+6>:	push   0x8
 |->   0x8048306 <puts@plt+6>:	push   0x0
       0x804830b <puts@plt+11>:	jmp    0x80482f0
       0x8048310 <exit@plt>:	jmp    DWORD PTR ds:0x804a010
       0x8048316 <exit@plt+6>:	push   0x8

乍一看就得很奇怪,为什么要莫名其妙的跳到紧接着下一条指令处?那是因为我们之前从未调用过puts函数,所以我们需要出发首次查找,push 0x0 在栈上压入(0x0),然后调用例程以查找符号名称。 这恰好是.plt节的开始(jmp 0x80482f0)

gdb-peda$ x/10i  0x80482f0
=> 0x80482f0:	push   DWORD PTR ds:0x804a004
   0x80482f6:	jmp    DWORD PTR ds:0x804a008
   0x80482fc:	add    BYTE PTR [eax],al
   0x80482fe:	add    BYTE PTR [eax],al
   0x8048300 <puts@plt>:	jmp    DWORD PTR ds:0x804a00c
   0x8048306 <puts@plt+6>:	push   0x0
   0x804830b <puts@plt+11>:	jmp    0x80482f0
   0x8048310 <exit@plt>:	jmp    DWORD PTR ds:0x804a010
   0x8048316 <exit@plt+6>:	push   0x8
   0x804831b <exit@plt+11>:	jmp    0x80482f0

以下的第一个(0xf7ffd918)指向ld.so的数据段(可写),第二个(0xf7fedfe0)指向可执行区域

gdb-peda$  x/2wx 0x804a004
0x804a004:	0xf7ffd918	0xf7fedfe0
gdb-peda$ vmmap
Start      End        Perm	Name
0xf7fd9000 0xf7ffc000 r-xp	/lib32/ld-2.23.so
0xf7ffc000 0xf7ffd000 r--p	/lib32/ld-2.23.so
0xf7ffd000 0xf7ffe000 rw-p	/lib32/ld-2.23.so

链接器/加载器(ld.so)在加载二进制文件时填充了.got.plt节中的这两个地址。因此,我将把ld.so中发生的事情视为黑匣子(查找符号的过程)可以说,最终我们将从ld.so代码中获取有关解析符号的内容。

原文:

https://systemoverlord.com/2017/03/19/got-and-plt-for-pwning.html

posted @ 2020-04-23 20:34  zer0_1s  阅读(473)  评论(0编辑  收藏  举报