手脱 Upx 壳
记录学习手脱 Upx 壳的过程,分 PE 篇和 ELF 篇。
手动脱壳的原理
在加壳的程序执行时,壳会先于原程序执行,将原程序恢复。通过动态调试的方式将程序运行到壳执行结束的时刻,此时内存中已有恢复了的原程序,将这部分内存复制一份,就得到了脱完壳的程序。
PE 篇
例题:BUUCTF 新年快乐
需要用到工具 x32dbg,Exeinfo PE。
先用 Exeinfo 查壳,发现是 upx。
然后使用 x32dbg 打开文件:
根据堆栈平衡原理脱壳。
堆栈平衡原理:
upx 壳运行时,会先将所有寄存器入栈(
pushad
),根据栈先进后出的特性,这些寄存器会在壳运行结束处附近出栈,所以我们只需找到程序开始的pushad
指令,执行完该指令后对esp
指向的内存地址打一个断点,就能快速找到 upx 壳的结束部分。
x32dbg 自动发现了 pushad
,可以在断点栏看到:
运行程序,直到程序在 pushad
处停下。
执行 pushad
,然后转到对 esp
指向的地址打断点:
运行,果然在 popad
执行后停下了:
到这里壳基本执行完了,下一个无条件跳转就会跳到原程序的入口。所以我们一路步过到那条 jmp
,然后 dump 内存。
得到的程序已能用 IDA 正常反编译。
ELF 篇
elf 文件无法在 windows 下运行,故需要用 IDA 进行远程调试。
elf 文件同样可以用 Exeinfo 查壳。
懒得写了,这个讲得挺好的:运行时压缩壳 - IDA动调ELF脱壳
贴个关键脚本:
1 |
|
手脱 Upx 壳
https://azc-pkk.github.io/2024/12/04/手脱-Upx-壳/