Crimsonland 血腥大地 逆向无敌通关分析报告【配置文件加密】【Dll隐藏MD5检测补丁反调试函数】【反反调试】

 

一、工具及游戏介绍

 使用工具:Ollydbg,PEID,Beyond Compare,Cheat Engine

实现功能:无敌,全部通关。

 

Crimsonland 血腥大地

 

二、实现无敌:

 使用CE查找全局变量。

无敌成功。

 

 

三、通关:

1、文件对比

原始关卡: 

 

   

这里先采用上一篇文章的方法。

渡者方案2:通过文件资源管理器的时间排序,来找到最后修改的文件,确定配置文件。

游戏过关,并查看文件资源管理器。

 

   

替换未过关的game.cfg文件,发现关卡回到了之前,可以确定是game.cfg文件

这里保存了未过关的game.cfg game2.cfg

和 过关的 game3.cfg game4.cfg

 

   

进行两两对比。

game.cfg game2.cfg

 

   

game3.cfg game4.cfg

   

 

   

用010Editor查看。

经过两两比较并多重测试,确定跟关卡相关是这几个点,暂且叫做关卡数据点。

当 关卡数据点 或者 非关卡数据点 的数据改变时,后面方框内的两组数据都会变,且变化无规律。

个人猜测:两组数据类似于对文件的数据计算,类似于哈希值算法。

接下来只能动用OD了。

 2、OD调试

2.1、查壳

很可惜,没加壳。

以下PEID 和 OEP特征可验证无壳:

 

 

 

2.2、下断

先查找字符串,在调用字符串资源的地方下断。

再在一些文件操作函数下断。

 

   

   

首先在字符串资源地方断下。

并找到了 字符串拼接路径 函数。

 

 

   

 

 

 

猜测接下来调用CreateFile,果然。

 

 

2.3、追踪关键代码

栈回溯返回用户界面,查看文件句柄。

   

   

F9接下来是ReadFile

 

 

显而易见:

在游戏运行时 就已经读取文件game.cfg到内存了。

此时ReadFile的Buff是配置文件的缓冲区。

目标:从Buff下手,追踪修改数据的关键代码。

2.4、继续追踪

重复以上步骤,确认逻辑正确,现在句柄是0x190

   

   

   

在此块内存上设置内存访问断点

   

   

 对断下来的地方进行分析

 

   

   

retn出函数后,似乎进入了循环,但这里只执行一次,把缓冲区的首个字节拷到483220地址上。

暂且把483220处的内存命名为 缓冲区2

 

   

跳到的一个地方,往下执行,直到调用函数,拷贝完接下来的267个字节。 

 

   

往下分析,发现把存放 缓冲区缓冲区2地址都加到了末尾。

   

   

接下来,按道理来说:跟踪数据,查看数据头部是否被修改,数据尾部是否增加。

   

   

但这里 直接再下一次内存断点,这次往缓冲区2【483220】处下内存写入断点

断下的地方证明了猜想,执行指令 往存放 缓冲区2 地址加4,也就是说 缓冲区2 总共预定存放0x268+0x4 == 0x26C 个字节。

 

 

我们再看看配置文件字节数,正好是0x26C个字节,正好吻合

 

 

 2.5、锁定关键代码

再继续分析,真正进入了一个大循环,且不断循环执行。

推断是解密算法。

   

   

直接循环后,查看 缓冲区2 【483220】结果:

   

 

2.6、OD RUN跟踪

进一步验证,分析循环次数。

此处循环判断是CMP ESI 0x10B18

通过ESI的数值判断。

 

   

由图可知比较esi来判断循环结束,esi算法复杂。

直接采用Run跟踪。

   

   

全局统计循环了 616次,

616 == 0x268,正好是拷贝的0x268个字节。

实际应该是0x26C个字节,那末尾的四个字节呢?

带着疑问继续跟踪。

   

   

发现此处指令往数据末尾写入4个字节,正好凑齐0x26C个字节,Perfect。

 

   

2.7、总结与实施方案

 解密了0x268个字节,解密后,再写入四个无加密字节。

最后四字节是此处代码生成,写进文件中会覆盖掉原数据,所以后续操作中不用考虑。

   

所以得出结论:此处就是解密算法 。

所以可以肯定的是 配置文件数据的确经过加密。

 

往下分析,写入文件时,遇到加密算法

   

   

解决方案:

  1. 由经过解密算法后的配置文件可以看出,头个字节就是关卡数,所以经过算法修改首个字节就行。
  2. 直接去掉程序算法,配置文件以原样数据保存。再修改配置文件。
  3. 逆算法,写一个翻译器。

   

本文选择高端而又简洁一点的操纵,第二种。

此处直接NOP掉算法代码。

   

四、路途曲折与反反调试

本文的最高潮来了。

1、出师不利

就在我修改完代码,保存文件,满怀期待地 双击运行的时候,弹出了这个小框框:

 

 

说实话,当初这东西对我地信心打击不小呀,但秉着不气馁不认输地倔强脾气,决定继续分析。

但得先思考思考,猜测是exe模块内存方面的反调试,类似于模块的哈希值。

 

 首先,既然弹框,往MessageBox上下断点。然后往上回溯。

可以看到弹框的关键跳转。

   

   

往上分析,弹框的条件取决于此函数返回的EAX值。

   

   

1. 跟进函数,发现LoadLibrary加载grim.dll后返回EAX为零值。

2. 为了进行比较,打开正常游戏,跟到此处,LoadLibrary加载grim.dll后返回却为正常值。

 

 

1. 分析下面发现后面还jmp 隐藏调用了grim.dll里的GRIM_GetInterface函数。

2. 此处为什么要隐藏调用。虽然这一点在文章后面用不上,但猜测是其它功能破解的线索,所以晒出来,以后或许用得上。

 

 

总结一下:

正常情况下,加载grim.dll后是有正常返回值的。

当修改了指令也就是模块内存后,保存exe,运行,加载grim.dll后返回空值,导致函数调用失败,外部EAX返回值使弹出MessageBox程序运行失败。

LoadLibrary —失败—>> 函数 —失败—>> EAX返回值 —导致—>>弹出MessageBox 程序运行失败

 

推测是程序 再次打开exe进程,校验模块内存,所以在进程相关函数下断。特别是CreateProcess

但从程序开始运行到弹窗,无一次断下。

2、峰回路转

不是模块内存,又必须对字节进行校验,剩下的可能,推测是进行了磁盘文件校验。

验证:用正常exe打开游戏进程后,替换dump的exe,发现依然存在错误,可以推断不是依靠进程内存判断的,而是通过磁盘文件

在CreateFile、ReadFile下断点。并进行参数过滤。

   

   

   

   

查看ReadFile的Buff,的确读取的游戏exe文件。 

   

   

ReadFile一次读取0x1000个字节,需要调用多次。

 

接下来要找到反调试的关键代码。

回溯:找到调用ReadFile的循环。

 

3、直击敌营

分析到这里就可以一口气开干了。

逆向分析代码:

目的:分析出算法计算最后得出的值,值的传递,并与谁比较。

   

   

分析可以得出此算法是计算文件的哈希值【MD5】

并拿计算好的MD5原MD5进行比较。 

 

   

进行修改指令,dump grim.dll即可。

 

   

再替换原有的游戏exegrim.dll。

 

   

成功。

 

   

最后一步:

修改配置文件

   

可以看出修改后的exe用WriteFile写出来的配置文件 清晰明了。

 

 

4、大获全胜

通关成功。

   

 

个人总结:灵活运用硬件断点、内存断点、栈回溯。

硬件断点和内存断点

硬件断点能快速定位关键点

方便,但逻辑较乱

栈回溯

栈回溯能顺藤摸瓜

需要耐心,但逻辑清晰

 

附件: 

 Crimsonland_血腥大地_外挂文件

 

 KIDofot

posted @ 2018-03-12 21:38  KIDofot  阅读(1329)  评论(0编辑  收藏  举报
levels of contents