4.游戏逆向-pxxx-得到GName偏移

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动!

本次游戏没法给

内容参考于:微尘网络安全

上一个内容:3.游戏逆向-pxxx-对照UE源码和IDA分析GName偏移(ida中calloff开头地址的说明)

上一个内容中通过下图红框找到了一段代码,那段代码应该是用来给GName解密的

如下图红框三行代码,首先sub_7FF7C24A7100是AddZeroed函数,然后AddZeroed函数是GName调用的,通过下图的传参可以看出v2是GName,v2的值通过off_7FF7CF1A9028得到的,在上一个内容使用CE查看了off_7FF7CF1A9028的代码,没有发现GName,然后off_7FF7CF1A9028的参数有一个v1,然后v1的值来自于sub_7FF7C24A7450,所以GName可能就在sub_7FF7C24A7450里面

双击sub_7FF7C24A7450进入,它里面很乱

通过返回值来推断谁是GName,返回值来自于下图红框的off_7FF7CF1B4120,所以接下来还是要进入到CE中查看

ida中现在的基址是0x7FF7BFF60000,得到偏移0xF254120

然后在CE中使用偏移得到 off_7FF7CF1B4120

添加完默认是十进制显示,右击选择Show as hexadecimal(中文意思是显示十六进制)

注意下图红框的才是函数地址,因为ida中off表示的偏移也就是mov rax [0xxxxx] call rax这样的代码,然后双击下图红框会弹出一个对话框,然后就可以复制地址了

然后右击选择Disassmble thhis memory region

然后会打开下图的窗口

然后按CTRL+G,把上方复制的地址,粘贴到下图红框,然后点击ok

就来到下图红框的代码

代码说明:这类操作常见于数据混淆、简单加密或校验逻辑

AddressBytesOpcodeComment
7FF46560160848 8D 05 A17D0000lea rax,[7FF4656093B0]将地址 7FF4656093B0 加载到 RAX 寄存器(但后续未使用该地址,可能是冗余或调试残留)
7FF46560160F48 8B CAmov rcx,rdx将输入参数(RDX 寄存器,x64 调用约定中常用作第 2 个参数)的值复制到 RCX 寄存器,后续操作基于 RCX 进行
7FF465601612C0 C1 27rol cl,39CLRCX 的低 8 位)执行循环左移 39 位。x86-64 中 8 位寄存器移位时,实际移位位数为 39 mod 8 = 7,即等效于循环左移 7 位
7FF46560161548 33 C9 34894998xor rcx,FFFFFFFF98498934RCX(64 位)与立即数 FFFFFFFF98498934 执行异或运算,结果存回 RCX
7FF46560161CC0 C1 25rol cl,37再次对 CLRCX 的低 8 位)执行循环左移 37 位。实际移位位数为 37 mod 8 = 5,即等效于循环左移 5 位
7FF46560161F48 33 C9 F80B6FF0xor rcx,FFFFFFFFF06F0BF8RCX(64 位)与立即数 FFFFFFFFF06F0BF8 执行异或运算,结果存回 RCX
7FF46560162648 8B C1mov rax,rcx将处理后的 RCX 值复制到 RAX 寄存器(x64 调用约定中 RAX 用于存放返回值)
7FF465601629C3ret函数返回,最终结果通过 RAX 传出

可以看出off_7FF7CF1B4120是一个加密操作,这里就有一个问题,为什么加密代码这么简单,这么短的代码进行加密很容易就给破解了,这个原因是,当前的代码位于UE引擎频繁调用的位置(反射机制),它不可能它也没办法去写复杂的加密,这样会影响性能,游戏玩起来会很卡,所以它只能写这种很简单的加密,然后还是没找到GName,写来继续看,如下图off_7FF7CF1B4120里有一个v32参数来自于off_7FF7CF1B4128,所以接下来就看off_7FF7CF1B4128

得到off_7FF7CF1B4128的偏移 7FF7BFF60000

进入CE使用偏移

如下图红框

代码说明:这段代码与上方off_7FF7CF1B4120的汇编逻辑完全互逆,off_7FF7CF1B4120是用来加密的,下方是用来解密的

AddressBytesOpcodeComment
7FF46560162A48 8D 05 817D0000lea rax,[7FF4656093B0]将地址 7FF4656093B0 加载到 RAX 寄存器(后续未使用该值,可能为冗余代码)
7FF46560163148 8B CAmov rcx,rdx将输入参数(RDX 寄存器,x64 调用约定中第 2 个参数)复制到 RCX,后续操作基于 RCX 进行
7FF46560163448 33 C9 F80B6FF0xor rcx,FFFFFFFFF06F0BF8RCX(64 位)与立即数 FFFFFFFFF06F0BF8 执行异或运算,结果存回 RCX
7FF46560163BC0 C1 DDrol cl,-37CLRCX 低 8 位)执行循环左移 - 37 位(等效于循环右移 37 位)。8 位寄存器移位时实际位数为 37 mod 8 = 5,即等效循环右移 5 位
7FF46560163E48 33 C9 34894998xor rcx,FFFFFFFF98498934RCX(64 位)与立即数 FFFFFFFF98498934 执行异或运算,结果存回 RCX
7FF465601645C0 C1 DBrol cl,-39CLRCX 低 8 位)执行循环左移 - 39 位(等效于循环右移 39 位)。实际位数为 39 mod 8 = 7,即等效循环右移 7 位
7FF46560164848 8B C1mov rax,rcx将处理后的 RCX 值复制到 RAX 寄存器(x64 调用约定中 RAX 用于返回结果)
7FF46560164BC3ret函数返回,结果通过 RAX 传出

然后通过参数可以找到一个全局变量,如下图,通过代码的逻辑可以看出,qword_7FF7D0BEF370它是最原始的GName,qword_7FF7D0BEF390是通过qword_7FF7D0BEF370加解密得到的,qword_7FF7D0BEF390所以也会是GName

说明:

为什么说qword_7FF7D0BEF370它是最原始的GName呢,它就不能是别的吗?这些都是通过经验猜测的,没有任何一个人可以通过下方的代码就确定它是GName,也没办法确定,我们没有源代码,没有源代码就没办法确定游戏中获取GName的代码特征,如果想要物理层面的确定只能去一点一点的调试,猜测也是猜对了,猜测的基本逻辑,首先UE源码中GName调用了AddZeroed,调用之前先调用了GetNames函数得到GName,从这一点可以看出AddZeroed上方附近的代码必定有一个是GetNames,并且附近的逻辑肯定都是为了去调用AddZeroed函数,如下图通过返回值的观察也验证了这个想法

然后通过分析sub_7FF7C24A7450函数里面的代码,发现是加解密,然后结合参数,最终找到了qword_7FF7D0BEF370和qword_7FF7D0BEF390,它俩又是全局变量,我们又是通过AddZeroed一点一点追到的,所以就猜测qword_7FF7D0BEF370是原始的GName

这里有一个论坛:https://www.unknowncheats.me/forum/index.php,里面有很多游戏的基址和分析,如下图当前游戏的基址偏移0x10C8F370,它用的是qword_7FF7D0BEF370

qword_7FF7D0BEF370的偏移:

qword_7FF7D0BEF390的偏移


img

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值