zl程序教程

您现在的位置是:首页 >  其它

当前栏目

利用ESP定律的upx脱壳实践

利用 实践 脱壳 定律 UPX ESP
2023-06-13 09:12:16 时间

大家好,又见面了,我是你们的朋友全栈君。

背景: 除了命令行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

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/161728.html原文链接:https://javaforall.cn