栈迁移基础

栈迁移


当我们的rop链过长时很可能栈空间不够,并且ebp之前的空间其实只是填充一些没什么用的数据

栈迁移机理


与传统的pop_ret类似,利用level_ret实现栈的迁移,都是寻找很小短的零碎代码,进行拼接,和拼积木很像。

level ret//拆解
mov ebp,esp//esp跟着ebp走
pop ebp //栈基指针的转移
pop eip//ret 

示例

栈迁移基础

.data:0804A008 count           dd 539h    //1337用十六进制表示就是539h

当我们还不知道level_ret时,采用一般的rop必然要在回到输入点,就这道题就是(main函数),但发现main函数受到count的影响仅一次main(无法重复利用main),所以要换一种思路。那我们能否利用有效的代码段与一段可以容纳数据(在我们的脚本中的要发送的数据)构成类似栈的结构,答案当然是可以的

显然有read 函数,但是(0x40-0x28)真正的数据填充区域有限,可有read函数,就想能否将数据写入某个位置(比如.bss)read(0,buf,0x100)

                    |    buf(ebp) |  //pop数值到ebp,改变基址
                    |   read(ret) |  //pop到eip,执行read(0,buf,0x100)
                    |     ret     |  //执行完read后返回,pop到eip
                    |     0       |
                    |     buf     |
                    |     0x100   |

这是一开始的栈的布局,看着很合理,但实际上还有缺陷,,比如执行完read后执行流终断,,因为.bss没有栈的pop的机制段,放在多数据却没法用。

                    |       buf        |//pop数值到ebp,改变基址
                    |     read_plt     |//pop到eip,执行read(0,buf,0x100)
                    |       leave_ret  |//pop到eip,执行leave_ret=>esp被代跑(触发)
                    |         0        |//此时栈指针都没了(栈已被移走;触发后)
                    |       buf        |
                    |       0x100      |

泄露地址

            .bss     |    buf2       |//这里写buf2的原因是pop ebp, 改变基址
                     |    puts_plt   |//这里要打印泄露puts的装载地址,leave_ret 的ret那一步
                     |   pop_ret     |//puts(puts_got)后,pop到eip,执行
                     |  puts_gots    |//要泄露的参数值,之后pop掉
                  
 pop ret        =》  |     read_plt  |//pop到eip,执行read(0,buf,0x100)   
                     |     leave_ret  |//pop到eip,执行leave_ret=>esp被代跑(触发)                                                                                       
                     |      0        |//此时栈指针都没了(已被移走;触发后)
                     |    buf        |
                     |    0x100      |      

调用system 函数

                     
            .bss     |    bbbb       |//随便 改变基址pop ebp 那一步
                     |    system     |//leave_ret 的ret那一步
                     |    cccc       |//返回地址随便写
                     |  binsh_addr   |                                                                               

栈迁移基础

上图仅供参考

上一篇:BUUCTF-RE-reverse3


下一篇:逆向工程-if-else语句逆向分析