逆向工程第001篇:解锁FIFA07传奇模式
FIFA07传奇难度的解锁,可以说是所有FIFA07玩家的终极目标。但是如果想以正常方式对其进行解锁,绝对是一件耗时耗力的工作。所以在这里我打算通过分析游戏存档文件的十六进制代码的方式,一步一步地找到解锁传奇难度的钥匙。在这一过程中,也实现了对游戏所有隐藏项目的彻底解锁。
图1 FIFA07游戏封面
一、收集游戏中必要的信息
在这里先不着急分析游戏的十六进制代码,需要先对游戏需要解锁的内容有一个大概的了解。首先游戏需要解锁的有两个大项的内容,一个是游戏中的“球迷商店”,另外一个是“FIFA07挑战”。其中“球迷商店”包含70个子项,是游戏中的隐藏内容,它们分别是:额外(4项)、足球(23项)、第三方球衣(35项)、创建中心(2项)、练习体育场(4项)以及赛季集锦(4项)。所有的这70个子项,是需要使用一定的游戏点数才能够换取的。而游戏点数的获取,则需要完成“FIFA07挑战”中的挑战项目才能够获得。不同的挑战项目,依据其难易程度,挑战成功后会得到不同的游戏点数,越困难的挑战项目,那么成功后所获得的游戏点数也就越多。“FIFA07挑战”中包含102个子项,它们分别是:英国(12)项、西欧(12项)、南欧(12项)、中欧(12项)、美洲(11项)、斯堪的纳维亚半岛(12项)、其余区域(9项)、世界(10项)以及世界2(12项)。而最终目标,也就是解锁传奇模式,它属于“世界2”的第12项解锁项目,若要解锁传奇模式,那么需要完成任两个大区的挑战才可以。到现在为止,在游戏中需要收集的信息基本已经收集完毕,那么分析的第一阶段就可以告一段落。
二、了解游戏存档信息
一般来说,类似于FIFA07这样的单机版的游戏,其设置信息还有各项的解锁及成就信息会保存在游戏的存档文件中。因此我们只需要对游戏的存档文件进行修改即可,并不需要对游戏的主程序或动态链接库之类的文件进行修改。而具体对FIFA07来进行分析,每当游戏新建立一个玩家信息,那么系统会自动建立一个默认名称为Profiles的文件,其默认路径为“C:\XXXX\XXXX\Documents\FIFA 07\”,用于保存全局设置以及相应的解锁信息。之所以能够确定Profiles文件的功用,是因为在FIFA07默认文件夹内,除了这个文件,其它的文件要么是用于存储录像信息,要么是存储由玩家创建的比赛信息。那么我们接下来的工作重点就是分析Profiles文件。
图2 FIFA07存档文件夹
三、粗略观察存档文件的十六进制代码
接下来可以使用十六进制代码查看软件对Profiles文件进行粗略的观察。当然现在不要指望经过这一轮的观察就能够直接定位到传奇模式的关键代码位置,这一步骤的目的在于对于文件内容各个区段有一个大致的了解。这里选用的查看软件最好同时也能够对文件的十六进制代码进行修改,以方便接下来的工作。需要说明的是,查看文件的十六进制代码,往往会发现大量的数字00的存在,一般来说,这些大段的00往往用于文件相应区段的对齐,也就是并没有实质的作用,但有时也会有其它的作用,因此具体问题要具体分析。在此,我将整个Profiles文件分为三个区段:
区段一(相对地址0x0000至0x002f):这个区段可以理解为是Profiles文件的头部,用于识别本文件是否为合法的FIFA07存档文件,一般不对其进行分析,在此将其略过。
图3 Profiles文件的头部
区段二(相对地址0x0160至0x0348):由于通过本区段的十六进制代码基本上无法推断出有意义的ASCII码对应的字母,因此可以暂时将这个区段列为重点怀疑的对象,也许本区段包含着解锁的关键。
图4 Profiles文件的中部(部分内容)
区段三(相对地址0x0368至0x0e24):这个区段可以理解为用于存储全局设置,从将本区段的十六进制代码转换为ASCII码就可以看出来,一般不需要进行分析,暂时将其略过。
图5 Profiles文件全局设置部分
由于在区段三之后就是大量的数字00,有理由相信这些00都是无意义的,仅仅作为填充对齐之用。而经过本步骤的粗略分析,我们对Profiles文件就有了一个大致的了解,那么接下来就到了实质分析推理并修改的阶段。
四、彻底解锁“球迷商店”
正如之前所分析的,球迷商店的内容需要使用游戏点数来换取,那么可以考虑采用通过修改游戏点数的方式来将“球迷商店”的内容一一解锁。就拿我的FIFA07中的游戏点数为例,进入游戏经查看可知,我现在拥有2535点的游戏点数,由于我们最终查看的是十六进制的代码,因此需要把十进制的2535转换为十六进制,即09e7,但是由于我们的计算机是以“小端”为标准,所以在代码文件中应该是以“e709”进行显示的,所以在这里可以利用十六进制代码查看软件搜索“e709”。找到后可以尝试将其修改为“ffff”,这样足够用于解锁。如果在文件中能够找到许多“e709”,那么可以分别修改,每修改完一处就进入游戏以查看,若成功,说明定位成功;若失败,则需将上一步的修改撤销,继续修改下一个位置。
图6 对游戏点数进行修改
很幸运的是,我们所查找到的第一个位置就是游戏点数的位置,其相对地址为0x0300与0x0301,这样我们再次进入游戏中的“球迷商店”,就能够一项一项地解锁所有隐藏项目了。
但是在解锁之前有一件事是需要特别注意的,那就是必须要对Profiles文件再复制一份进行保存。这么做的目的是为了观测游戏解锁前后的变化,而且这一良好的习惯,会成为接下来解锁工作的关键。至此,“球迷商店”已经彻底解锁,但是距离我们的目标,似乎还是很遥远。
五、寻找“球迷商店”标志位
仅仅通过修改游戏点数来换取隐藏项目并不是我们理想中高明的方式,既然是逆向工程,那么必须要找出究竟是什么导致了游戏能够识别出哪些项目解锁了,哪些项目没有解锁。依据现在所掌握的的资料,可以从两个方面入手。
首先在图4中可以发现Profiles文件的区段二中,在大量的十六进制数字00中,包含着一定数量的01,这其实是一件很奇怪的事情,因为ASCII码中的01代表SOH(Start of Headling)即头标开始,是一个不可打印的ASCII码,我们可以认为它就是一个无意义的。对比其它位置,这个区段中的01确实是多了些,加上又是参杂在大段的00中,那么可以联想到这里的01也许就是一个开关,也许就是某个标志位。最后我们需要对上述猜测进行确认,这里通过使用对比解锁前后的两个文件的十六进制代码的软件来辅助我们的分析。
图7 对比“球迷商店”解锁前后的Profiles文件
实际对比中可能会有别的位置也有差别,但是图中区段是我们重点怀疑的位置,截图中的上半部分为“球迷商店”解锁前的Profiles文件,下半部分为彻底解锁的Profiles文件。通过对比基本确认了我们的猜测。由于隐藏物品有70项,那么也需要70个字节用于标记这70项的内容。而相对地址0x01f4至0x0239正好是70个字节的内容。可以认定这就是我们要找的标志位。如果不放心可以进入解锁前的游戏,记下“球迷商店”中解锁物品与未解锁物品的位置,依照上图样式,以00代表未解锁,01代表解锁,写下来对比观测,看看是否与图中一致。
图8 “球迷商店”隐藏项目标志位
至此,已经掌握了“球迷商店”的修改关键,这样就可以直接对这些相应的标志位进行修改,无需通过修改游戏点数的方式来解锁隐藏物品了。
六、彻底解锁“FIFA07挑战”
不同于解锁“球迷商店”,“FIFA07挑战”并不需要游戏点数进行解锁,因此不能通过找寻某一特殊数值的方式来换取点数对其进行解锁。但是由于有了以上的经验,可以怀疑“FIFA07”挑战也许如同“球迷商店”一样,也是在某个区段,采用了以00代表未解锁,01代表解锁了的方式进行记录。但是这个不容易进行定位,可以考虑采取两种方式。一种是在游戏中先通过正常方式解锁一项挑战内容,之后通过对比解锁前后的Profiles文件的方式进行定位。另外一种是直接对Profiles文件的十六进制代码进行观察,特别是区段二部分,寻找类似于“球迷商店”那样的在大段的00中夹杂着01的区块。然后就可以定位到相对地址为0x017c至0x01e1,一共102个字节的位置,正好对应于102个挑战项目。可以将该区段全部修改为01,而传奇难度正是第102个标志位,即0x01e1位置。但是修改后发现,尽管在“FIFA07挑战”中所有选项已经打钩,但是传奇难度依旧未能解锁,由此可以推断,传奇难度应该另有标志位,以决定其是否解锁。在这里可以先任选两个区的挑战,在这两个区中留下一个不进行解锁,而将本区中其它位置通过修改标志位的方式进行解锁,进入游戏以正常方式达成未解锁成就,这样两个区成就达成,游戏便自动解锁了传奇难度。同样的,依旧要保存解锁前后的Profiles文件。
图9 “FIFA07挑战”标志位
至此,“FIFA07挑战”得到彻底解锁,同时传奇难度也得以解锁。
七、寻找传奇难度标志位
尽管通过上述方式可以解锁传奇难度,但是我们的目的还是要以不进行游戏,直接修改标志位的方式来解锁传奇难度。同样还需要采取对比的方式,可能解锁前后会有许多的数据发生了变化,但是还是需要优先寻找未确定功能的区块中的01位置。每修改完一处就进入游戏实验传奇难度是否已经解锁,若没有解锁,则撤销之前的修改,继续修改下一个标志位,采用这种手段就能够最终找到传奇难度的标志位,即0x023b的位置。
图10 FIFA07传奇难度的标志位
这样,我们可以在不对Profiles文件进行任何修改的前提下,直接对该标志位进行修改,实现传奇难度的解锁。至此大功告成,同时在这寻找的过程中,也彻底分析清楚了FIFA07中所有隐藏项目的解锁位置。
八、尝试投机方式解锁传奇难度
之前分析了Profiles文件中的区段三保存着全局设置的数据,那么可以尝试一下直接修改难度的数值,测试是否能够解锁传奇难度。这里可以采用搜索字符串的方式查找到设置中保存的难度标志位,直接将该值设置为4,即传奇难度。但是进入游戏发现,设置中的游戏难度为空,没有任何显示。那么有必要对这个“空格”难度的实力进行测试。而经过测试发现,“空格”与真实的传奇难度的水平相差甚远,因此可以得知,采用这种投机的方式并不能直接解锁传奇难度。
图11 尝试修改全局设置解锁传奇难度
九、总结
由以上的流程可以看出,逆向工程需要的是细心与耐心。很多时候,成功的逆向往往是“三分技术,七分运气”。对于同一项内容的解锁,尝试采取不同的方式往往会有新的发现。而对逆向工具的正确使用,也会起到事半功倍的效果。
至此,FIFA07已经得到彻底解锁,也找到了所有隐藏项目的标志位,逆向工程的第一个成功的尝试,也是为以后的工作打下了良好的基础。
逆向工程第001篇:解锁FIFA07传奇模式的更多相关文章
- 逆向工程第003篇:跨越CM4验证机制的鸿沟(上)
一.前言 <冠军足球经理>系列作为一款拟真度极高的足球经营类游戏,赢得过无数赞誉,而CM4可以说是这个传奇的起点.但是在游戏安装过程中,当用户输入完序列号之后,程序并不会对用户的输入进行真 ...
- 技术面试问题汇总第001篇:猎豹移动反病毒工程师part1
我在2014年7月1日参加了猎豹移动(原金山网络)反病毒工程师的电话面试,但是很遗憾,由于我当时准备不足,加上自身水平不够,面试官向我提出的很多技术问题我都没能答出来(这里面既有基础类的问题,也有比较 ...
- Java进阶篇设计模式之六 ----- 组合模式和过滤器模式
前言 在上一篇中我们学习了结构型模式的外观模式和装饰器模式.本篇则来学习下组合模式和过滤器模式. 组合模式 简介 组合模式是用于把一组相似的对象当作一个单一的对象.组合模式依据树形结构来组合对象,用来 ...
- Java进阶篇设计模式之五-----外观模式和装饰器模式
前言 在上一篇中我们学习了结构型模式的适配器模式和桥接模式.本篇则来学习下结构型模式的外观模式和装饰器模式. 外观模式 简介 外观模式隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口.这 ...
- Java进阶篇设计模式之三 ----- 建造者模式和原型模式
前言 在上一篇中我们学习了工厂模式,介绍了简单工厂模式.工厂方法和抽象工厂模式.本篇则介绍设计模式中属于创建型模式的建造者模式和原型模式. 建造者模式 简介 建造者模式是属于创建型模式.建造者模式使用 ...
- 设计模式总结篇系列:原型模式(Prototype)
首先对原型模式进行一个简单概念说明:通过一个已经存在的对象,复制出更多的具有与此对象具有相同类型的新的对象. 在理解Java原型模式之前,首先需要理解Java中的一个概念:复制/克隆. 在博文< ...
- Android架构篇--MVP模式的介绍篇
摘要: 在MVVM成熟之前MVP模式在Android上有被神化的趋势,笔者曾经在商业项目中从零开始大规模采用过MVP模式对项目进行开发.在使用MVP模式进行开发的时候发现项目的结构模式对开发是有一定的 ...
- 逆向工程第005篇:跨越CM4验证机制的鸿沟(下)
一.前言 本文是逆向分析CM4系列的最后一篇,我会将该游戏的序列号验证机制分析完毕,进而编写出注册码生成器. 二.分析第二个验证循环 延续上一篇文章的内容,来到如下代码处: 图1 上述代码并没有特别需 ...
- 逆向工程第004篇:跨越CM4验证机制的鸿沟(中)
一.前言 在上一篇文章的最后,我已经找出了关键的CALL语句,那么这篇文章我就带领大家来一步一步地分析这个CALL.我会将我的思路完整地展现给大家,因此分析过程可能略显冗长,我会分为两篇文章进行讨论. ...
随机推荐
- 利用CORDIC算法计算三角函数
这里主要先介绍如何利用CORDIC算法计算固定角度\(\phi\)的\(cos(\phi)\).\(sin(\phi)\)值.参考了这两篇文章[1].[2]. 一般利用MATLAB计算三角函数时,用\ ...
- Java实现文件的读写
需求:实现基本的读写 package com.sbx.io; import java.io.File; import java.io.FileReader; import java.io.FileWr ...
- Mybatis系列全解(五):全网最全!详解Mybatis的Mapper映射文件
封面:洛小汐 作者:潘潘 若不是生活所迫,谁愿意背负一身才华. 前言 上节我们介绍了 < Mybatis系列全解(四):全网最全!Mybatis配置文件 XML 全貌详解 >,内容很详细( ...
- 《从零开始TypeScript》系列 - 基础数据类型
TypeScript 是 JavaScript 的超集,这里我们只讨论两者中的不同的部分,或者需要注意的部分 数组 Array:在TypeScript中,有两种方式来定义一个数组: 在元素类型后面接上 ...
- JVM线上问题排查
前言 本文介绍服务器内运行的 Java 应用产生的 OOM 问题 和 CPU 100% 的问题定位 1. 内存 OOM 问题定位 某Java服务(比如进程id pid 为 3320)出现OOM,常见的 ...
- rest framework ViewSet
ViewSets 路由选择确定要用于一个请求哪个控制器之后,控制器负责做出请求的感并产生相应的输出. - Ruby on Rails的文档 Django的REST框架允许你的逻辑一组在一个类中的相关意 ...
- 使用dcmtk库读取.dcm文件并获取信息+使用OpenCV显示图像
借助VS2013和OpenCV的绘图功能,在工程DICOMReader.sln中实现了对单张.dcm图像的读取与显示,以下是详细步骤. 前期准备工作 编译器:VS2013 库:dcmtk-3.6.0( ...
- 拖拽方式生成Vue用户界面
前一阵子拜访了一些小伙伴,大家都表示苦前端太久了,需要花费不少时间在前端开发上.本着在不损失灵活性的前提下尽可能提高开发效率的原则,作者尝试在框架内集成了拖拽方式生成Vue用户界面的功能作为补充, ...
- 回忆那些年我玩过的ide,看看哪些你也玩过,看图回忆
闲来无聊,回忆一下这些年玩过的ide.看看哪些你也玩过. QBasic 第一个ide,兴奋程度也是最大的,从此进入了码农行列 VisualBasic 可以拖界面了,成就感爆棚 Turbo C c语言, ...
- Java例题_19 打印菱形图案
1 /*19 [程序 19 打印菱形图案] 2 题目:打印出如下图案(菱形) 3 * 4 *** 5 ***** 6 ******* 7 ***** 8 *** 9 * 10 */ 11 12 /*分 ...