目录

XMD系列之技能真实名称遍历

XMD系列之技能真实名称遍历

上一篇文章里,我们对技能名字进行分析,得到了一个数组,但是经过观察,我们发现这个数组是一个临时存放的数组,只有当技能栏打开时才会显示当前一栏的技能,这样我们在获取所有技能信息时是很不方便的,所以下面我们要换一个方向找到真正的技能库遍历。

在之前找到的数组上下F2断点,并获取同一个技能的对象,我们会发现及时从新打开技能栏,获取到的技能对象都是一样的,只是存放的地址发生了变化。所以我们可以通过CE对这个地址进行扫描,并通过重新打开技能栏来过滤掉临时存放的地址。

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/640.png

分别在数据窗口中观察这两个地址,我们发现第二个地址的结构和临时存放的结构是一样的,也就是说这里就是拷贝到临时地址中的数组。

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/640-20211025114048391.png

在这个地址上下硬件访问断点,切换技能栏,游戏断到一个新的数组位置

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/640-20211025113956466.png

这里同样是一个+8偏移和一个*8+4的数组,在ebx+8处下断,观察断下的值,发现里面的内容是固定不变的,重新打开技能栏,ebx也不会重新生成。

我们继续分析ebx的来源,在上面可以得到来源于一个CALL的返回eax

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/640-20211025114041960.png

在CALL上下断,分析参数,发现这个CALL只有一个参数,而参数的值很可能就是技能类型的ID

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/640-20211025113956736.png

到CALL里面分析eax的来源,得到来源于局部变量[ebp-10],而这个局部变量在上面的以结构体参数传到CALL中并被赋值。

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/640-20211025113956809.png

到CALL 9CB360中分析来源,首先得到一个+10偏移

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/640-20211025114030037.png

继续向上分析,可以得到一个数组套链表的结构

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/640-20211025113957161.png

对代码的走向进行分析,可以得出数组套链表的节点+8中存放的数值会反复的与外面传入的技能类型ID进行比较,所以说这个位置存放的就是技能类型ID

执行到返回后,继续分析ecx的来源,可以得到+20偏移

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/640-20211025113957261.png

再次执行到返回可以得到基地址

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/640-20211025114023209.png

既然得到了基地址,是不是说我们的分析结束了呢?

不!还没有结束!

我们对数组套链表的结构进行观察后发现,这里的元素和节点实在是太多了,我们需要继续分析传入到CALL中的技能类型ID的来源

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/640-20211025113957636.png

我们执行到返回后得到了一个数组

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/640-20211025113957691.png

直接用CE扫描这个ebx可以得到一个基地址

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/640-20211025114013577.png

接下来分析数组里面元素,可以得出以下公式

[[0x047CECD0]+138]+n*4+4技能类型

n=1为1转类型ID

n=2为2转类型ID

n=3为3转类型ID

n=4为4转类型ID

而0转的技能类型所有职业都为0

可以说,追到这里我们就已经可以通过关联来获取到完整遍历了,但是如果为了提高一点代码效率,我们可以用技能类型ID经过加密计算获取到数组套链表的数组下标,这部分代码就在数组套链表的上面

https://cdn.jsdelivr.net/gh/xinqinew/pic@main/img/640-20211025113957925.png

最终我们可以整理出公式如下

技能类型ID 循环右移5 得到结果为G

[[[0x03CF46D8]+20+4]+(G%[[0x03CF46D8]+20+8])*4]+4链表

[[[0x03CF46D8]+20+4]+(G%[[0x03CF46D8]+20+8])*4]+8ID

[[[0x03CF46D8]+20+4]+(G%[[0x03CF46D8]+20+8])*4]+10对象

链表+4链表

链表+8ID

链表+10对象

当ID==技能类型ID时,取出对象

==========================

[对象+8]-4技能数组元素数量

[[对象+8]+n*8+4]+4技能ID

[[[对象+8]+n*8+4]+8]+0技能名字ASCII

完整的技能遍历已经获取到了,虽然有些复杂,不过成就感是慢慢的,当然如果有小伙伴觉得这个办法太麻烦,也可以用传参调CALL的方式获取,被检测到了不要哭哦。

从安全角度来讲,这个部分正向代码的设计其实要比逆向麻烦很多,如果能在关键的CALL中加入弱VM并加入本地检测,会得到意想不到的效果。

玩游戏,学逆向,做安全,欢迎感兴趣的小伙伴关注我们。

没看够?

可以加入我们QQ直播群:805981646

每晚都有免费的公开课

欢迎大家加入