壳的作用:保护程序不会被简单的反编译,或者进行压缩。
基本概念:OEP原始程序入口点。EP(Entry Point),意即程序的入口点。而OEP是程序的原始入口点,一个正常的程序只有EP,只有入口点被修改的程序(加壳等),才会拥有OEP。
DLL(Dynamic Link Library)文件为动态链接库文件,很多Windows可执行文件并不是一个可以完整执行的文件,而是被分割成了多个DLL文件。当我们执行一个文件的时候,对应的DLL文件就会被调用。
ITA(Import Address Table):导入地址表。在不同版本的Windows系统中DLL的版本不同,那么我们需要借助ITA,获取函数的真实地址。
PE:可以执行的文件。
压缩壳:使用数据压缩算法,例如zip。主要可以减少软件的体积大小常见的,压缩壳有UPX,ASPack,PECompact,RLPack,Nspack。
压缩壳的原理:将正常的pe文件压缩成数据,这时候我们的pe文件变成了一个新的pe程序,我们原本的pe程序变成了新程序节里的数据。当我们启动程序的时候壳里的解压缩程序启动,进行解压缩,然后将程序正常的映射到内存之中。
加密壳:单纯为了保护程序。类似与压缩壳。
upx -d脱壳方法:
最简单的就是进行upx -d命令 进行脱壳,但此种脱壳需要对upx特征码进行识别,我们只需要在winhex中将其简单的改变就会让这种脱壳方法失效。
进行修改后
发现脱壳失败。
脱壳机脱壳
一些脱壳机可以识别特征码被改变或被抹去的upx壳,但在od中修改upx特征可以将其改变到连ExEinfoPE都无法识别,这种脱壳方法也只能应对部分壳。
手动脱壳ESP定律脱壳
由于在程序自解密或者自解压过程中, 不少壳会先将当前寄存器状态压栈, 如使用pushad, 在解压结束后, 会将之前的寄存器值出栈, 如使用popad. 因此在寄存器出栈时, 往往程序代码被恢复, 此时硬件断点触发. 然后在程序当前位置, 只需要少许单步操作, 就很容易到达正确的OEP位置.
Ob打开我们的程序。
发现只要esp的值改变使用esp定律脱壳。去到esp的正确位置。
单步跳转后进行插件脱壳就可以了。
API定位脱壳
我们知道在入口点调用的api,直接在api处下断点就好。
单步方法寻找入口处,进行脱壳
单步步过程序,尝试寻找断点,一种情况是我们遇到循环时在循环的下一位下断点,直接运行程序就发现循环被跳过了,继续单步执行程序就可以找到oep。
一步直达
壳在执行完之后会跟一个跳转代码,直接跳转到oep处,我们可以直接搜索跳转指令的机器码来直接跟踪到程序的入口。
继续运行就可以跳转到oep了,如果没有成功找到入口可以尝试其他的跳转指令的机器码call:E8,jmp:E9。缺点是判断正确的跳转函数太浪费时间。
模拟跟踪法
需要ob的命令行插件,程序的ope一般位于第一个区块中,而加壳位于ope的后几个区块,定位壳代码的第一个地址。
在指令区输入top eic < 地址。直接运行程序自动到达oep处。壳代码与程序在同一区段中就无法使用此方法。
Sfx法很简单,直接使用ob自带的功能就可以。但ob要提前选择忽略所有异常。重启运行后会自动停在oep处。
最后一次异常法
壳之中可能会有很多异常来误导逆向手,我们寻找最后一次的异常,和上面相反,去掉所有忽略异常运行程序,我们运行程序,找到最后一次的异常点,之后按照常规方法寻找oep。
补:upx壳的去特征
看到一篇文章是教如何去特征的,在这里也写一下。最简单的直接在16进制编辑器中修改特征码。
可以骗过upx-d脱壳。
无法骗过ExEinfoPE。
Ob修改pushad为nop。
发现无法准确识别了,但仍旧猜测为upx壳。此时常规的杀毒软件已经不报错了。
在尾部改变其特征码。杀毒软件无法将其识别为upx壳。
Winhex覆盖以及修改pe头地址。
无法识别程序入口。