手动脱壳教程

时间:2024-04-12 18:16:35

一、什么是壳?
        壳是指在一个程序的外面再包裹上另一段代码,保护里面的代码不被非法修改或反编译的的程序。它们一般先于程序运行,拿到控制权,然后完成它们保护软件的任务。
二、壳的加载过程
1、保存程序入口参数
        加壳程序初始化时保存各个寄存器的值(用堆栈),外壳执行完毕后,再恢复各个寄存器的值,最后再跳到源程序执行。
2、获取壳自己所需要使用的API的地址
        通过三个函数完成:GetProcAddress、GetMoudleHandle和LoadLibrary.
3、解密原始程序各个区块的数据
        按区块进行解密,并且会把解密的区块数据按照区块的定义放在合适的内存位置中。
4、IAT初始化
        由于加壳时外壳程序自己构建了一个输入表,并让PE头文件中的输入表指针指向了自建的输入表。所以 ,PE装载器只会对自建的输入表进行填写。原来的PE的输入表的填写,只好由外壳程序来实现。外壳要做的就是将这个新的输入表结构从头到尾扫描一遍,对每个DLL所引入的所有函数重新获取地址,并填写在IAT中。
5、重定位项处理
        主要:是在被加壳的DLL文件中。针对加壳后的DLL文件,外壳程序需要进行重定位。
6、跳转到程序入口点(OEP)
        OEP原始入口点,当程序完成上述操作后,就会跳转到原始的程序入口点去执行,因此这里就是外壳程序和原始程序的“分界线”。我们进行脱壳时就是找到程序的原始入口点,然后将相应的程序代码从内存中拷贝出来(dump)得到原始程序。
三、手动脱壳步骤
        手动脱壳的常规步骤如下:
        (1)、查壳:可用查壳软件(如PEiD)
        (2)、查找程序的入口点
        (3)、抓取内存映像文件
        (4)、PE文件(输入表)重建
第一步:查壳
        可使用PEID、die等工具进行查壳,一般都支持拖放。
第二步,手动脱壳
        方法一:单步跟踪法(用F8、F7、F4),一直跟踪到程序大跳转时,开始dump内存。主要用于比较简单的壳。
        方法二:ESP定律法(根据堆栈平衡原理找OEP) ,这是因为外壳程序在开始运行时需要保护现场,结束后恢复现场,从而保持堆栈平衡。
        脱壳方式:在外壳执行完pushad或pushfd后,对ESP指向的内存地址设置硬件访问断点,然后F9运行程序,很快就可达OEP。演示如下:
        用PEiD查壳,发现壳的类型为ASPack 2.12

手动脱壳教程
用OD载入程序,用ESP定律法手动脱壳:
手动脱壳教程
然后看一下ESP的值,如第一幅图,为0012FF8C,F8单步跟踪,并注意ESP的值,直到发现ESP第一次发生变化(且只有它为红色),如第二幅图,ESP的值变为0012FF6C。
手动脱壳教程
手动脱壳教程
在ESP处右键,选择HW break选项 ,此时会下一个硬件断点,点击调试-》硬件断点可看到:
手动脱壳教程
手动脱壳教程
然后点击F9运行程序,再F8单步跟踪,直到虚拟地址有较大变化时,如下图:则很可能已经到达程序的OEP,不过发现代码分析出错。
手动脱壳教程

右键-》分析-》分析代码:强迫OD再次分析代码,得到下图所示,代码正常显示:
手动脱壳教程

然后便可以用OD的插件来进行脱壳,具体操作是:右键-》选中OllyDbg脱壳调试进程:
手动脱壳教程
然后保存文件:如脱壳.exe
手动脱壳教程
用PEiD查看程序:脱壳.exe,发现没壳,以及运行程序正常:说明脱壳成功。
手动脱壳教程
手动脱壳教程
方法三:利用内存访问断点找OEP。
        内存断点:就是通过将需要设置断点的内存页设置为不可访问属性,这样,当程序访问相关内存地址时就会发生异常,从而中断下来。一般分为内存访问和内存写入两种断点。(以页为单位)
        两次内存访问一次性断点法:通过两次内存断点的方式来找到OEP。
        在第一个.text段处设置断点,然后F9,运行,运行到断点之后F8单步跟踪,即可找到程序的真正入口点,然后脱壳。
方法四:根据编译语言寻找OEP。(查找函数,在函数前下断进行脱壳)
        函数调用:GetCommandLineA、GetModuleHandleA、GetVersion、GetStartupInfoA