文章目录
- Introduction
- Finding save files
- Strings
- Unicode
- Example!
- Value search
- Health search
- Conclusion
Introduction
这节课我们将学习编辑十六进制,主要用于编辑保存文件,但十六进制编辑涉及的技能可以很好地转移到:
- Save file editing
- Resources editing
- Raw memory editing
- Packet editing
这些都是我们将学习的有用技术,因此十六进制编辑也有三个主要步骤:
- Find info in save file that you want to hack
- Hex edit the file
- See if it worked
Finding save files
- 选项一 Just google it - 没有必要在这上面努力工作并花费时间精力
- 选项二 API monitoring - 询问操作系统去查看游戏使用了哪些文件,你可以拦截游戏保存文件的请求,这样就可以知道游戏使用了什么文件
- 游戏使用 OS Calls 去读写文件
- 系统更新文件在 Hard drive 硬盘上
- 使用 Process Monitor 可以查看游戏在请求系统做什么,同样的,很多反作弊系统也通过查看有没有恶意软件在进行一些危险请求来确认游戏是否被攻击
微软官网下载 Process Monitor 并解压出来后打开即可
你可以使用 Find 工具
或者使用作者更喜欢的 Include Process From Window,你只需要把这个拖动到某个窗口上,接下来程序就只会显示你筛选的那个窗口的信息了
因为游戏是从数据中进行流式传输的,所以他会不断访问,如下:
所以让我们忽略 ReadFile 这种 Operation,只关注保存文件时的事件,只需要右键 ReadFile 然后 Exclude 即可
当我们购买一个物品消耗了一波金币,会发现 CreateFile 事件,路径是某个文件夹下的 Global.sqa 我们只需要购买一些东西并使用该工具,即可隔离保存文件!
Strings
很棒!我们已经发现了保存文件所在的目录,但在我们开始编辑文件之前,我们需要了解字符串。
回到我们对文件的理解,文件和程序似乎不是一个东西,但两者之间有很多相似之处,到目前为止我们学习的一切东西都适用于文件和计算机程序,由字节信息组成,我们学习了整数如何存储,现在我们要了解一下字符串如何存储:
73 71 75 61 6C 6C 79 00 00 00 00 00 00 … 省略后续的 00
这串字符的意思是 squally,如果你查看字节,你会发现有一个十六进制字符代表 squally 中的每个字符,在这情况下,73代表s,71代表q 等等,还留下了一堆 00,这些零似乎没有意义,他们只是额外的空间,如果我们决定在编程时向单词中添加更多文本,这些 00 有一个特殊的名称,被称为空终止符,程序员必须决定一个单词可以有多少个字母,任何未使用的字母都只是零。
现代的编程语言比如 C++ C# Python 可能不会让你看到额外的零,只有一个零或者甚至根本没有。
你会注意到 73 代表 s,这是 ASCII 编码,你可以通过 google baidu 来找到对应的表!
Unicode
有些时候可能不使用英文来玩游戏,这时候想解决这个简单的问题不要困惑,所以有一个叫做 Unicode 的标准,可以显示我们想要在计算机上显示的所有语言,最流行的是 utf-8,因为它建立在 ASCII 标准上,utf-16 也十分流行:
- A - ASCII -> 0100 0001
- A - UTF-8 -> 0100 0001
- A - UTF-16 -> 0000 0000 0100 0001
- 日语a - UTF-8 -> 1110 0011 1000 0001 1000 0010
- 日语a - UTF-8 -> 0011 0000 0100 0010
如果我们用 utf-8 编码这个日语的符号,将会占用 3个bytes,使用 utf-16 将会占用 2个bytes。因此在 Hex 编辑器中,你可以选择显示文本和不同的编码
Example!
在之前的例子中我们找到了 Global.sqa 它就是我们发现的文件,我们先使用 Ctrl+c、Ctrl+v 进行备份,接下来我们使用 HxD 编辑器来查看该文件。
在这里切换每一行显示的字符数量
打开右侧的数据检视
编辑器会自动尝试将这些字节转换成 ASCII 字符,那么我们要在里面查找金币数量,只需要按 Ctrl + F 并输入 GOLD,找到1个匹配项以后我们就可以充分相信,这后面的数据存储的就是 GOLD,我们可以猜测,接下来的 4个bytes 存储的就是金币,因为大多数金币使用 int32 存储
举例在植物大战僵尸中,数据存储在 user1.dat 中,金币在圈起来的位置,修改后保存即可更改玩家的金币数量,在这里只是使用备份作为参考,修改后实际上并没有作用,需要进行内存修改!
注意,在计算机内部存在小端序和大端序两种数据排布方式:
- 小端序 Little Endian E7 03 00 00 = 999
- 大端序 Big Endian 00 00 03 E7 = 999
人类阅读和书写数字的顺序是大端序,但在计算机中往往是通过小端序来排布设置的,所以我们直接阅读 HxD 中的 bytes 数据是无意义的,但在数据检视中查看,HxD 会帮你排布好数据真实的顺序~
Value search
我们接下来讨论数值搜索,这次还是修改金币,但这一次通过不同的方式来做。我们很幸运可以通过 GOLD 这个字来获得金币,因为数据是按照字典方式来存储的,但如果游戏使用了不同的编程方式这就无效了
更可靠的办法是,我们通过金币的数值来搜索数据,记住我们的金币数值比如 679,然后按 Ctrl + F 在 HxD 中搜索整数,这就可以找到金币所在的位置了!
Health search
上面的情况是最幸运的,有时候我们不止有一个匹配项,这次试试把生命值从 8 修改到 16 吧,当你在文件中搜索 8 有时你会发现数百个匹配项,我们不可能一个一个修改保存尝试。
- 把你 8 生命值的存档保存,然后备份命名 8health.spa
- 去游戏里恢复或降低生命值,总之让生命值产生变化
- 打开分析工具,把光标放在同一开始的地方,按 F6 开始对比!
Conclusion
对于某些游戏,这两种办法可能都不生效
- 有可能游戏重启以后,玩家和怪物的对象整体地址会变化,可能会交换或者其他
- 第一种办法可行性更小,很多时候游戏不会编码字典
同时为了反作弊,可能会有其他办法阻止你修改
- Anti-cheat Integrity checks (checksums)
- Encrypted filles