一. Kkrunchy介绍
KKrunchy属于压缩壳,常用于恶意代码的压缩保护。
KKrunchy [1] is a small executable packer intended for 64k intros. It does not try to pack DLLs and cannot handle exports or TLS. It performs a transform on the input code to allow it to compress better. It will fill uninitialized data sections with zeros and then pack them together with the rest of the code. KKrunchy is often used by malware authors to prevent AV analysts from reversing their code.
二. 脱壳思路
-
In order to unpack KKrunchy, put a break point on LoadLibraryA. When the break point triggers, step the debugger and search for the initialization of the stack frame. Once the stack frame initialization is complete, dump the debugged process. The dumped process is the unpacked version of the executable.
其实就是API断点的方法,通过在重要API上下断点,找到外壳程序载入DLL和导入函数的位置,来查找OEP的位置。
-
ESP脱壳定理方法:使用寄存器状态恢复的原理,开始时外壳程序会将寄存器push入栈进行保存,然后当外壳程序执行完毕准备回到主程序前会将寄存器pop出栈恢复,在这里断住后再通过单步步入找到OEP。
三. 背景知识
1. 断点API函数
-
LoadLibraryA函数
HMODULE LoadLibraryA( [in] LPCSTR lpLibFileName ); //将指定的模块加载到调用进程的地址空间中。
-
GetProcAddress函数
FARPROC GetProcAddress( [in] HMODULE hModule, [in] LPCSTR lpProcName ); /* [in] hModule 包含函数或变量的 DLL 模块的句柄。 LoadLibrary、LoadLibraryEx、LoadPackagedLibrary 或 GetModuleHandle 函数返回此句柄。 GetProcAddress 函数不会从使用 LOAD_LIBRARY_AS_DATAFILE 标志加载的模块中检索地址。 有关详细信息,请参阅 LoadLibraryEx。 [in] lpProcName 函数或变量名称, */
2.如何使用X_dbg当中的Scylla进行脱壳和IAT修复操作
DUMP文件
注意,dump时需要填写正确的原始OEP地址,然后点击Dump按钮保存文件。
保存完毕之后,最后就是修复文件了。
使用x64dbg脱壳之修复文件
修复文件,本质上就是修复IAT,所以还是使用插件Scylla,先对当前程序的IAT进行扫描,如果能找到就可以使用工具修复,不能就需要手动修复。
为了能更好的获取IAT,我们需要对插件Scylla进行设置。
- 打开设置
- 设置高级扫描
- 查找IAT
- 获取导入表
- 修复上一节的dump文件
四. 脱壳步骤
使用ESP脱壳定律脱壳,通过Scylla修复
-
找到改变ESP寄存器内容的位置,下硬件访问断点
-
F9运行,在相应断点处断下
开始向下F8加F4查找OEP所在位置,始终向下执行,遇上向上跳转的指令越过即可。 -
顺利找到OEP,再使用Scylla进行DUMP修复,得到脱壳后的文件。
-
使用IDA载入,文件成功脱壳。
五. 参考文章
- Virus Bulletin :: Quick reference for manual unpacking
- 006 kkrunchy_Ryd之类FSG压缩壳 (csdn.net)
- 使用x64dbg脱壳之开源壳upx - 知乎 (zhihu.com)
- 微软官方文档![]