【2022.1.3】手脱压缩壳练习(含练习exe)
0、简介
记录练习手脱壳(简单的压缩壳),都有对应练习exe。(虽然都是一样的。。。)
壳简介:
图片来源:看雪论坛
对比上图,可以理解壳的加载过程一般分为4步:
-
保存入口参数
(通常用 pushad / popad、pushfd / popfd 指令对来保存和恢复现场环境)
-
获取所需函数 API
一般是
LoadLibrary
+GetProAddress
-
解密各区块数据
-
(恢复入口参数,比如通过popad)跳转回原程序入口点AddressOfEntryPoint
而我们脱壳要做的就是,在有壳程序执行完步骤4之后,把程序dump出来,此时dump出来的程序虽然不能启动,但是已经可以被IDA反编译出正常的自身函数了,不过还是有些导入的函数看不见名字,一般是IAT表出现问题,所以还要通过ImportREC.exe
进行IAT重建,之后即可正常启动,
常规的脱壳方法一般有几种:单步跟踪法、ESP定律法、一步到达OEP法等等。
下面就是脱壳练习记录~
1、单步跟踪法
(#)方法介绍
总的来说:就是一步步调试,直到程序自动自动解壳
**概述:**单步跟踪法的原理就是通过 Ollydbg 的步过 (F8), 步入(F7) 和运行到 (F4) 功能, 完整走过程序的自脱壳过程, 跳过一些循环恢复代码的片段, 并用单步进入确保程序不会略过 OEP. 这样可以在软件自动脱壳模块运行完毕后, 到达 OEP, 并 dump 程序。
技巧:
1、打开程序按 F8 单步向下, 尽量实现向下的 jmp 跳转
2、会经常遇到大的循环, 这时要多用 F4 来跳过循环
3、如果函数载入时不远处就是一个 call(近 call), 那么我们尽量不要直接跳过, 而是进入这个 call
4、一般跳转幅度大的 jmp 指令, 都极有可能是跳转到了原程序入口点 (OEP)
(0)练习exe下载
链接:https://pan.baidu.com/s/1Gf99jnR1XESBseoNp5n57w
提取码:mjeu
单步跟踪法 脱壳练习
(1)、查看源程序
检测有无壳
Aspack的压缩壳
IDA打开,看看IDA分析有壳的程序是什么样
(2)、单步跟踪法脱壳
【1】单步跟踪法脱壳口诀
- 打开程序按 F8 单步向下, 尽量实现向下的 jmp 跳转
- 会经常遇到大的循环, 这时要多用 F4 来跳过循环
- 如果函数载入时不远处就是一个 call(近 call), 那么我们尽量不要直接跳过, 而是进入这个 call
- 一般跳转幅度大的 jmp 指令, 都极有可能是跳转到了原程序入口点 (OEP)
【2】OD载入脱壳
[1]遇到近call
进来后直接遇到近call
f7步入之后,f8执行
f8执行到近call,f7步入
步入之后是这样,没有发现近call,放心f8
[2]遇到跳转指令
f8的过程中一定要注意跳转指令(jmp,je,jne,jz,jb等待)
跳转指令 尽量是向下跳转的,
如果遇到向上跳转,则选中下一行代码,按f4执行到指针处,
下面遇到了一个向上跳转的指令,(技巧)
又遇到向上跳转,和上面一样的方法
然后就是一直f8,遇到向上跳转则重复上面的方式。
题外话:遇到一个popad
又继续f8…………
[3]似乎来到OEP
直到到这里,下面的结构就很像程序真正的入口函数,猜测这里就是OEP
[4]验证该处是否为OEP
先假设上述地址0x4010cc
就是程序OEP,所以在那里dump出来
右键->dump
先获取当前EIP作为OEP,再dump文件出来
文件名默认为原名_dump.exe
验证猜测
用IDA打开我们dump出来的文件
根据以上两点,则猜测验证完毕,
单步脱壳法完成
【3】IDA分析主函数,缺少函数名
对比上一张IDA打开的图
【4】无法启动脱壳后的程序
综上所述,还要还原IAT表
(3)、还原IAT表
ImportREC1.7下载链接
链接:https://pan.baidu.com/s/1ztQybt9saucXHk22-majgQ
提取码:2k6v
打开ImportREC.exe ,
运行原程序,(未脱壳的版本能运行)。
在ImportREC.exe里附加活动进程为原程序。
更改OEP为我们新找到的OEP(主要要减去ImageBase(基值)400000)
然后点击自动搜索
然后点击获取输入表
再点击修复转存文件
选取先前dump出来的文件,完成后,会生成一个新的文件原名_dump_.exe
(4)、最后测试
点击运行NotePad_dump_.exe
,发现能正常运行了
然后用IDA分析这个文件,API函数名也能正常显现了
完成单步跟踪法脱壳+IAT修复
2、ESP定律
(#)方法介绍
ESP 定律法是脱壳的利器, 是应用频率最高的脱壳方法之一。
由于在程序自解密或者自解压过程中, 不少壳会先将当前寄存器状态压栈,如使用pushad, 在解压结束后, 会将之前的寄存器值出栈,如使用popad。
因此在寄存器出栈时, 往往程序代码被恢复, 此时硬件断点触发. 然后在程序当前位置, 只需要少许单步操作, 就很容易到达正确的 OEP 位置。
- 程序刚载入开始 pushad/pushfd
- 将全部寄存器压栈后就设对 ESP
- 寄存器设硬件断点
- 运行程序, 触发断点
- 删除硬件断点开始分析
- 找到OEP,dump程序
(0)练习exe下载
链接:https://pan.baidu.com/s/10F7z2L_ne4MD59o9bHfjVA
提取码:xs9d
ESP定律脱壳练习
由于是一样的程序,前面单步跟踪法
已经讲了完整脱壳过程,我这里就直接记录重点。
开头结尾略去。
(1)载入OD
看见第一条指令便是pushad指令。
(2)下硬件断点
f8执行一步,发现esp发生变化,右键点击esp,选择数据窗口中跟随
下硬件访问断点
(3)再f9执行来到硬件访问断点
f9之后,来到这里
查看前一行代码,很显然是popad
(4)f8单步执行寻找OEP结构
下来之后,f8单步执行,仔细看,注意跳转
几步之后,就跳到了这里
所以也是猜测地址0x4010CC
是OEP
(5)假设OEP,dump文件
假设地址0x4010CC
是OEP
同样的方式dump文件,主要要先点击Get EIP as OEP
(6)验证假设
IDA打开dump文件
假设验证成功
但很显然,dump程序也不能执行,
所以是没有恢复IAT表
(7)、恢复IAT表
一样的程序,前面单步脱壳法
已经记录了,这里就不再赘述!
3、一步到达OEP法
(#)方法介绍
**简介:**所谓的一步到达 OEP 的脱壳方法, 是根据所脱壳的特征, 寻找其距离 OEP 最近的一处汇编指令, 然后下 int3 断点, 在程序走到 OEP 的时候 dump 程序.(比如常见脱壳特征:popad)
如一些压缩壳往往 popad 指令距离 OEP 或者大 jmp 特别近, 因此使用 Ollydbg 的搜索功能, 可以搜索壳的特征汇编代码, 达到一步断点到达 OEP 的效果。
以OD调试为例
- ctrl+f 查找 popad
- ctrl+l 跳转到下一个匹配处
- 找到匹配处, 确认是壳解压完毕即将跳转到 OEP 部分, 则设下断点运行到该处
不过这只适用于极少数压缩壳
(0)练习exe下载
链接:https://pan.baidu.com/s/1mEoJwJKUJxUp4HErF4NTSA
提取码:p465
(1)脱壳记录
OllyDbg载入Notepad.exe
直接按Ctrl+F搜索popad
我们需要找的popad需要满足,是在程序最后返回时,壳程序希望恢复现场环境的地方
也就是靠近jmp,或retn的地方
直接搜索popad,显示出的几个结果,都不太符合标准
我们按Ctrl+L,查看下一个搜索目标。
在0040D3AF位置处我们发现这样一个popad
0040D3AF 61 popad
0040D3B0 75 08 jnz short NotePad.0040D3BA
0040D3B2 B8 01000000 mov eax,0x1
0040D3B7 C2 0C00 retn 0xC
0040D3BA 68 00000000 push 0x0
0040D3BF C3 retn
离跳转和retn很接近,我们变可以尝试这个popad,按F4运行到此处,继续F8单步向下
在retn后返回到OEP,使用Ollydump脱壳,然后一样的重建IAT即可
但是你要注意,这个方法只能用于极小部分情况。很多壳是不会直接使用popad这样的指令的
4、脱壳机练习(upx)
(#)方法介绍
就是直接傻瓜式一键操作
(0)练习exe下载
链接:https://pan.baidu.com/s/1s319A3-XPCnmqJ-ffTg7fA
提取码:vn4w
(1)脱壳记录
脱壳机安装
https://upx.github.io/
脱壳指令:
upx -d “脱壳程序”
5、总结
多动手操作,印象跟深刻!
参考文章:ctf-wick:脱壳技术