一、前言

《冠军足球经理》系列作为一款拟真度极高的足球经营类游戏,赢得过无数赞誉,而CM4可以说是这个传奇的起点。但是在游戏安装过程中,当用户输入完序列号之后,程序并不会对用户的输入进行真伪判断,只有等到安装完毕,进入游戏之后,通过游戏是否正常显示才能够得知。而如果遇到用户不小心输入错误的情况,那么只能卸载游戏重新安装,这就会造成很大的麻烦。

为解决这个问题,这次的研究会以两篇文章的篇幅通过两种方式对这个游戏进行逆向分析,一种是采用常见的“爆破”手段,也就是本文所讨论的方法;而另一种则是编写出CM4的注册码生成器,这会在下一篇文章中进行讨论。后者需要依据反汇编代码分析出游戏的验证机制,这可以说是任何逆向研究的最终目标,也是本次研究的最终目标。

图1 CM4游戏封面

 

二、尝试在没有序列号的前提下安装并进入游戏

CM4这款游戏在游戏安装的过程中,会要求用户输入序列号,这个序列号由数字加字母组成,一共16位,每4位为一组。

图2 CM4安装程序的序列号输入界面

而在本研究的过程中,我尝试将序列号输入为“0123456789ABCDEF”,每一位输入不同的字符,这样便于后面的逆向跟踪。这种方式往往也运用于缓冲区溢出的检测(可见《反病毒攻防研究第003篇:简单程序漏洞的利用》)。当游戏安装完毕后,进入游戏。程序会先进行序列号的验证,如果之前的序列号输入错误,那么就会出现错误提示对话框。

图3 进入游戏之前提示的错误信息

这里当我们单击“确定”之后,依然能够进入游戏,但是游戏却无法正常显示,在我的电脑中,凡是出现文字的部分,均会以乱码显示。虽然说对于老玩家而言,依然可以通过各个按钮的位置来确定每个按钮的功能,但是依然会造成很大的麻烦,所以在此很有必要对这一问题进行逆向研究。

图4 进入游戏中的乱码显示

三、寻找软件的CDKEY检查对话框位置

一般来说,想要找到软件的验证语句的位置,则需要运用动态或者静态反汇编工具,得到它的反汇编代码,分析该软件的运行机理,一步一步跟踪执行,直至弹出如图3所示的“CDKEY检查”对话框。这个对话框一定是由一个CALL语句调用出来的,那么这个CALL语句必然包含了相应的验证机制,就有必要进入这个CALL语句,进一步分析。

对于这次的研究对象——CM4来说同样如此,根据惯例,我们有必要先对这款软件进行查壳的操作,这是一切逆向工作的起始,毕竟有壳的软件是必须要进行脱壳之后才能进一步分析的。这里我使用的是PEiD:

图5 对CM4进行查壳操作

根据查壳的结果可以看到,本软件是采用Microsoft Visual C++ 8.0编写的Debug版本,并没有加壳,那么接下来就可以按照上述思想开始分析了。直接单步运行进行检查,很快就可以定位到调用错误提示对话框的CALL语句,其相对地址为0x0041495C(当然真正调用MessageBox()语句的 CALL还在这个CALL的内部)。

图6 找到CDKEY检查的CALL

按F7进入这个CALL之后,继续单步执行,来到相对地址为0x00411E3C位置处的语句,由于经过上一步(test eax,eax)的验证后ZF标志位为1(两个eax的值相等),于是跳转实现,会直接跳转到0x00411F26的位置。

图7 跳转至对话框的语句

经过观察可以发现,所跳转到的0x00411F26的位置就是调用MessageBox()函数的位置,而它也正是“CDKEY检查”对话框。

图8 对话框调用函数位置

分析至此,就可以采取相应的手段来避开这个对话框,使游戏正常运行。

 

四、采取“爆破”方式来正常进入游戏

“爆破”最常用的方式是修改关键跳,对于本软件来说,就是上面分析出来的相对地址为0x00411E3C位置(图7)处的“je00411F26”(相等则跳转)语句。正是由于这个跳转实现,使得CDKEY检查对话框(图3)弹出。依据这个就可以进行修改了。

在此情况下通常有两种方式可以达到目的。一种是可以考虑改变条件跳转语句的条件。可以将je修改为jnz(不等于0则跳转),这样程序可以顺序执行下去,而不会跳转到错误提示窗口。

图9 修改跳转语句的条件

另一种是可以直接将跳转语句删除,用nop予以取代,也可以达到避免产生跳转的效果。(注意:将反汇编代码修改为nop并不是对所有程序都有效,其目的只是避免跳转,从而继续下一条语句执行。具体情况需要具体分析)。

图10 nop掉跳转语句

采用上述任何一种方式修改之后,进入游戏,可以发现错误提示窗口不再显示,并且游戏中的文字也正常了。

图11 修改后进入游戏

当然,“爆破”的手段五花八门,可供修改的位置以及方式多种多样,在此也就不再赘述。但是有一点在此需要强调,在一般的软件逆向分析中,有一种去除NAG窗口的方式是把MessageBox()函数的第一个参数(在反汇编代码中是第四个参数)的值修改为一个无意义的值,比如1,这样就会导致消息窗口创建失败,从而也就不会显示MessageBox了。

图12  修改MessageBox的hWnd参数的值

但是在本软件中,采用这种方式虽然能够去除错误窗口,但是进入游戏后依旧显示乱码(如图4所示),可见,此时虽然不再提示CDKEY检查错误对话框,但是验证依旧失败,说明验证流程已经执行了。因此在本程序中,仅仅修改hWnd这个参数是无法达到目的的。

 

五、进一步分析CM4序列号验证机理

采取“爆破”手段虽然能够解决问题,但是却修改了程序的源代码,因此并不是高明的手段。而类似于这种软件的逆向分析的最高目标,就是通过分析其序列号的验证机制,从而编写出序列号生成器,这样不会破坏程序的原始代码,也对程序有了比较深刻的理解。当然关于序列号验证算法的逆向分析与序列号生成器的程序编写,会放到下一篇文章中讨论,这里只是去寻找验证机制的反汇编代码位置。

首先可以肯定的是,序列号验证模块的入口代码一定是一个CALL语句,而且它必然在判断是否执行错误提示窗口代码(图7)的上方(可能在上方很远处)。对于本程序来说,这个CALL的返回值保存在eax中,而这个eax正好就在弹出“CDKEY检查”窗口反汇编代码的正上方:

图13 序列号验证返回值判断

一般来说,序列号的验证就是通过一系列的算法对序列号进行检验,验证结束以后,接下来的语句就可以通过返回值,也就是保存在eax中的值的情况进行判断,以决定程序接下来的走向。有些不一样的是,本程序并不是对eax中的内容直接进行判断,而是将[ebp-19d]中的值经填充后再赋给eax进行验证,那么有理由相信,用于验证的CALL语句的真正返回值会保存在[ebp-19d]中,它才是最为关键的位置。逆向分析时就需要时刻留意这个位置的值如何发生变化。换算成相对地址,也就是0x0012FCEB。

不断向上回溯查找可以发现,整个流程中会出现非常多的CALL,但是不必每一个CALL都要跟进查看,只要留意该CALL语句执行完毕后是否改变了0x0012FCEB位置的值即可。可以紧盯数据窗口中的0x0012FCEB位置,看其究竟是受到哪个CALL的影响由断点“CC”变成了非零值(关于断点“CC”的说明,可查看《技术面试问题汇总第001篇:猎豹移动反病毒工程师part1》中问题1末尾处的补充知识)。按照这种思想,很快就可以找到关键CALL: 

图14 影响返回值的关键CALL

相对地址为0x0041DB3的CALL语句执行后,其返回值赋给了[ebp-19d],将该位置的值由CC变成了00。

图15  数据窗口中查看0x0012FCEB

这样一来,接下来的工作就是进入相对地址为0x0041DB3的CALL语句中进行分析了。对于这个CALL内部原理的分析,我会放在下一篇文章中。

六、小结

对软件进行逆向分析是一件非常耗时的工作,需要耐心与恒心。但是一旦成功,喜悦是不言而喻的。OllyDbg是我们反汇编工作中的利器,希望大家能够熟练掌握,还是那句话,希望各位读者能够勤加练习,才能在实际的运用中,少走弯路。

逆向工程第003篇:跨越CM4验证机制的鸿沟(上)的更多相关文章

  1. 逆向project第003篇:跨越CM4验证机制的鸿沟(上)

    一.前言 <冠军足球经理>系列作为一款拟真度极高的足球经营类游戏.赢得过无数赞誉,而CM4可以说是这个传奇的起点. 可是在游戏安装过程中.当用户输入完序列号之后.程序并不会对用户的输入进行 ...

  2. 逆向工程第004篇:跨越CM4验证机制的鸿沟(中)

    一.前言 在上一篇文章的最后,我已经找出了关键的CALL语句,那么这篇文章我就带领大家来一步一步地分析这个CALL.我会将我的思路完整地展现给大家,因此分析过程可能略显冗长,我会分为两篇文章进行讨论. ...

  3. 逆向工程第005篇:跨越CM4验证机制的鸿沟(下)

    一.前言 本文是逆向分析CM4系列的最后一篇,我会将该游戏的序列号验证机制分析完毕,进而编写出注册码生成器. 二.分析第二个验证循环 延续上一篇文章的内容,来到如下代码处: 图1 上述代码并没有特别需 ...

  4. 逆向project第005篇:跨越CM4验证机制的鸿沟(下)

    一.前言 本文是逆向分析CM4系列的最后一篇,我会将该游戏的序列号验证机制分析完成,进而编写出注冊码生成器. 二.分析第二个验证循环 延续上一篇文章的内容,来到例如以下代码处: 图1 上述代码并没有特 ...

  5. 黑客攻防技术宝典web实战篇:攻击验证机制习题

    猫宁!!! 参考链接:http://www.ituring.com.cn/book/885 随书答案. 1. 在测试一个使用joe和pass证书登录的Web应用程序的过程中,在登录阶段,在拦截代理服务 ...

  6. Linux登录验证机制、SSH Bruteforce Login学习

    相关学习资料 http://files.cnblogs.com/LittleHann/linux%E4%B8%AD%E7%94%A8%E6%88%B7%E7%99%BB%E5%BD%95%E8%AE% ...

  7. 通过扩展改善ASP.NET MVC的验证机制[实现篇]

    原文:通过扩展改善ASP.NET MVC的验证机制[实现篇] 在<使用篇>中我们谈到扩展的验证编程方式,并且演示了本解决方案的三大特性:消息提供机制的分离.多语言的支持和多验证规则的支持, ...

  8. 通过扩展改善ASP.NET MVC的验证机制[使用篇]

    原文:通过扩展改善ASP.NET MVC的验证机制[使用篇] ASP.NET MVC提供一种基于元数据的验证方式是我们可以将相应的验证特性应用到作为Model实体的类型或者属性/字段上,但是这依然具有 ...

  9. 本版本延续MVC中的统一验证机制~续的这篇文章,本篇主要是对验证基类的扩展和改善(转)

    本版本延续MVC中的统一验证机制~续的这篇文章,本篇主要是对验证基类的扩展和改善 namespace Web.Mvc.Extensions { #region 验证基类 /// <summary ...

随机推荐

  1. HDOJ-1024(动态规划+滚动数组)

    Max Sum Plus Plus HDOJ-1024 动态转移方程:dp[i][j]=max(dp[i][j-1]+a[j],max(dp[i-1][k])+a[j]) (0<k<j) ...

  2. 【Arduino学习笔记02】第一个Arduino项目——点亮LED Blink.ino程序解读 Arduino程序基本结构 pinMode() digitalWrite() delay()

    /* Blink Turns an LED on for one second, then off for one second, repeatedly. */// define variables ...

  3. 计算机二级Python学习笔记(一):温度转换

    今天通过一个温度转换的十行代码,理解了一些Python的基本元素. 所谓温度转换,就是摄氏度和华氏度的转换,要求输入摄氏度,可以输出华氏度,反之一样能实现.代码如下: #TempConvert.py ...

  4. 001-HashMap源码分析

    HashMap源码分析 哈希表(hash table)也叫散列表,是一种非常重要的数据结构,应用场景及其丰富,许多缓存技术(比如 memcached)的核心其实就是在内存中维护一张大的哈希表. 一.什 ...

  5. C#开发BIMFACE系列37 网页集成开发1:审图系统中加载模型或图纸

    系列目录     [已更新最新开发文章,点击查看详细] 在之前的<C#开发BIMFACE系列>中主要介绍了BIMFACE平台提供的服务端API接口的封装开发与测试过程. 服务端API测试通 ...

  6. NIO三大组件之Selector选择器

    什么是选择器 选择器的作用是完成IO的多路复用.一个通道代表一条连接通路,通过选择器可以同时监控多个通道的IO(输入输出)状况.选择器和通道的关系,是监控和被监控的关系. 使用 重要的成员 Selec ...

  7. 利用jmeter对WebRTC应用进行压力测试(java)

    利用jmeter对WebRTC应用进行压力测试(java) 说明:WebRTC是一款开源的多人即时视频API,与一般的http请求不同,webrtc应用实际压力主要是码流 最近负责了一个WebRTC的 ...

  8. SDK音频测试流程

    概述 在上篇文章中,给小伙伴们讲述了sdk模板在渲染中的流程,我们简单来回顾一下,主要讲述了数据创建.素材替换.音频.文字等四部分,在上次讲述中也因为时间于原因没有特别仔细的去讲述他们.上次我们说到最 ...

  9. CMU数据库(15-445) Lab4-CONCURRENCY CONTROL

    Lab4- CONCURRENCY CONTROL 拖了很久终于开始做实验4了.lab4有三个大任务1. Lock Manager.2. DEADLOCK DETECTION .3. CONCURRE ...

  10. 简易计算器实现:while循环+switch语句

    个人练习: 写一个计算器,要求实现加减乘除功能,并且能循环接收新的数据,通过用户交互实现(即Scanner对象) 用到了 while循环 switch语句,实现了数据的循环输入并计算!!!!妙啊!!! ...