逆向分析传奇4委托任务内存数据遍历[新增视频]
本帖最后由 泉羽 于 2022-3-9 21:05 编辑运行环境:
WIN10
涉及工具:
xdbg64
教程类型:
分析传奇4委托任务内存数据遍历
是否讲解思路和原理:
是
PS:此文仅供大家参考逆向分析思路。小白教程,大神略过。
以下为图文内容:
此游戏为传奇4国际版。游戏有支线任务列表和委托任务列表,这里主要分析下委托任务的内存数据结构。思路:通过接受委托任务CALL来寻找。为什么通过这个CALL来寻找呢?因为游戏要接受委托任务,肯定会像任务call传入任务ID参数。这样才能保证接受到不同的任务。
通过接受委托任务CALL,找到任务ID,再通过任务ID,就能逆向分析到委托任务遍历代码。
图文分析可能看起来可能不方便,新增视频分析:链接:https://share.weiyun.com/lP8jR9ET 密码:3iuyaq
一、先通过发包CALL找到接委托任务CALL发包CALL头部特征码:41 8B F8 4C 8B E2 48 8B D9
1.定位到特征码出,拉倒发包CALL头部下断。发现下断就断,发现R8是6D64就断。
2.设置个条件断点r8!=6d64, 3.回到游戏,点击接受委托任务。断下来。file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps54AF.tmp.jpg 4.CTRL+F9,返回上一层。返回这一层,发现就是接受委托任务CALL。分析下这个CALL,有三个参数。r8、rdx、rcx。file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps54B0.tmp.jpg 5.方便查看代码,先分析下模块。file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps54B1.tmp.jpg 6.由于我们的目的是找委托任务遍历。所以在这个CALL上下断,找下看看任务ID在哪个参数里面。下断后,进游戏,点“接受委托”,让游戏断下来。file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps54B2.tmp.jpg 7.分析这个CALL。R8是固定值,每个任务ID肯定是不一样的,所以R8肯定不是任务ID,应该是提交任务的类型数值。我们再看看rdx和rcx。00007FF63B7A12FB | 48:8B48 08 | mov rcx,qword ptr ds: |RCX是一个内存地址。00007FF63B7A12F6 | 48:8D5424 28| lea rdx,qword ptr ss: |RDX这段汇编,是加载了这个堆栈地址。每次调用这个CALL,都会向这个堆栈地址里面写入数据。那么写入的数据会不会有任务ID呢?file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps54B3.tmp.jpg 点击下下方的内存窗口,然后ctrl+G,输入rdx,跳到rdx看看里面内容。Rdx里面的值如下:0000005997F7D4F8 00007FF63F8C47E0 .... mir4g.&sub_7FF63C7750A00000005997F7D500 0000000000000000 ....0000005997F7D508 00000000003D3074 .=..8.F9让游戏运行起来,换一个NPC,再接个委托任务,断下来后,再看看rdx里面有什么不同。file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps54B4.tmp.jpg 断下来后,得到如下rdx内容:0000005997F7D4E8 00007FF63F8C47E0 .... mir4g.&sub_7FF63C7750A00000005997F7D4F0 0000000000000000 ....0000005997F7D4F8 00000000003D3E84 .=..对比上次得到的rdx内容,发现第三行是不同的一个数值。也就是rdx+10这的00000000003D3E84 就应该是任务ID。9.追rdx+10里面的值,就应该能来到任务遍历的地方。00007FF63B7A12F6 | 48:8D5424 28| lea rdx,qword ptr ss: |追这个值的思路:那我们先要下断,游戏接受任务断下来,再在内存窗口跳到rdx。然后取消断点,F9让游戏跑起来,然后在函数头部下断,然后F8往下走,看经过哪个CALL或者经过哪段代码,给rdx+10赋值了,那么rdx+10就来自那里。也就追到了任务ID。9-1:接下来操作下。先CALL上下断,然后游戏里面接受任务,断下来,内存窗口跳到rdxfile:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps54C5.tmp.jpg 9-2:取消断点,F9让游戏跑起来。然后来到函数头部下断,游戏里接受任务,断下来。file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps54C6.tmp.jpg 9-3:然后,F8,往下走,观察内存窗口。在什么地方给赋值了。发现经过 00007FF63B7A12BC | 895C24 38 | mov dword ptr ss:,ebx |这段代码,下方内存窗口+10的地方赋值了任务ID。说明任务ID来至于ebx。追ebx,往上看:00007FF63B7A12AF | 8BDA | mov ebx,edx |ebx来至于edx。file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps54C7.tmp.jpg 9-4:我们追edx,已经到函数头部了。证明来自上一层,函数头部下断。回到游戏接受委托任务断下来。CTRL+F9,返回上一层,继续追edx。00007FF63C0714DB| 8B53 08 | mov edx,dword ptr ds: |edx来自,追rbx。00007FF63C0714CB| 48:8BD8 | mov rbx,rax |rbx来自于rax,修改下表达式:。追rax。rax应该就来自于上面这个call00007FF63C0714C6| E8 356578FF | call <sub_7FF63B7F7A00> |进CALL,我们追rax。file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps54C8.tmp.jpg 9-5:回车,进入这个CALL,然后拉到底部ret地方。也可以在CALL上下断,F7进入,F8走到CALL的ret地方。我图方便,就直接进入CALL,拉倒ret地方。00007FF63B7F7A9B| 48:8B41 08 | mov rax,qword ptr ds: |Rax来自,修改下表达式:[+8]。file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps54C9.tmp.jpg 我们分析下:[+8]=任务ID。那么应该就是任务对象了。证明猜测,我们下断,回游戏,接任务断下来。然后内存窗口调转到rcx+8。我们转换成无符号的短整数,查看下数值。file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps54CA.tmp.jpg 果然在里面发现了跟任务对应的数值,7897任务要求战力,6820任务奖励金钱,2040任务奖励经验。file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps54CB.tmp.jpg 我们再转换成浮点数看看file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps54CC.tmp.jpg 我们发现了任务坐标也在里面file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps54CD.tmp.jpg 通过上面分析,那么就能确定就是任务对象地址。继续追rcx。我们发现在如图,箭头位置有个跳转代码:00007FF7C2A58507 | 75 E7 | jne 7FF7C2A584F0 |那这个跳转形成了跳转没呢?如果形成跳转,就很有可能形成循环。再加上跳转中间有rcx被赋值。已知又是任务对象地址。如果是循环,循环中rcx如果不断被赋值,那就会不断的产生不同的任务对象地址。那证明这个循环就是委托任务的遍历代码。我们在这个跳转下断:回游戏,接受委托任务断下来,发现跳转实现了。按F8直接跳上去,再按F8运行到断点的时候又跳上去,说明形成了循环。就说明我们上面的猜测对了。这段代码就是委托任务的循环遍历代码段。file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps54CE.tmp.jpg
10.我们继续追rcx。
lea rcx,qword ptr ds:
rcx=r9+rdx*8,因为是lea所以表达式不能加[]
要分别追下r9和rdx的来源
11.先追rdx,因为RDX就在上面被加载了值。
lea rdx,qword ptr ds:
rdx来源于rcx+rcx*2,对于这种表达式,我们可以直接改成rcx*3。为什么呢?
我们可以假定rcx为一个值,比如为3,那么就是3+3*2=9,就相当于3*3,所以
就可以修改表达式为:rcx*3,注意是lea,所以也是没[ ]的。
12.那么rcx的值是不是一个正常的数组下标呢,如果是正常的,我们编程的时候,就可以直接设置一个循环变量,
比如设置循环变量i 来代替,就可以不用追rcx的来源了。我们在这个代码下断,回游戏接受任务断下来,然后按F9
,观察右上角的rcx值的变化,多次按F9后,我们发现连7这个小数值都出现了,就可以确定是一个正常的数组下标。
那么就编程用I代替,不用追rcx了。
13.上面搞定了rdx来源。我们修改下表达式:
rcx:r9+i*3*8
那继续追r9的来源,往上看,r9被赋值
我们下断,回游戏重新接受委托任务,断下来。
跳转到rdx+168,发现rdx+168就是数组首地址,在rdx+168+8的地方有18B就应该是数组成员数。
14.那么搞定数组首地址,搞定数组成员数就可以遍历了。我们继续追rdx,看数组首地址rdx的来源:
在上面,发现rdx来源rcx,已经到函数头部了。
函数头部下断,回游戏接受任务断下来,ctrl+F9返回上一层,发现rcx来源一个基址
15.至此,我们完成了整个委托任务的遍历。但是在任务对象里面没发现任务名字。
那么说明任务名字肯定在另外的地方存放,或者有一种调用方式。下次来追下。
下面是我整理的表达式:
[+168] 数组首地址[+168+8] 数组成员数[[+168] +i*3*8+8] 任务对象地址[[[+168] +i*3*8+8]+8] 任务ID[[[+168] +i*3*8+8]+68]任务总需求[[[+168] +i*3*8+8]+34]任务需求战力[[[+168] +i*3*8+8]+D0]任务获得经验[[[+168] +i*3*8+8]+D4]任务获得金钱[[[+168] +i*3*8+8]+A0]任务坐标X[[[+168] +i*3*8+8]+A4]任务坐标Y[[[+168] +i*3*8+8]+A8]任务坐标Z
如果能讲清楚发包CALL头部特征码的分析过程就更完美了 大佬牛批!顶!! 感谢楼主 帮顶一下 谢谢分享 谢谢分享 谢谢分享 感谢楼主 谢谢分享 如果楼主能每天都分享一些,那就更好了