CE修改Eternium永恒之金LUA篇

Posted Thuuunder

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CE修改Eternium永恒之金LUA篇相关的知识,希望对你有一定的参考价值。

CE修改Eternium永恒之金【LUA篇】

目录

本文将介绍如何直接修改钻石、金币、等级、冠军等级、装扮点数和新版本黄球的数量

一、加密分析

前面两篇教程中我介绍了通过修改任务奖励或者修改邮件物品数量来修改钻石数量而不是直接修改,是因为直接搜索得到的数据不是真正代表钻石数量的数据。直接修改的话会逐渐恢复成原来的数值。真正的地址中的数据应该是经过加密了。有没有办法找出加密算法和加密值的地址并对其进行修改呢?

我们先直接搜索钻石数,看看是什么访问、改变了这些地址:

这三条语句都属于函数Eternium.s86+211D0,用IDA看一下:

简单分析:

上图4个紫圈内的语句对ECX赋值。第四个是将ECX置零,第一、第三个紫圈中的函数都调用了第二个紫圈中的函数:


让我们看看第二个紫圈中这个函数sub_1000AD60:


其中dword_1071C860指向的是一个用于异或的数组,暂且称之为异或表吧:

一个4字节的整数加密存储后占16字节。DWORD指针V1指向前4字节,5至8字节是加密(异或)后的数据,9至12字节用于存储异或的数在异或表中的索引,最后4字节则是对加密后的数据的验证。

函数的逻辑大致是这样的:

至此,我们已经搞清楚了这些数据的加密方式,可以开始尝试查找数据并修改了。

二、使用LUA直接修改数据

1. 找到加密数值的地址

要想找到加密数据的地址不难,只要在CE中找到读取加密数据的指令,再查看指令访问的地址即可。

找到很多地址,其中一些还在不断地变化:

2. 使用CE运行LUA脚本

由于地址存放的是加密数据,再加上部分数据不断变化,如何确认这是我们要找的地址呢?我们可以通过LUA实现对数据的读取与写入:


下面是我写的用于查询和修改的LUA脚本,代码水平一般,大伙凑合着看。另外建议将代码复制到编辑器里看,Markdown的代码块似乎不支持lua的语法高亮。

-- 读取异或表
XORTableAddress = getAddress("Eternium.s86+71C860")
XORTable = 
for i=1, 64 do
    XORTable[i] = readInteger(XORTableAddress + i*4-4)
end

-- 读取某地址加密的数据
function ReadEncrypted(address)
	pause()
	encrypted = readInteger(address)
	XORIndex = readInteger(address + 4)
	XORCheck = readInteger(address + 8)
	unpause()

	if XORIndex >= 0 and XORIndex <= 63 then
		if ((0x186557FB * (encrypted + XORTable[(XORIndex ~ 0x3F) + 1])) & 0xFFFFFFFF) == XORCheck then
			result = encrypted ~ XORTable[XORIndex + 1]
			print(result)
			return
		end
	end
	print("Fail, wrong address!")
	return
end

-- 将数值写入指定地址
function WriteEncrypted(address, number)
	pause()
	encrypted = readInteger(address)
	XORIndex = readInteger(address + 4)
	XORCheck = readInteger(address + 8)

	if XORIndex >= 0 and XORIndex <= 63 then
		if ((0x186557FB * (encrypted + XORTable[(XORIndex ~ 0x3F) + 1])) & 0xFFFFFFFF) == XORCheck then
			encrypted = number ~ XORTable[XORIndex + 1]
			XORCheck = (0x186557FB * (encrypted + XORTable[(XORIndex ~ 0x3F) + 1])) & 0xFFFFFFFF

			writeInteger(address, encrypted)
			writeInteger(address + 8, XORCheck)
			print("Success!")
			unpause()
			return
		end
	end
	print("Fail, wrong address!")
	unpause()
	return
end

测试一下,读取之前列表的第一个地址,与钻石数量一直:


尝试进行修改:


修改成功!

3. 一些重要数据的地址

同理我们可以用相同的方法找到其他数据的地址。
先找和钻石一样一直在变化的数值:
右键点击钻石数量地址 => 找出是什么改写了这个地址 => 显示反汇编程序 => 右键点击代码 => 找出指令访问的地址,可以看到这样不停变化的数有5个,经过我的验证,前四个分别代表钻石、金币、冠军等级、等级,第五个尚不确定。


再浏览钻石数量的地址附近区域,装扮点数的地址位于钻石地址+40h处,新版本黄球的地址位于钻石地址+50h处



使用LUA读取、修改数据的方法到此结束。

三、不使用LUA直接修改数据

个人觉得上述使用LUA脚本读取、修改数据的方法有点麻烦,下面提供一种懒人修改法,不过不确定是否稳定。懒得折腾lua的玩家可以试试看。

1. 去除数据验证

通过上面的分析我们知道,每组加密数据中最后一个数作为验证,一旦加密的数据验证不通过则将数据置零。既然已经找到了用于验证的代码,我们就可以通过注入的方式移除验证。
找到比较计算出的验证位和存储的验证位的指令。

AOB注入:

激活脚本后直接修改加密的数据试试看:

钻石数量改变了,并没有置零。此方法可以,但我不确定是否稳定。

2. 自定义异或表使得数据明文存储

游戏数据加密只是通过简单的异或,那么如果用于异或的数为0,异或的结果就与异或前相同,是不是就相当于明文存储?

在逆向分析的过程中我发现,每次游戏启动的时候,异或表都会随机变化一次:

这个函数在程序刚开始运行的时候被调用,所以我们要先写好代码注入的脚本,再重启游戏运行脚本。

同样使用AOB注入:

重新启动游戏。注意:由于游戏刚开始运行的时候就会执行本函数,所以启动游戏的时候,要以最快的速度最小化游戏窗口到任务栏暂停游戏进程,之后打开CE选择游戏进程并激活脚本,最后再点开游戏窗口。


可以看到已经成功修改了异或表中的值。开启去除异或验证的脚本之后,尝试搜索明文数据并修改:


修改成功

四、补充说明

  1. 国外有大佬做出使用GG修改器运行的lua脚本并发在了GG修改器的论坛上,功能挺多并且还在不断更新,有兴趣的话可以看看。
  2. 我尝试对加密的钻石数量等地址进行指针扫描,但是并没有得到可用的结果。所以在文中采用通过指令找数据地址的方法。有兴趣的可以尝试找指针。
  3. CE的Lua文档在帮助里面,有问题的可以自行查询。
  4. 文中可能会有一些语病和措辞不当,还请多多包涵。如果发现错误或者有不明白的地方可以在下面评论,有时间我都会回复的。
  5. 游戏或CE的版本不同可能导致修改失败。
  6. 文中一些工具的下载地址:
    Cheat Engine 7.1 (官网)
    IDA pro (吾爱破解)
  7. 文中游戏版本1.5.5,版本不同指令地址也不同。Eternium.s86文件位于游戏安装目录,查看的时候可能需要用到安全选项卡。

以上是关于CE修改Eternium永恒之金LUA篇的主要内容,如果未能解决你的问题,请参考以下文章

CE修改Eternium永恒之金基础篇

CE修改Eternium永恒之金基础篇

CE修改Eternium永恒之金进阶篇

CE修改Eternium永恒之金进阶篇

网安工具篇:CE修改器详细使用指南(必看)

Lua性能优化