六、加密的原理及解密
1、简单的加密解密例子
- CS1.6人物速度加密实现
首先,找到人物速度后,访问速度查看任何改写和访问的代码。
然后对这四条都进行自实现简单的加解密。
进行HOOK。
效果如下:
加密前
加密后
- 定位解密
访问速度。
根据自写代码可知,赋值为加密操作,读值为解密操作。因此查看取值代码。
根据游戏代码解密即可。
- 结论
用到的加密数据附近必定有解密代码。
2、PUBG解密
- Uworld
利用字符串SeamlessTravel FlushLevelStreaming
定位到代码如下:
根据官方源码可知,Uworld
在附近,但是这里看到是一个CALL
,因此交叉引用后分析外层,得到下图结果。
可知Uworld
来自(_QWORD *)(v1 + 160)
,但是这里并不是一个全局变量。看到上边sub_7FF77B03EE38
有对v1+160操作,因此进去看看。
发现代码调用了off_7FF77E5E7720
对a2,也就是Uworld
进行了处理,下边又调用了off_7FF77E5E7728
对处理后的数据进行二次处理。由于该处是UE4引擎对Uworld的初始化,但是游戏本身对Uworld有加密操作。因此变量qword_7FF77F9D96E0
为Uworld
,函数off_7FF77E5E7720
为加密函数,用于将加密后的数据赋值给Uworld
,又因为此处需要用到Uworld
,所以游戏又给他解密了,off_7FF77E5E7728
为解密函数。为啥不直接用a2
?别问,问就是不懂。
- GName
利用字符串ByteProperty
定位到代码如下:
从函数sub_7FF778C03450
开始分析
可以看到a2 / 0x40F0
,根据算法可以判定为0x40F0为Chunk_Size
,而且这里应该是在计算类名。既然计算了类名,那么肯定是需要GName
,看到代码对a1
进行了解密,并且看到将v3(就是除法计算好的结构) * 8加上 一个解密结果,所以可知a1是GName(Gname算法),追a1。
v2(也就是a1),被v1解密了一次,v1又从sub_7FF778C03830来,所以去这个函数里即可拿到GName。
- GObject、Index
利用字符串DebugCanvasObject
定位到代码如下:
很明显的一句v7 = off_7FF77DFDA628(1212074649i64, qword_7FF77F9988A8) + 0x30i64 * v11;
,0x30是FObjectItem的结构大小,v11就相当于遍历的i(0~9999),这里是在获取GObject中的某一个对象。根据UObject成员可知,index为对象下标,所以Index的偏移为0x34,解密代码为:v17 ^ (v17 << 16) ^ 0xFC17596F
。
- Class、Outer、FName
利用字符串CopyPropertiesForUnrelatedObjects
定位到代码如下:
对应官方代码为:
由于GetFullName有获取Class,Outer,FName的成员,因此进入该函数寻找解密和偏移。
对比源代码分析后得到如下结果。