首页
论坛
课程
招聘
[原创]剑网三怪物二叉树分析
2021-1-5 21:36 4334

[原创]剑网三怪物二叉树分析

2021-1-5 21:36
4334

一、用ce找出怪物血量

1.png

 

已知怪物血量是可见的。攻击前先搜一次血量,每次攻击都搜一次。剑网三这个游戏是64位的,但是一开始是从32位转变过来的,大部分数据类型基本上都是32位的。所以用4字节搜血量

 

2.png
对这个地址进行访问,并且攻击怪物

 

3.png

 

任意找一条跟就可以了,我找的是我鼠标选中的这一条。根据经验,大致应该八成可以肯定这个r8是怪物对象,那么我们只要往上跟踪找出怪物对象的来源就可以了。这类情况我会选择偷懒上IDA。

二、dump游戏用IDA分析

可以用x64dbg附加上后,使用scylla插件来dump游戏内存。

 

然后拖进ida。注意用64位的ida。

 

跳转到刚才ce找到的相应位置

 

4.png

 

红箭头是刚才找到的位置。我们应该从这往上找到R8寄存器里值得来源。可以看到黄色箭头,R8来源于rax。根据经验rax来源八成来自于绿框的call。

 

所以我们进入call。F5

 

5.png

 

看到这个伪代码可以先观察一手。

 

已知这个call返回的是当前被攻击的怪物的对象。所以直接可以看result = v4[5]

 

这个可以看成v4 + 0x28

 

看到上面有个while循环。判断*(BYTE*)(v5+0x19)的值。等于1就退出循环。

 

再看下面的代码 判断 v5+8的值是否大于a2。a2来源于上一层的参数。

 

这个判断是和否都不会立刻跳出循环。会把v5的值存放在v4。而v4又是最后怪物对象的关键数据。

 

所以这个a2可以猜测是个标志。能够确认当前怪物的标识。那么这个while就可以看成是在遍历怪物了,通过标识取出当前攻击的怪物对象。这个结构结合起来已经很明显了,这是个二叉树。

 

v5[0]是左树 ,v5[2]是右树 ,v5 + 0x19 里的值等于1的话应该是树到尾部了。

 

那么只需观察最上面的参数a1。a1很明显是个二叉
6.png
树相关的值。

 

黄色箭头是刚才进入的call。

 

根据ida分析。我们需要寻找这个call的第一个参数。根据基础知识,可以知道第一个参数是ecx。那么就找到了红色箭头处。显而易见。接来下敲代码遍历它。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
void PlayClass::GetPlayTree(DWORD64 StartAddress,int LocalFlag)
{
    if (StartAddress)
    {
        if (ReadMemory<BYTE>(StartAddress + 0x19) == 0)
        {
            shared_ptr<PlayInfo>Player(new PlayInfo);
            DWORD64 PlayerObject = ReadMemory<DWORD64>(StartAddress + 0x28);
            strcpy(Player->m_Name, (char*)(PlayerObject + PlayNameOffset));
 
 
            if (ReadMemory<DWORD32>(StartAddress + 0x20) == LocalFlag)
            {
                Player->m_FlyStatus = ReadMemory<DWORD32>(PlayerObject + PlayFlyStatusOffset);
                Player->m_FlyValue = ReadMemory<DWORD32>(PlayerObject + PlayFlyValueOffset) / 100;
                Player->m_BestFlyValue = ReadMemory<DWORD32>(PlayerObject + PlayFlyBestValueOffset) / 100;
                Player->bIsLocal = true;
            }
            Player->m_Flag = ReadMemory<DWORD32>(PlayerObject + PlayFlagOffset);
            Player->m_Object = PlayerObject;
            Player->m_Hp = ReadMemory<DWORD32>(PlayerObject + PlayHpOffset);
            Player->m_BestHp = ReadMemory<DWORD32>(PlayerObject + PlayBestHpOffset);
            Player->m_Mp = ReadMemory<DWORD32>(PlayerObject + PlayMpOffset);
            Player->m_BestMp = ReadMemory<DWORD32>(PlayerObject + PlayBestMpOffset);
            Player->m_pos.m_x = ReadMemory<DWORD32>(PlayerObject + PlayXOffset);
            Player->m_pos.m_y = ReadMemory<DWORD32>(PlayerObject + PlayYOffset);
            Player->m_pos.m_z = ReadMemory<DWORD32>(PlayerObject + PlayZOffset);
            Player->m_Level = ReadMemory<DWORD32>(PlayerObject + PlayLevelOffset);
            m_PlayInfo.push_back(Player);
            DWORD64 TreeLeft = ReadMemory<DWORD64>(StartAddress);
            GetPlayTree(TreeLeft, LocalFlag);
            DWORD64 TreeRight = ReadMemory<DWORD64>(StartAddress + 0x10);
            GetPlayTree(TreeRight, LocalFlag);
        }
    }
}

7.png

结束

第一次发帖,好紧张,不要喷我。呜呜呜


[注意] 招人!base上海,课程运营、市场多个坑位等你投递!

收藏
点赞5
打赏
分享
最新回复 (18)
雪    币: 1195
活跃值: 活跃值 (2037)
能力值: ( LV6,RANK:158 )
在线值:
发帖
回帖
粉丝
L0x1c 活跃值 1 2021-1-5 21:46
2
0
龟哥无敌!站楼!
雪    币: 4504
活跃值: 活跃值 (489)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
如斯咩咩咩 活跃值 2021-1-5 21:51
3
0
剑网三:你号没了
雪    币: 626
活跃值: 活跃值 (1015)
能力值: ( LV3,RANK:32 )
在线值:
发帖
回帖
粉丝
qqzxc 活跃值 2021-1-6 08:28
4
0
L0x1c 龟哥无敌!站楼!
源神教的。我爱源神
雪    币: 626
活跃值: 活跃值 (1015)
能力值: ( LV3,RANK:32 )
在线值:
发帖
回帖
粉丝
qqzxc 活跃值 2021-1-6 08:29
5
0
如斯咩咩咩 剑网三:你号没了
我自愿加入西山居,志愿献身剑网三
雪    币: 11986
活跃值: 活跃值 (7855)
能力值: (RANK:600 )
在线值:
发帖
回帖
粉丝
有毒 活跃值 9 2021-1-6 09:05
6
0
剑网三:你号没了
雪    币: 626
活跃值: 活跃值 (1015)
能力值: ( LV3,RANK:32 )
在线值:
发帖
回帖
粉丝
qqzxc 活跃值 2021-1-6 09:46
7
0
有毒 剑网三:你号没了
号还在!!!我是rmb玩家
雪    币: 107
活跃值: 活跃值 (30)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
回忆心痛 活跃值 2021-1-6 09:53
8
0
你号没了
雪    币: 626
活跃值: 活跃值 (1015)
能力值: ( LV3,RANK:32 )
在线值:
发帖
回帖
粉丝
qqzxc 活跃值 2021-1-6 09:56
9
0
回忆心痛 你号没了

雪    币: 1704
活跃值: 活跃值 (2474)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
舒默哦 活跃值 1 2021-1-6 11:06
10
0
L0x1c 龟哥无敌!站楼!
雪    币: 1413
活跃值: 活跃值 (385)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
nekaxi 活跃值 2021-1-6 11:58
11
0
龟哥无敌!
雪    币: 327
活跃值: 活跃值 (154)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
天地豪迈 活跃值 2021-1-6 13:11
12
1
大佬 附上 工具 源码嘛
雪    币: 610
活跃值: 活跃值 (238)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
ugvjewxf 活跃值 2021-1-6 14:01
13
0
不错
雪    币: 28
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
万神fake 活跃值 2021-1-6 14:56
14
0
666谢谢楼主分享
雪    币: 129
活跃值: 活跃值 (83)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
艾米哈柏 活跃值 2021-1-7 12:10
15
0
我比较好奇,你是怎么处理他下断之后会卡到假死的情况的。
雪    币: 626
活跃值: 活跃值 (1015)
能力值: ( LV3,RANK:32 )
在线值:
发帖
回帖
粉丝
qqzxc 活跃值 2021-1-7 13:07
16
0
艾米哈柏 我比较好奇,你是怎么处理他下断之后会卡到假死的情况的。
不是假死,是因为剑三下了个全局消息钩子。你把钩子卸载掉按键盘就不会卡了,但是剑三收不到你的按键消息了
雪    币: 412
活跃值: 活跃值 (298)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
qdjytony 活跃值 2021-1-8 15:23
17
0
阿龟流批~
雪    币: 2548
活跃值: 活跃值 (1945)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
低调putchar 活跃值 1 2021-1-10 21:04
18
0
游戏中当LocalFlag的0x1e位(bit30)为1时((LocalFlag&0x40000000)!=0)就要开始搜索被攻击的怪物了,所以:
0x40000000就是ATTACK_FLAG了。
你是用的: 根->左->右, 先序遍历算法哈!好帖子!思路清晰!
雪    币: 0
活跃值: 活跃值 (63)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wx_子陵 活跃值 2021-3-1 11:41
19
0
很好的一种方式
游客
登录 | 注册 方可回帖
返回