大家好,欢迎来到IT知识分享网。
脱壳
保护壳简介 – CTF Wiki (ctf-wiki.org)
什么是壳
为了防止程序被非法修改或反编译,开发人员通常会在二程序中加入一段如同保护层的代码,使得原程序代码失去了原本的面目,这段如同保护层的代码和自然界的壳在功能上十分相近,因此把这样的程序称之为“壳”。壳一般都是先于程序运行,拿到控制权,然后完成它们保护软件的任务。
壳的种类
- 压缩壳:最常见的类型,主要目的是压缩文件减少存储空间的占用
- 加密壳:对文件进行了加密,以增加对恶意软件攻击的防御能力
- 混淆壳:通过混淆代码来增加防御能力
- 虚拟机壳:使用虚拟机技术来保护代码
常用脱壳方法
1.工具脱壳
对于简单,常见的壳,可以使用 ExeinfoPE 识别壳的类型,然后用对应的脱壳工具直接进行脱壳
常用脱壳工具:Free UPX,UPX Unpacker 等。
比如这个 32 位可执行程序用的壳是 UPX (UPX 全称是 “Ultimate Packer for eXecutables”,是一个免费、开源、编写、可扩展、高性能的可执行程序打包程序。换句话说一个可执行文件的压缩工具。)
用 ida 打开明显不对,就两个函数
打开 freeupx 脱壳处理
再重新 ida 加载X
2.单步跟踪法
单步跟踪法的原理就是通过 Ollydbg 的步过 (F8), 步入(F7) 和运行到 (F4) 功能, 完整走过程序的自脱壳过程, 跳过一些循环恢复代码的片段, 并用单步进入确保程序不会略过 OEP.(EP 是程序入口点,OEP 是原程序入口点,加壳会隐藏程序 EP,所以我们才要找到 程序 OEP) 这样可以在软件自动脱壳模块运行完毕后, 到达 OEP, 并 dump 程序.
- 打开程序按 F8 单步向下, 尽量实现向下的 jmp 跳转
- 会经常遇到大的循环, 这时要多用 F4 来跳过循环
- 如果函数载入时不远处就是一个 call(近 call), 那么我们尽量不要直接跳过, 而是进入这个 call
- 一般跳转幅度大的 jmp 指令, 都极有可能是跳转到了原程序入口点 (OEP)
直解分析 ctf-wiki 上给的例子,aspack 壳。
打开 od。入口点是一个pushad
保存所有寄存器状态到栈中,随后便是一个call
调用位于0040D00A
处的函数. 调用后便无条件跳转到459DD4F7
处, 之后的push ebp
和retn
显然没有任何意义. 像这种入口点附近就是一个call
的我们称为近call
, 对于近 call 我们选择步进, 按下 F7(当然你也只能选择步进, 不然 EIP 就跑偏程序停止了).
f7 步入发现又有一个近 call,再次步入这个 call
后面就没有近 call 了,我们选择 f8 步过,可以看到后面在调用 GetModuleHandleA, GetProcAddress等api
都是远 call,后面,f8 一直步过。在 004012D 到 0040D140 处有循环,我们直接选中 0040D142 然后 F4 跳过。
后面只要是看到让你往上跳你就 f4 跳过这个循环。直到0040D3AF
处, 我们看以下的代码
0040D3AF 61 popad 0040D3B0 75 08 jnz short NotePad.0040D3BA 0040D3B2 B8 0 mov eax,0x1 0040D3B7 C2 0C00 retn 0xC 0040D3BA 68 CC push NotePad.004010CC 0040D3BF C3 retn
这里popad
可以恢复在程序入口点处保存的寄存器状态, 然后jnz
跳转到0040D3BA
处, 这里是利用push
和retn
来将EIP
改变为004010CC
, 也就是说在壳解压完代码等资源完毕后, 将通过jnz
跳转到push
处, 然后通过push
和ret
将EIP
设置为程序原来的入口点 (OEP) 并返回到 OEP 处, 然后继续执行原程序的代码. 我们执行到retn
返回后, 可以看到如下:
怎么都变成单字节数据了?显然, 我们到了一堆被Ollydbg
误认为是数据的地方继续执行, 显然Ollydbg
分析错误了, 我们需要让Ollydbg
重新分析, 我们可以右键选择分析->从模块中删除分析
, 或是按下ctrl+a
, 这时正确地显示出 OEP 处的汇编指令.
这里直接右键用 ollydump 脱壳,保存。我们再看入口区段变成 txt,脱壳成功
3.ESP 命令脱壳
ESP 定律的原理在于利用程序中堆栈平衡来快速找到 OEP.
由于在程序自解密或者自解压过程中, 不少壳会先将当前寄存器状态压栈, 如使用pushad
, 在解压结束后, 会将之前的寄存器值出栈, 如使用popad
. 因此在寄存器出栈时, 往往程序代码被恢复, 此时硬件断点触发. 然后在程序当前位置, 只需要少许单步操作, 就很容易到达正确的 OEP 位置.
- 程序刚载入开始 pushad/pushfd
- 将全部寄存器压栈后就设对 ESP 寄存器设硬件断点
- 运行程序, 触发断点
- 删除硬件断点开始分析
我们先 f8 执行 pushad,保存寄存器状态,可以看到右边寄存器 ESP 仍为红色,选中 esp,右键选择HW break[ESP]
然后 f9 运行程序,可以看到程序跳转到了
0040D3B0 75 08 jnz short NotePad.0040D3BA
我们可以看到上面就是 popad,恢复寄存器状态。然后 f8 一直步过,直到一大跳来到 程序OEP 处。
然后 ollydump 脱壳即可
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/122304.html