六_加密的原理及解密
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的成员,因此进入该函数寻找解密和偏移。
对比源代码分析后得到如下结果。