前言:
大家好,我是周杰伦
这里整合了一下之前本人学习软件手工脱壳的一些笔记和脱文,心愿能给新学软件逆向和脱壳的童鞋们一点帮忙。
1 一些概念
1.1 加壳
加壳的全称应该是可执行程序资源压缩,是爱护文件的罕用伎俩。加壳过的程序能够间接运行,然而不能查看源代码。要通过脱壳才能够查看源代码。
加壳是利用非凡的算法,对EXE、DLL文件里的资源进行压缩、加密。相似WINZIP 的成果,只不过这个压缩之后的文件,能够独立运行,解压过程齐全荫蔽,都在内存中实现。它们附加在原程序上通过Windows加载器载入内存后,先于原始程序执行,失去控制权,执行过程中对原始程序进行解密、还原,还原实现后再把控制权交还给原始程序,执行原来的代码局部。加上外壳后,原始程序代码在磁盘文件中个别是以加密后的模式存在的,只在执行时在内存中还原,这样就能够比拟无效地避免破解者对程序文件的非法批改,同时也能够避免程序被动态反编译。
壳的类型通常分为压缩壳和加密壳两类。压缩壳的特点是减小软件体积大小,加密爱护不是重点。加密壳品种比拟多,不同的壳侧重点不同,一些壳单纯爱护程序,另一些壳提供额定的性能,如提供注册机制、应用次数、工夫限度等。
1.2 OEP
OEP:(Original Entry Point),程序的入口点。软件加壳个别暗藏了程序实在的OEP(或者用了假的OEP), 咱们须要寻找程序真正的OEP,才能够实现脱壳。
个别加壳程序在应用Ollydbg等动静调试工具时,会停在壳的预处理块。即处在对于程序原始代码块的解压或解密操作之前,在运行完程序自脱壳模块后,会停留在程序加壳之前的OEP地位,此时是dump程序的最佳时期。脱壳时在实在OEP处下int3断点,就能够捕捉到程序代码段完全恢复的状态。因而,寻找加壳程序的正确OEP,也成了手动脱壳时的第一要务。
1.3 IAT
IAT:(Import Address Table),导入地址表。因为导入函数就是被程序调用但其执行代码又不在程序中的函数,这些函数的代码位于一个或者多个DLL中。当PE文件被装入内存的时候,Windows装载器才将DLL 装入,并将调用导入函数的指令和函数理论所处的地址分割起来(动静连贯),这操作就须要导入表实现。其中导入地址表就批示函数理论地址。少数加壳软件在运行时会重建导入地址表,因而获取加壳程序正确的导入地址表也是手动脱壳操作中的一个关键问题。
2 一些脱壳办法
2.1单步跟踪法
单步跟踪法的原理就是通过Ollydbg的单步(F8)、单步进入(F7)和运行到(F4)性能,残缺走过程序的自脱壳过程,跳过一些循环复原代码的片段,并用单步进入确保程序不会略过OEP。这样能够在软件主动脱壳模块运行结束后,达到OEP,并dump程序。
2.2 ESP定律法
ESP定律法是脱壳的利器,是利用频率最高的脱壳办法之一。
ESP定律的原理在于程序中堆栈均衡的正当利用。因为在程序自解密或者自解压过程中,不少壳会先将以后寄存器内容压栈,如应用pushad,在解压完结后,会将之前的寄存器值出栈,如应用popad。因而在寄存器出栈时,往往程序代码被主动复原,此时硬件断点触发。而后在程序以后地位,只须要少许单步跟踪,就很容易达到正确的OEP地位。
2.3内存镜像法(二次断点法)
内存镜像法是在加壳程序被加载时,通过OD的ALT+M快捷键,进入到程序虚拟内存区段。而后通过加两次内存一次性断点,达到程序正确OEP的地位。
内存镜像法的原理在于对于程序资源段和代码段下断点,个别程序自解压或者自解密时,会首先拜访资源段获取所需资源,而后在主动脱壳实现后,转回程序代码段。这时候下内存一次性断点,程序就会停在OEP处。
2.4一步达到OEP
所谓的一步达到OEP的脱壳办法,是依据所脱壳的特色,寻找其间隔OEP最近的一处汇编指令,而后下int3断点,在程序走到OEP的时候dump程序。如一些压缩壳往往popad指令间隔OEP或者Magic Jump特地近,因而应用Ollydbg的搜寻性能,能够搜寻壳的特色汇编代码,达到一步断点达到OEP的成果。
2.5最初一次异样法
最初一次异样法的原理是,程序在自解压或自解密过程中,可能会触发无数次的异样。如果能定位到最初一次程序异样的地位,可能就会很靠近主动脱壳实现地位。当初最初一次异样法脱壳能够利用Ollydbg的异样计数器插件,先记录异样数目,而后从新载入,主动停在最初一次异样处。
2.6 模仿跟踪法
模仿跟踪法的原理就是应用Ollydbg下条件断点,SFX相当于是一个自解压段,在自解压段完结时(eip的值转到代码段时),曾经间隔OEP很近,然而这种跟踪办法会比拟耗时。
2.7 “SFX”法
“SFX”法利用了Ollydbg自带的OEP寻找性能,能够抉择间接让程序停在OD找到的OEP处,此时自解压曾经实现,能够间接dump程序。
3一些脱壳实际
上面给出整顿的应用以上办法,本人尝试手动脱这几种罕用壳的脱壳笔记。
3.1UPX脱壳笔记
首先进行侦壳:
首先把程序扔到OllyIce外面能够看到:
而后这里尝试应用ESP定理:即在ESP第一次扭转时,对ESP的地址设置硬件字拜访断点,这样能够在代码被UPX算法还原之后,跳转到程序的失常入口处。
而后F5运行,并没有间接到跳转到程序入口处的大跳地位,然而能够看到UPX的大跳就在眼前:
所以被还原后的程序入口点就是0x00445151(通过单步往下走,F4略过往回走的循环语句,也能够看到这个大跳的地位。)接下来走到大跳地位,跳到失常程序入口处:
而后去掉硬件断点,并应用LoadPE的dump性能dump目标程序:
先修改映像大小,而后再抉择残缺脱壳,这样能够失去第一步dump的程序,而后再应用ImportREC修复dump程序的OEP,OEP的信息通过OD自带的dump性能查问或者间接填45151:
将正确的入口地址填入ImportREC中,而后主动搜寻IAT信息:
而后点击获取输出表失去修改IAT之后的程序函数输出表,而后再点击显示有效函数,欢快地发现没有有效函数,那么就能够间接修复转存文件了。
抉择刚刚第一步dump下来的转储文件进行修复,修复实现之后脱壳实现:
这里对于压缩壳UPX,间接应用了ESP定律,能够很不便找到OEP并dump程序。
4.2 tElock脱壳笔记
这里脱的是一个tElock的壳:
1、先应用最简略的最初一次异样法:首先把程序扔到OllyIce外面设置OD调试选项中的异样选项,
仅保留内存非法拜访异样,而后应用异样计数器插件,在应用前要清空断点设置:
等到程序失常运行后,从新加载程序,再抉择第二步,停在最初一次异样之前:
而后用Alt+M转到内存窗口,对主程序code段下内存断点,SHIFT+F9执行:
这样程序就中断在了正确的OEP处,能够抉择从模块中删除剖析以显示失常剖析的汇编代码。而后应用LoadPE dump程序,并修改程序映像大小。然而在应用ImportREC v1.6F Fix版,输出正确的OEP,获取函数输出表信息时,会发现有效的指针。应用办法一修复后,再应用办法三能够齐全修复
再点击Fix dump,能够修复之前dump下来的程序,脱壳实现:
2、应用二次内存断点法:首先载入程序,将所有的异样类型疏忽,而后在idata段设置内存断点, 而后SHIFT+F9:
停下来后再次在code段设置内存断点,再次SHIFT+F9执行,能够间接达到正确的OEP中:
而后LoadPE dump,而后修复IAT。修复办法同办法1。
3、寻找magic jump以及修复函数表实现后dump程序:前两步还是加内存断点(idata、code),而后定位到程序的正确OEP处
而后如果这时应用LoadPE dump后修复,就和前两种一样了。这里先是应用ImportREC获取函数输出表第一个地位的指针地址。
而后失去函数指针偏移地址在0x005512C,加上基地址后为0x045512C,这时在该地位下硬件拜访双字断点。再从新SHIFT+F9疏忽异样执行后,因为下了断点,会触发tElock的CRC校验谬误:
所以这里要先绕过CRC校验,能力胜利执行到硬件断点地位,所以首先暂停程序,而后应用Alt+F9返回用户代码。点击确定按钮后,程序暂停在调用ExitProcess的地位:
当初要向上找一找能跳过这个退出的跳转(CRC判断跳转),而后进行批改并跳过:
找到了应该批改的地位,然而如果批改之后从新运行是会被复原的,所以先记下来这个跳转的地址,0x00469622。从新运行之后,在idata断设置内存断点,SHIFT+F9停下后,再Ctrl+G找到批改点再批改。批改完之后再设置之前的硬件断点,这样不会触发CRC校验谬误了。
无数次的SHIFT+F9之后,在寄存器窗口能够看到指针以及可能失常显示:
而后此时F8单步,找magic jump……看小生大大的视屏是通过剖析疑似CRC跳转失去magic jump的地位:
这里记下来magic jump的地址是0x0046973B,而后清空udd文件,删除硬件断点,再次从新运行程序,而后在idata下内存断点停住,而后Ctrl+G找到magic jump地位处,批改跳转:
而后在code段下内存断点:
而后SHIFT+F9执行,停下来就到了OEP的地位:
这时候再dump程序,IAT表曾经被修复,能够间接取得脱壳版程序:
这里尝试应用了另外两种脱壳办法,并且通过事后找OEP的形式,修复了CRC校验后,间接dump到了IAT被修复了的程序。
3.3 PEncrypt脱壳笔记
先把程序扔到OllyIce外面,而后程序停在这里,看起来蛮怪的:
好吧,从新加载程序,尝试应用最初一次异样法,不疏忽所有异样,而后应用异样计数器插件,程序停在最初一次异样处:
如果此时F8单步上来,程序会触发异样解决,而后又到不了OEP了。这时须要看一下堆栈数据状况:
这时须要在0040CCD7处F2下断点,而后SHIFT+F9执行,能够跳过这个坑:
而后接下来就是F8+F4的操作,一路直到OEP:
用LoadPE脱壳,而后用ImportREC修复后,尽管没有有效指针,然而还是不能运行:
这时候用LoadPE的重建PE性能:
而后就能够失常运行了:
这个壳应用了单步跟踪的脱壳办法,一路跳过程序“陷阱”,最初达到OEP。并且应用了LoadPE的重建PE性能,对程序进行了重建,最终实现了这个加密壳的脱壳全过程。
3.4 FSG变形壳脱壳笔记
首先进行侦壳:
应用ESP定律,首先把程序扔到OllyIce外面,F8单步走,察看ESP变动,在ESP第一次发生变化时,对ESP对应的地址处设置内存硬件拜访WORD断点,而后SHIFT+F9运行,在程序停下来之后,勾销硬件断点,进行F8单步:
用F4略过向后的跳转(循环),而后持续往下找,始终到这里:
在这个jmp上面F4,程序会跑飞。阐明程序代码在这个循环中就曾经开释结束,所以向上找找这个循环中有没有带条件的大跳。这样很容易找到magic jump的地位,而后咱们Enter或者Ctrl+G到00402666的地位,发现果然是OEP,从新剖析,而后F2下断点,让程序走到OEP:
如果是FSG1.33,间接应用LoadPE dump文件,而后应用ImportREC修复,就能够失常脱壳了。然而这里在应用ImportREC修复时,会呈现一个有效指针:
这里间接剪掉(或者删掉)这个指针,而后修复转存文件,发现无奈失常关上:

而后再把修复后的程序,丢到OllyIce中F9间接运行:
这里是变形壳增加的一个暗桩,会导致程序出现异常退出,这里间接nop掉或者把之前的jle(校验)改成jmp,而后保留批改另存文件。而后就能够运行了