Shark恒 发表于 2015-1-20 17:25

使用OllyDbg从零开始Cracking 第四十五章-ReCrypt v0.80脱壳

                      第四十五章-ReCrypt v0.80脱壳本章我们一起来分析一个用OllyDbg比较难脱的壳,这款壳就算我们配置好隐藏插件程序也无法正常运行,会弹出一个错误框。(PS:其实用海风月影大哥的StrongOD插件就可以完美解决,但是,04年的时候StrongOD还没有出来,啧啧!!!)。其实用别的调试器也可以搞定,但是我们整个教程的核心是OllyDbg,所以这里我们还是用OllyDbg来进行调试,嘿嘿。我们的实验程序名称叫做UnPackMe_ReCrypt0.80。这个程序的反调试比较强力(PS:当时算比较强力,现在不算什么了)。我们首先不加载调试器直接运行该程序。好,程序运行起来了,但是大家细心的话会发现一个比较蛋疼的问题,这个程序的CPU占用率居然高达99%。我们一起来看看它做了哪些手脚。我们打开OllyDbg,选择菜单项File -> Attach,打开可以附加的进程列表。我们可以看到无法正常加载。好,那么我们就用前面章节介绍过的专门用于定位OEP的OllyDbg或者Patched 5这个OllyDbg来打开它。我们可以看到弹出了一个错误框提示无效的PE文件,这里我们单击Aceptar(西班牙语译为:接受,这里译为确定)按钮。断在了系统断点处,我们直接运行起来。又弹出了一个错误框。好,那么我们重启OD,再次断在了Sytem startup breakpoint(系统断点)处,现在我们单击工具栏上的M按钮打开区段列表窗口。这里我们可以看到主模块仅仅只有一个区段,所以刚刚加载的时候弹出的那个无效PE格式的错误框是由于修改了原程序PE头中NumberOfRvaAndSizes(数据目录结构数组的项数)字段导致的。接下来我们对该区段设置内存访问断点,大家应该还记得Patched 5这款OD吧,前面章节我们介绍过,这款OD是打过补丁的,其内存访问断点仅仅在执行代码的时候才会断下来,读取或者写入并不会断下来,这样对于我们定位OEP非常有帮助。运行起来。断在了405000地址处,好,现在我们删除内存访问断点,接着直接运行起来。我们可以看到还是弹出了错误框。好,那么我们来看看PE头中NumberOfRvaAndSizes(数据目录结构数组的项数)字段的值是多少。我们在数据窗口中单击鼠标右键选择Go to-Expression,输入400000(主模块基地址)。接着还是单击鼠标右键选择Special-PE header切换到PE结构解析模式。往下拉,定位到NumberOfRvaAndSizes字段。我们可以看到该字段的值是7A0B5FD9(PS:数据目录结构数组项数怎么可能会这么大,明显被做了手脚),通常情况下该字段的值为0x10,好,这里我们把字段的值修改为0x10,看看会发生什么。接下来我们在选中该字段,单击鼠标右键选择Copy to executable file尝试将所做的修改保存到文件。我们可以看到报错了,无法在可执行文件中定位到该数据。好那我们尝试用十六进制编辑器来修改吧。(PS:这里使用的十六进制编辑器是UltraEdit,当然你也可以使用其他十六进制编辑器,比如WinHex)。这里我们定位到0xB4偏移处,也就是NumberOfRvaAndSizes字段处,就该字段的值修改为0x10。接着将所做的修改保存到文件。这里我将修改过的文件重命名为了UnPackMe_ReCrypt0.80 b.exe。我们可以看到用OD加载修改过的UnPackMe_ReCrypt0.80 b.exe,正常的断在了入口点处。说明这一处反调试我们的修复是正确的,接下来我们直接运行起来。依然报错。那么我们尝试将NumberOfRvaAndSizes字段的值还原看看能不能正常运行。好,这里NumberOfRvaAndSizes的值我们已经还原了,运行起来。很明显有什么地方我们没有绕过。提示正在访问一个不存在的区段地址,OD无法继续运行。这里常规思路是行不通的,我们需要一点奇招。大家需要做的就是:琢磨琢磨琢磨嘿嘿多思考思考好了,下面我就来给大家介绍一些思路,这里并不是每一种思路都能奏效,但是你需要熟悉这些思路,因为以后经常会碰到。下面打开Patched 5这款OD,选择主菜单项中的Option-Just-in-time debugging,将其设置为即时调试。(Just-in-time debugging)即时调试:(PS:这个功能大家应该不会陌生吧)当有程序崩溃的时候,OD就会自动附加上该程序。我们单击Make OllyDbg just-in-time debugger(将OD设置为即时调试器)按钮。如果以后你不想OllyDbg作为即时调试器的话,可以单击Restore old just-in-time debugger(恢复原来的即时调试器)按钮。因为每当应用程序崩溃,就被OD附加上是很烦的。现在我们关闭OD,修改了NumberOfRvaAndSizes字段的UnPackMe_ReCrypt0.80 b.exe暂时不用了,因为修改NumberOfRvaAndSizes并不起作用,我们选中原程序UnPackMe_ReCrypt0.80.exe,单击鼠标右键。我们可以看到系统右键菜单上有个选项Break’n’Enter(LordPE)。这个选项的作用是给指定的应用程序入口点处设置一个INT 3断点,直接运行该程序就会崩溃,然后即时调试器就会附加之,方便我们的调试。(PS:如果大家没有配置LordPE的话,系统菜单是不会出现Break’n’Enter(LordPE)以及Load into PE editor(LordPE)这两个菜单项的)。大家做如下配置就可以出现以上两个菜单项了。打开LordPE主程序。我们可以看到LordPE主界面中有Break & Enter这么一个按钮。这个跟系统菜单项Break’n’Enter(LordPE)的作用是一样的。下面我们单击Options按钮对LordPE进行配置。这里我们勾选上PEEditor以及Break & Enter分组中的Register shell extension选项就可。单击OK按钮。然后单击LordPE主界面中的Exit按钮退出。LordPE的目录下就会生成一个名为LordPE.iNi的配置文件。大家在选中UnpackMe_Recrypt 0.80.exe,单击鼠标右键,看看是不是多了两个菜单项,嘿嘿。我们单击Break’n’Enter(LordPE)菜单项。我们单击确定按钮。OD立马附加上了该程序,我们可以看到入口点处的第一个字节被LordPE修改为了INT 3指令。我们将INT 3恢复为PUSHAD指令。运行起来。还是报这个错误。那我们只能一步步来跟踪咯,看看它都做了什么。我们用PEEditor打开UnpackMe_Recrypt 0.80.exe文件。我们单击sections按钮查看一下区段。我们可以看到通过PEEditor可以完美的查看各个区段。现在我产生了一个想法:希望这个想法可以奏效,嘿嘿。首先我们对这个程序具体情况一无所知。那我们就考虑一下常规情况的吧,一般来说,针对于该程序大部分壳会从401000地址处开始解密区段。我们可以尝试修改某些区段的访问权限,比如说我们去掉某个区段的可写权限。当壳尝试写入该区段的话,就会报错,此时我们之前设置Patched 5这个即时调试器就能派上用场了。我们一起来试一试吧。我们可以从第一个区段开始尝试,但是考虑到壳解密区段过程中会将IAT的中一些API函数地址写入到.rdata这个区段中(也就是紧随其后的一个区段),所以这里我们首先尝试.rdata这个区段,如果.rdata不起作用的话,我们再来尝试第一个区段。这里单击右下角的char.wizard按钮打开向导页面修改该区段的访问权限。这里我们去掉writeable(可写)复选框上的对勾。单击右上方的take it(确定)按钮。这里我们可以看到.rdata这个区段的访问权限已经修改成功了。有可能壳的作者会在运行时调用VirutalProtect之类的API函数将各个区段的访问权限修改回去。没有关系,我们还是来看看先。这里我们直接双击运行已经被修改区段访问权限的UnpackMe_Recrypt 0.80.exe。即时调试器Patched 5立马启动了。断在了这里,该指令尝试将MessageBoxA这个API函数的地址保存到.rdata这个区段对应的地址空间中(嘿嘿,说明我的猜想是正确的)。由于我们刚刚以前去掉了.rdata段的可写属性,说明当执行到该指令时,程序就会发生异常崩溃,即时调试器OD就会自动附加之。好,我们继续。下面我们需要手工将该区段的访问属性修改回去,让其能够对该区段进行正常的写入。这里我们可以看到OD仅仅显示了一个区段,我们刚刚在PEditor中看到显示的是5个区段,没有关系。我们直接在该区段上单击鼠标右键选择Full access,给该区段赋予所有权限。接下来我们单击F7单步试试,看看能不能执行该指令。(PS:存在两种情况,情形1:该指令成功执行 情形2:报错)嘿嘿,我们可以看到执行功能执行了,并没有报错。由于OD中只显示了一个区段,看起来不是很方便,我们还是来看看PEEditor中的区段排列情况。我们可以看到第一个区段(.text)相对虚拟地址是0x1000,并且Virutal Size也是0x1000,所以下面一个区段.rdata起始地址应该是0x402000,也就是说我们修改的是虚拟地址范围为0x402000~0x403000对应的区段的访问属性,嘿嘿。如果我们在反汇编窗口中定位到0x401000这个地址,可以看到区段已经解密完毕了。这里我们不要盲目的对OD中显示的唯一的那一个区段设置内存访问断点,OD这里对区段的解析是有误的。这里我们在数据窗口中定位到0x401000~0x402000这一块内存地址,这块内存单元正好对应的就是.text段。我们选中这块内存单元,给其设置内存访问断点。这里我们选中0x401000地址处的第一个字节,按住鼠标左键不放,将鼠标往下拖,直到选中0x401000~0x402000整个范围位置。接着单击鼠标右键选择Breakpoint-Memory,on access。运行起来。这里我们可以看到断在了401000地址处,也就是OEP处。好了,最困难的一步我们已经迈过了,下面我们打开OllyDump对该程序进行dump。这里我们去掉Rebuild Import前面的对勾,不使用OllyDump来修复导入表。仅仅用它来dump。下面我们来定位IMP REC重建IAT所需要的数据。这里我们就拿OEP下方的GetModuleHandleA这个API函数的调用处来说吧。这里我们在该指令上单击回车键或者单击鼠标右键选择Follow跟进。可以看到我们很容易的就定位到了IAT。很明显这几项都没有被重定位过。例如:GetModuleHandleA这个API函数对应的项值是0x402000,很显然是属于IAT的。我们在数据窗口中定位到IAT。可以看到该程序的IAT很小。IAT的起始地址为0x402000,结束地址为0x40201C,所以IAT的长度的为0x1C。下面我们打开IMP REC将IAT的信息填充进去。IAT起始地址(RVA):0x2000IAT大小:0x1COEP(RVA):0x1000这里我们将OEP,IAT的起始地址以及大小填充到IMP REC中。接着单击Get Imports按钮。我们可以看到获取的IAT项都是有效的,啧啧!!!接下来单击Fix Dump修复刚刚我们dump出来的文件。修复完毕以后直接运行起来,可以看到报错了。我们将其拖拽到LordPE中的Rebuild PE按钮上,这样就可以重建PE了。重建PE完毕,直接运行起来,嘿嘿,完美运行。看来我们的剑走偏锋还是有所成效的。总结:大部分壳的加密思路都是有共同之处的,但是有些壳会玩一些花招来抵御常规的脱壳思路,剑走偏锋往往能收到奇效,嘿嘿。
本系列文章汉化版转载看雪论坛
感谢原作者:RicardoNarvaja(西班牙人) 原作者个人主页:http://www.ricardonarvaja.info/
感谢热心翻译的朋友:1~3章译者:BGCoder4~58章译者:安于此生
全集配套程序下载地址:
链接: http://pan.baidu.com/s/1eQzTWfo 密码: vytv



亚轩 发表于 2015-1-20 17:59

hackysh 发表于 2022-2-9 17:42


[快捷回复]-感谢楼主热心分享!

bnjzzheng 发表于 2022-2-26 16:08


[快捷回复]-感谢楼主热心分享!

别管我了行 发表于 2022-3-2 03:59

zg2600 发表于 2022-7-26 10:37

[吾爱汇编论坛52HB.COM]-楼主分享不易,顶帖是必须的

曾经沧海 发表于 2022-10-31 19:54

感谢分享。正在试用。

风动鸣 发表于 2022-10-31 21:50

感谢分享

曾经沧海 发表于 2022-11-20 19:34

感谢,正好有需要,非常感谢~

曾经沧海 发表于 2023-4-5 23:24

可以可以,学到了。
页: [1] 2
查看完整版本: 第四十五章-ReCrypt v0.80脱壳