关于c++:逆向基础软件手动脱壳技术入门

51次阅读

共计 4924 个字符,预计需要花费 13 分钟才能阅读完成。

前言:

大家好,我是周杰伦

这里整合了一下之前本人学习软件手工脱壳的一些笔记和脱文,心愿能给新学软件逆向和脱壳的童鞋们一点帮忙。

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 修复时,会呈现一个有效指针:

这里间接剪掉 (或者删掉) 这个指针,而后修复转存文件,发现无奈失常关上:

![在这里插入图片形容](https://img-blog.csdnimg.cn/6…
process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5Luj56CB54as5aSc5pWy,size_12,color_FFFFFF,t_70,g_se,x_16)

而后再把修复后的程序,丢到 OllyIce 中 F9 间接运行:

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

正文完
 0