逆向基础:软件手动脱壳技术入门

前言:
大家好,我是周杰伦
这里整合了一下之前自己学习软件手工脱壳的一些笔记和脱文,希望能给新学软件逆向和脱壳的童鞋们一点帮助 。
1 一些概念 1.1 加壳
加壳的全称应该是可执行程序资源压缩,是保护文件的常用手段 。加壳过的程序可以直接运行,但是不能查看源代码 。要经过脱壳才可以查看源代码 。
加壳是利用特殊的算法,对EXE、DLL文件里的资源进行压缩、加密 。类似 的效果,只不过这个压缩之后的文件,可以独立运行,解压过程完全隐蔽,都在内存中完成 。它们附加在原程序上通过加载器载入内存后,先于原始程序执行,得到控制权,执行过程中对原始程序进行解密、还原,还原完成后再把控制权交还给原始程序,执行原来的代码部分 。加上外壳后,原始程序代码在磁盘文件中一般是以加密后的形式存在的,只在执行时在内存中还原,这样就可以比较有效地防止破解者对程序文件的非法修改,同时也可以防止程序被静态反编译 。
壳的类型通常分为压缩壳和加密壳两类 。压缩壳的特点是减小软件体积大小,加密保护不是重点 。加密壳种类比较多,不同的壳侧重点不同,一些壳单纯保护程序,另一些壳提供额外的功能,如提供注册机制、使用次数、时间限制等 。
1.2 OEP
OEP:( Entry Point),程序的入口点 。软件加壳一般隐藏了程序真实的OEP(或者用了假的OEP), 我们需要寻找程序真正的OEP,才可以完成脱壳 。
一般加壳程序在使用等动态调试工具时,会停在壳的预处理块 。即处在对于程序原始代码块的解压或解密操作之前,在运行完程序自脱壳模块后,会停留在程序加壳之前的OEP位置,此时是dump程序的最佳时期 。脱壳时在真实OEP处下int3断点,就可以捕捉到程序代码段完全恢复的状态 。因此,寻找加壳程序的正确OEP,也成了手动脱壳时的第一要务 。
1.3 IAT
IAT:(Table),导入地址表 。由于导入函数就是被程序调用但其执行代码又不在程序中的函数,这些函数的代码位于一个或者多个DLL中 。当PE文件被装入内存的时候,装载器才将DLL 装入,并将调用导入函数的指令和函数实际所处的地址联系起来(动态连接),这操作就需要导入表完成 。其中导入地址表就指示函数实际地址 。多数加壳软件在运行时会重建导入地址表,因此获取加壳程序正确的导入地址表也是手动脱壳操作中的一个关键问题 。
2 一些脱壳方法 2.1单步跟踪法
单步跟踪法的原理就是通过的单步(F8)、单步进入(F7)和运行到(F4)功能,完整走过程序的自脱壳过程,跳过一些循环恢复代码的片段,并用单步进入确保程序不会略过OEP 。这样可以在软件自动脱壳模块运行完毕后,到达OEP,并dump程序 。
2.2 ESP定律法
ESP定律法是脱壳的利器,是应用频率最高的脱壳方法之一 。
ESP定律的原理在于程序中堆栈平衡的合理利用 。由于在程序自解密或者自解压过程中,不少壳会先将当前寄存器内容压栈,如使用,在解压结束后,会将之前的寄存器值出栈,如使用popad 。因此在寄存器出栈时,往往程序代码被自动恢复,此时硬件断点触发 。然后在程序当前位置,只需要少许单步跟踪,就很容易到达正确的OEP位置 。
2.3内存镜像法(二次断点法)
内存镜像法是在加壳程序被加载时,通过OD的ALT+M快捷键,进入到程序虚拟内存区段 。然后通过加两次内存一次性断点,到达程序正确OEP的位置 。
内存镜像法的原理在于对于程序资源段和代码段下断点,一般程序自解压或者自解密时,会首先访问资源段获取所需资源,然后在自动脱壳完成后,转回程序代码段 。这时候下内存一次性断点,程序就会停在OEP处 。