一、前言

《冠军足球经理》系列作为一款拟真度极高的足球经营类游戏,赢得过无数赞誉,而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. JS动态获取select中被选中的option的值,并在控制台输出

    生活城市: <select id="province"> <option>河南省</option> <option>黑龙江省< ...

  2. python带颜色打印字符串

    python带颜色打印字符串 之前调试pwn题的时候,有时候需要将某些特别的,重要的信息用不一样的颜色打印出来.查阅一些资料,了解了print函数的特性后,自己写了一个脚本,可以用来获取带颜色信息的字 ...

  3. 200-Java语言基础-Java编程入门-004 | Java分支与循环

    一.流程控制语句 可以控制程序的执行流程 在程序开发的过程之中一共会存在有三种程序逻辑:顺序结构.条件分支(选择)结构.循环结构. 顺序结构的定义,即:所有的程序将按照定义的代码从上往下.顺序依次执行 ...

  4. Apache配置 5.访问日志不记录静态文件

    介绍:项目中的CSS.图片.js都是静态文件.一般会将静态文件放到一个单独的目录中,以方便管理. 1. 配置 # vim /usr/local/apache2.4/conf/extra/httpd-v ...

  5. SQL练习——LeetCode解题和总结(1)

    只用于个人的学习和总结. 178. Rank Scores 一.表信息 二.题目信息 对上表中的成绩由高到低排序,并列出排名.当两个人获得相同分数时,取并列名次,且名词中无断档. Write a SQ ...

  6. BZOJ_2844 albus就是要第一个出场 【线性基】

    一.题目 albus就是要第一个出场 二.分析 非常有助于理解线性基的一题. 构造线性基$B$后,如果$|A| > |B|$,那么就意味着有些数可以由$B$中的数异或出来,而多的数可以取或者不取 ...

  7. 1.mysql读写

    一.数据库读取(mysql) 参数 接受 作用 默认 sql or table_name string 读取的表名,或sql语句 无 con 数据库连接 数据库连接信息 无 index_col Int ...

  8. JVM之对象回收

    finalize /** *此代码演示了两点: *1.对象可以在被GC时自我拯救. *2.这种自救的机会只有一次,因为一个对象的finalize()方法最多只会被系统自动调用一次 */ public ...

  9. Java系列教程-SpringMVC教程

    SpringMVC教程 1.SpringMVC概述 1.回顾MVC 1.什么是MVC MVC是模型(Model).视图(View).控制器(Controller)的简写,是一种软件设计规范. 是将业务 ...

  10. 6、Spring教程之自动装配

    自动装配说明 自动装配是使用spring满足bean依赖的一种方法 spring会在应用上下文中为某个bean寻找其依赖的bean. Spring中bean有三种装配机制,分别是: 在xml中显式配置 ...