.got&.plt简要调试分析

基于buuctf/rip
寻找puts函数的动态链接

###  readelf
readelf -S filename      查看session header找到相关重定向表

.plt       0000000000401020
.got       0000000000403ff0
.got.plt   0000000000404000


###  gdb调试

断点:b *0x401151
[-------------------------------------code-------------------------------------]
   0x401143 <main+1>:   mov    rbp,rsp
   0x401146 <main+4>:   sub    rsp,0x10
   0x40114a <main+8>:   lea    rdi,[rip+0xeb3]        # 0x402004
=> 0x401151 <main+15>:  call   0x401030 <puts@plt>
   0x401156 <main+20>:  lea    rax,[rbp-0xf]
   0x40115a <main+24>:  mov    rdi,rax
   0x40115d <main+27>:  mov    eax,0x0
   0x401162 <main+32>:  call   0x401050 <gets@plt>
Guessed arguments:
arg[0]: 0x402004 ("please input")


(1)si
[-------------------------------------code-------------------------------------]
   0x401021:    xor    eax,0x2fe2
   0x401026:    jmp    QWORD PTR [rip+0x2fe4]        # 0x404010
   0x40102c:    nop    DWORD PTR [rax+0x0]
=> 0x401030 <puts@plt>: jmp    QWORD PTR [rip+0x2fe2]        # 0x404018 <puts@got.plt>
 | 0x401036 <puts@plt+6>:       push   0x0
 | 0x40103b <puts@plt+11>:      jmp    0x401020
 | 0x401040 <system@plt>:       jmp    QWORD PTR [rip+0x2fda]        # 0x404020 <system@got.plt>
 | 0x401046 <system@plt+6>:     push   0x1
 |->   0x401036 <puts@plt+6>:   push   0x0
       0x40103b <puts@plt+11>:  jmp    0x401020
       0x401040 <system@plt>:   jmp    QWORD PTR [rip+0x2fda]        # 0x404020 <system@got.plt>
       0x401046 <system@plt+6>: push   0x1
                                                                  JUMP is taken


(3)x/2w 0x404018
可以发现指向了一个不知道哪里的地方,此时是因为是第一次寻找puts函数所以指向的地址上没有需要的puts函数地址(这个点很重要)
0x404018 <puts@got.plt>:        0x00401036      0x00000000


(3)可以发现jmp执行直接进入了下一条指令push而不是跳转
jmp指向的地址0x404018处于.got.plt表内,说明puts函数的寻找先到.got.plt表内寻找
[-------------------------------------code-------------------------------------]
   0x401026:    jmp    QWORD PTR [rip+0x2fe4]        # 0x404010
   0x40102c:    nop    DWORD PTR [rax+0x0]
   0x401030 <puts@plt>: jmp    QWORD PTR [rip+0x2fe2]        # 0x404018 <puts@got.plt>
=> 0x401036 <puts@plt+6>:       push   0x0
   0x40103b <puts@plt+11>:      jmp    0x401020
   0x401040 <system@plt>:       jmp    QWORD PTR [rip+0x2fda]        # 0x404020 <system@got.plt>
   0x401046 <system@plt+6>:     push   0x1
   0x40104b <system@plt+11>:    jmp    0x401020


(4)si
jmp指向的地址0x404020处于.plt表起始,说明跳转到.plt表内
[-------------------------------------code-------------------------------------]
   0x40102c:    nop    DWORD PTR [rax+0x0]
   0x401030 <puts@plt>: jmp    QWORD PTR [rip+0x2fe2]        # 0x404018 <puts@got.plt>
   0x401036 <puts@plt+6>:       push   0x0
=> 0x40103b <puts@plt+11>:      jmp    0x401020
 | 0x401040 <system@plt>:       jmp    QWORD PTR [rip+0x2fda]        # 0x404020 <system@got.plt>
 | 0x401046 <system@plt+6>:     push   0x1
 | 0x40104b <system@plt+11>:    jmp    0x401020
 | 0x401050 <gets@plt>: jmp    QWORD PTR [rip+0x2fd2]        # 0x404028 <gets@got.plt>
 |->   0x401020:        push   QWORD PTR [rip+0x2fe2]        # 0x404008
       0x401026:        jmp    QWORD PTR [rip+0x2fe4]        # 0x404010
       0x40102c:        nop    DWORD PTR [rax+0x0]
       0x401030 <puts@plt>:     jmp    QWORD PTR [rip+0x2fe2]        # 0x404018 <puts@got.plt>
                                                                  JUMP is taken


(5)si
[-------------------------------------code-------------------------------------]
   0x40101a:    add    BYTE PTR [rax],al
   0x40101c:    add    BYTE PTR [rax],al
   0x40101e:    add    BYTE PTR [rax],al
=> 0x401020:    push   QWORD PTR [rip+0x2fe2]        # 0x404008
   0x401026:    jmp    QWORD PTR [rip+0x2fe4]        # 0x404010
   0x40102c:    nop    DWORD PTR [rax+0x0]
   0x401030 <puts@plt>: jmp    QWORD PTR [rip+0x2fe2]        # 0x404018 <puts@got.plt>
   0x401036 <puts@plt+6>:       push   0x0


(6)x/2w 0x404008(因为是QWORD,64位数据,而每位是32位的数据,64位数据就需要两个位置)
0x404008:       0xf7ffe2c0      0x00007fff


(7)si
jmp指向的地址处于.got.plt表内,说明又转到.got.plt表内一个地址上指向的地址
[-------------------------------------code-------------------------------------]
   0x40101d:    add    BYTE PTR [rax],al
   0x40101f:    add    bh,bh
   0x401021:    xor    eax,0x2fe2
=> 0x401026:    jmp    QWORD PTR [rip+0x2fe4]        # 0x404010
 | 0x40102c:    nop    DWORD PTR [rax+0x0]
 | 0x401030 <puts@plt>: jmp    QWORD PTR [rip+0x2fe2]        # 0x404018 <puts@got.plt>
 | 0x401036 <puts@plt+6>:       push   0x0
 | 0x40103b <puts@plt+11>:      jmp    0x401020
 |->   0x7ffff7fdd400:  push   rbx
       0x7ffff7fdd401:  mov    rbx,rsp
       0x7ffff7fdd404:  and    rsp,0xfffffffffffffff0
       0x7ffff7fdd408:  sub    rsp,0x240
                                                                  JUMP is taken
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffe198 --> 0x7ffff7ffe2c0 --> 0x0                这里就是压入了 0xf7ffe2c0 和 0x00007fff
0008| 0x7fffffffe1a0 --> 0x0
0016| 0x7fffffffe1a8 --> 0x401156 (<main+20>:   lea    rax,[rbp-0xf])
0024| 0x7fffffffe1b0 --> 0x0
0032| 0x7fffffffe1b8 --> 0x0
0040| 0x7fffffffe1c0 --> 0x1
0048| 0x7fffffffe1c8 --> 0x7ffff7df16ca (mov    edi,eax)
0056| 0x7fffffffe1d0 --> 0x0
[------------------------------------------------------------------------------]
(虽然确实压入了数据,但是该数据在后面调试中发现会被覆盖掉,所以不知道该数据的作用是什么。。。)
(不过按照地址来看,这段数据应该是属于ld.so的数据)


(8)x/2w 0x404010
0x404010:       0xf7fdd400      0x00007fff


(9)si
此时跳转到/lib64/ld-linux-x86-64.so.2的实际地址了
[-------------------------------------code-------------------------------------]
   0x7ffff7fdd3f2:      ret
   0x7ffff7fdd3f3:      data16 cs nop WORD PTR [rax+rax*1+0x0]
   0x7ffff7fdd3fe:      xchg   ax,ax
=> 0x7ffff7fdd400:      push   rbx                      可以发现成功跳转到 0xf7fdd400 和 0x00007fff指向的地址
   0x7ffff7fdd401:      mov    rbx,rsp
   0x7ffff7fdd404:      and    rsp,0xfffffffffffffff0
   0x7ffff7fdd408:      sub    rsp,0x240
   0x7ffff7fdd40f:      mov    QWORD PTR [rsp],rax


(10)多个ni后
[-------------------------------------code-------------------------------------]
   0x7ffff7fdd46d:      mov    rsp,rbx
   0x7ffff7fdd470:      mov    rbx,QWORD PTR [rsp]
   0x7ffff7fdd474:      add    rsp,0x18
=> 0x7ffff7fdd478:      jmp    r11
 | 0x7ffff7fdd47b:      nop    DWORD PTR [rax+rax*1+0x0]
 | 0x7ffff7fdd480:      push   rbx
 | 0x7ffff7fdd481:      mov    rbx,rsp
 | 0x7ffff7fdd484:      and    rsp,0xffffffffffffffc0
 |->   0x7ffff7e3fb70 <puts>:   push   r14                    这里要开始转到实际puts地址开始执行了
       0x7ffff7e3fb72 <puts+2>: push   r13
       0x7ffff7e3fb74 <puts+4>: push   r12
       0x7ffff7e3fb76 <puts+6>: push   rbp
                                                                  JUMP is taken


(11)si后执行info symbol $pc
puts in section .text of /lib/x86_64-linux-gnu/libc.so.6      说明确实是处于系统库的puts函数实际地址


(12)finish跳出puts函数,执行x/2w   0x404018
可以发现此时在0x404018这个地址上不再是原来储存的地址,储存的反而是指向puts在系统库内的实际地址
0x404018 <puts@got.plt>:        0xf7e3fb70      0x00007fff

简要流程图

学习于:

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值