利用ESP定律的upx脱壳实践

本文介绍了利用ESP定律进行UPX壳的手动脱壳实践。通过理解堆栈平衡原理,从查壳、OD打开到设置硬件断点,逐步找到OEP并跳转执行,最终成功脱壳。在实践中,作者详细解释了每一步的操作和原因,特别是ESP和EIP寄存器的变化,以及popad指令的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景:
除了命令行upx -d脱壳,还有手动脱壳。ESP定律的本质是堆栈平衡,又称堆栈平衡定律,是应用频率最高的脱壳方法之一,脱壳的目的就是找到真正的OEP(源文件的EP代码)

方法:
从pushad到popad是一段解压缩代码(解压UPX壳),这段代码执行后,紧跟在popad后的第一个JMP指令可跳转到OEP
实践:
1:查壳在这里插入图片描述
2:OD打开
在这里插入图片描述
3:F8
在这里插入图片描述
//对于寄存器,指令执行后发生改变的寄存器会用红色显示,此处ESP和EIP的值发生改变,因为执行pushad指令,将8个通用寄存器(EAX-EDI)的值保存至栈,栈中的值增加了,所以ESP的值发生变化,而EIP的值表示下一个要执行指令的地址,也发生变化
执行PUSHAD的原因是使栈平衡,这段代码的最后还有popad,两者执行后可以把ESP的值回到原值,这里不明白为什么使栈帧平衡要执行push和pop,如果没有这两步只执行movebp,esp,不是还有基准值,搞不懂push和pop的意义)

4:下硬件断点
在这里插入图片描述
//下硬件断点,与F2断点不同的是,硬件断点直到下断点地址处的指令执行完成后,才完成调试,也就是说,程序会不断执行直到遇到了硬件断点处的地址,把该处地址的指令执行完成后,才完成调试,此处在ESP为000DFF54处下硬件断点的原因,我的理解是,是为了到达popad处回到栈的初始状态完成解压缩代码,在popad未执行时,它前一个指令执行后ESP的值应该是000DFF54,所以运行后再次遇到ESP为000DFF54时,下一个命令是popad
(popad指令把pushad存储在栈中的值再次恢复到各个寄存器,我理解为8次pop命令)

5:F9运行
在这里插入图片描述
//猜测未执行popad时,ESP的值应该是000DFF54,此时还未将8个寄存器的值弹出栈。执行popad时的瞬间访问到硬件断点000DFF54,暂停调试,此时已执行了popad,回到了栈的初始状态,发现除了EIP其他寄存器值和初始寄存器的值一样

6:找到离popad最近的JMP,执行JMP跳转
在这里插入图片描述
//发现OEP处寄存器的值除了EAX和EIP,其他的的值和pushad的值一样
EAX中值不一样的原因是,EAX中保存函数的返回值,保存的是OEP的地址

7:脱壳
在这里插入图片描述
总结:
1:执行pushad,下硬件断点F9运行
2:找到popad后的第一个jmp指令F8
3:跳转到了OEP

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

y4n9-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值