加脱壳学习
结合《加密与解密》进行学习
壳
加壳的全称是可执行程序资源压缩,是保护文件的常用手段。加壳过的程序可以直接运行,但是不能查看源代码。要经过脱壳才可以查看源代码。
加壳是利用特殊的算法,对EXE、DLL文件里的资源进行压缩、加密。类似WINZIP 的效果,只不过这个压缩之后的文件,可以独立运行,解压过程完全隐蔽,都在内存中完成。它们附加在原程序上通过Windows加载器载入内存后,先于原始程序执行,得到控制权,执行过程中对原始程序进行解密、还原,还原完成后再把控制权交还给原始程序,执行原来的代码部分。加上外壳后,原始程序代码在磁盘文件中一般是以加密后的形式存在的,只在执行时在内存中还原,这样就可以比较有效地防止破解者对程序文件的非法修改,同时也可以防止程序被静态反编译。
OEP:(Original Entry Point),程序的入口点。软件加壳一般隐藏了程序真实的OEP(或者用了假的OEP), 我们需要寻找程序真正的OEP,才可以完成脱壳。
什么是IAT
IAT:(Import Address Table),导入地址表。由于导入函数就是被程序调用但其执行代码又不在程序中的函数,这些函数的代码位于一个或者多个DLL中。当PE文件被装入内存的时候,Windows装载器才将DLL 装入,并将调用导入函数的指令和函数实际所处的地址联系起来(动态连接),这操作就需要导入表完成。其中导入地址表就指示函数实际地址。 多数加壳软件在运行时会重建导入地址表,因此获取加壳程序正确的导入地址表也是手动脱壳操作中的一个关键问题。
脱壳方法
1 单步跟踪法
单步跟踪法的原理就是通过Ollydbg的单步(F8)、单步进入(F7)和运行到(F4)功能,完整走过程序的自脱壳过程,跳过一些循环恢复代码的片段,并用单步进入确保程序不会略过OEP。这样可以在软件自动脱壳模块运行完毕后,到达OEP,并dump程序。
2 ESP定律法
ESP定律法是脱壳的利器,是应用频率最高的脱壳方法之一。
ESP定律的原理在于程序中堆栈平衡的合理利用。由于在程序自解密或者自解压过程中,不少壳会先将当前寄存器内容压栈,如使用pushad,在解压结束后,会将之前的寄存器值出栈,如使用popad。因此在寄存器出栈时,往往程序代码被自动恢复,此时硬件断点触发。然后在程序当前位置,只需要少许单步跟踪,就很容易到达正确的OEP位置。
在外壳代码中有一个pushad的指令,该指令会将所有的寄存器的值都压入栈中也就是说在pushad指令之后esp的值就是指向外壳的代码段了,等之后运行完外壳程序,我们只要找到OEP就可以了
3 内存镜像法(二次断点法)
内存镜像法是在加壳程序被加载时,通过OD的ALT+M快捷键,进入到程序虚拟内存区段。然后通过加两次内存一次性断点,到达程序正确OEP的位置。
内存镜像法的原理在于对于程序资源段和代码段下断点,一般程序自解压或者自解密时,会首先访问资源段获取所需资源,然后在自动脱壳完成后,转回程序代码段。这时候下内存一次性断点,程序就会停在OEP处。
结合buuctf 新年快乐
尝试手动脱壳,因为自动脱壳有手就行
用x32dbg打开 程序
查看断点
在其中找到pushad的断点,并将其设置为新的eip
尝试步过,检查esp保存的地址,在内存中找到其位置
在这里设置断点,然后运行
找到一个jmp 到新年快乐.401280
这就是oep 通过scylla 尝试更改输出,
将00401280写入oep后生成新年快乐_dump.exe 接下来用ida pro查看便可知道
虽然一些函数名缺失,但能够分辩这个sub401B98是strcmp
得出flag{HappyNewYear!}
花指令
花指令的介绍
花指令(JunkCode)指的是使用一些技巧将代码复杂化,使人难以阅读的技术。广义上花指令与代码混淆(ObfusedCode)同义,包括结构混淆、分支混淆、语句膨胀等等
狭义上指的主要是干扰反汇编解析的技术。
花指令的原理
本质
- 反汇编器无法维护执行上下文,只能静态分析
- x86指令集是不定长指令集,每条指令的长度不确定。
结合Maze进行学习
直接打开,发现只有一个函数,推测有upx壳,脱壳后再打开发现
这里可以注意到jnz到了call这个位置,然后call下面一眼顶针判断为代码没有分析出来,将call这一行尝试d
这时候发现说jnz跳转到了unk_40102F位置,推测为0E8为多余的指令,将除开0E8的部分转换为代码后再将main函数选中p,生成主函数
虽然存在JUMPOUT情况,但主题逻辑可以分析
主要逻辑为走迷宫 可以再字符串中找到迷宫
提取后分析得出
flag{ssaaasaassdddw}