在之前的文章里,我们讲到了基本的数据结构和已经函数调用相关的知识,下面我们对游戏的控件相关知识进行讲解。
控件数据的入手点比较少,因为他可变动属性很少,而且控件名字也无法直接看到,所以分析起来也相对比较难。常用的控件分析方式有两种,第一种是通过是直接通过能够触发控件点击的发包功能直接获取到控件点击CALL。比如通过交接任务CALL,在点击交任务时可以触发对话控件的点击,然后向外层返回,就可能会返回到控件点击CALL中。下面我们对某款游戏控件CALL与控件遍历进行分析。
首先打开任务NPC,并对话到最后一步提交任务处(如图)
通过明文包函数返回到交任务函数处,这里的明文包如果获取就不做讲解了 。点击提交任务,游戏断下(如图)
向外层返回几次后,可以得到一个在点击任意对话会断下,但是点击其他控件不会断下的函数(如图)
在此处断下不同的对话,并查看参数(如图)(如图)
这里的R9恰好代表对话的序号,说明这里就是对话CALL。我们继续向外层返回,找到一个点击任意控件会断的函数(如图)
控件点击CALL一般都是调用虚表函数的,而函数地址的来源则为当前控件的对象。
点击打开背包控件让游戏断下,观察函数参数(如图)
rcx来源于rdi,而rdi为函数地址的来源也就是控件对象,所以rcx为控件对象
rdx为结构体参数(如图)
rdx中有常量0x1000000C,控件对象,以及一些数值较小的常量,并不难分析。
那么接下来就是对控件对象来源进行分析。
有人可能会说,顺着函数向上分析控件对象即可。这种方法虽然也可能得到控件遍历,但是更多的时候得到的并不是完整的或者正确的控件遍历。分析控件遍历最好的方式还是在控件对象上下访问断点,往往可以直接断到控件遍历代码中。
在背包控件对象上下硬件访问断点,游戏断下(如图)
RCX来源于268F77C处的rcx+rax,在268F762处rcx又来源于shl rcx,4
在268F775处rax来源于[rdi+0D8]
也就是说控件对象来源于[rdi+0D8]+rcx*10
继续分析rdi的来源,执行到返回两次后发现再次来到了268F2D0函数中,也就是说这里是一个递归函数。为了能够跳出递归函数继续分析遍历来源,我们可以在函数头部下F2断点,当断到一个不同的返回地址后点击堆栈进行返回(如图)
返回后继续分析RCX来源(如图)
rcx来源于[rbx+rax+8],在此处下断后发现rbx始终为0,也就是说这里相当于[rax+8](如图)
继续向上分析rax,可以得到+58偏移,再向外返回几层就可以得到基地址(如图)
最终可以得到公式
[[[[[0x400e790]+48]+80]+58]+58]+8 控件遍历起始地址
后面只需要加入递归公式就可以得到所有控件对象。
以上就是直接通过发包函数分析控件点击CALL以及控件对象遍历的方法,但是这种方法有很大的局限性,后面的文章里我们会以其他的分析方式对控件相关的内容进行讲解。
控件数据的入手点比较少,因为他可变动属性很少,而且控件名字也无法直接看到,所以分析起来也相对比较难。常用的控件分析方式有两种,第一种是通过是直接通过能够触发控件点击的发包功能直接获取到控件点击CALL。比如通过交接任务CALL,在点击交任务时可以触发对话控件的点击,然后向外层返回,就可能会返回到控件点击CALL中。下面我们对某款游戏控件CALL与控件遍历进行分析。
首先打开任务NPC,并对话到最后一步提交任务处(如图)
通过明文包函数返回到交任务函数处,这里的明文包如果获取就不做讲解了 。点击提交任务,游戏断下(如图)
向外层返回几次后,可以得到一个在点击任意对话会断下,但是点击其他控件不会断下的函数(如图)
在此处断下不同的对话,并查看参数(如图)(如图)
这里的R9恰好代表对话的序号,说明这里就是对话CALL。我们继续向外层返回,找到一个点击任意控件会断的函数(如图)
控件点击CALL一般都是调用虚表函数的,而函数地址的来源则为当前控件的对象。
点击打开背包控件让游戏断下,观察函数参数(如图)
rcx来源于rdi,而rdi为函数地址的来源也就是控件对象,所以rcx为控件对象
rdx为结构体参数(如图)
rdx中有常量0x1000000C,控件对象,以及一些数值较小的常量,并不难分析。
那么接下来就是对控件对象来源进行分析。
有人可能会说,顺着函数向上分析控件对象即可。这种方法虽然也可能得到控件遍历,但是更多的时候得到的并不是完整的或者正确的控件遍历。分析控件遍历最好的方式还是在控件对象上下访问断点,往往可以直接断到控件遍历代码中。
在背包控件对象上下硬件访问断点,游戏断下(如图)
RCX来源于268F77C处的rcx+rax,在268F762处rcx又来源于shl rcx,4
在268F775处rax来源于[rdi+0D8]
也就是说控件对象来源于[rdi+0D8]+rcx*10
继续分析rdi的来源,执行到返回两次后发现再次来到了268F2D0函数中,也就是说这里是一个递归函数。为了能够跳出递归函数继续分析遍历来源,我们可以在函数头部下F2断点,当断到一个不同的返回地址后点击堆栈进行返回(如图)
返回后继续分析RCX来源(如图)
rcx来源于[rbx+rax+8],在此处下断后发现rbx始终为0,也就是说这里相当于[rax+8](如图)
继续向上分析rax,可以得到+58偏移,再向外返回几层就可以得到基地址(如图)
最终可以得到公式
[[[[[0x400e790]+48]+80]+58]+58]+8 控件遍历起始地址
后面只需要加入递归公式就可以得到所有控件对象。
以上就是直接通过发包函数分析控件点击CALL以及控件对象遍历的方法,但是这种方法有很大的局限性,后面的文章里我们会以其他的分析方式对控件相关的内容进行讲解。