【干货】如何开发一款游戏修改器?11:初识vftable

文摘   游戏   2025-01-04 17:00   广西  
本期教程我们来一起分析一下技能CALL。我们将通过快捷栏数组相关的数据进行分析。通过观察快捷栏数组,我们可以间接地了解技能的使用情况。因为我们通过快捷栏数组来使用相应的技能,所以肯定会访问这个数组中的对象。因此,我们可以将其作为突破口来进行分析。
在分析思路方面,我们可以分成两种情况。首先是查找访问数组对象的代码,另一种是访问对象的 WIFTB 代码。至于后者,我们可能会在下一节课才讲解。
除了这两种情况,还有第三种情况,我们可以通过肾的发包来分析技能的释放。这种方法有很多种,我们可以尝试找出最方便快捷的方式。
接下来,我们将把需要的技能或动作放到技能栏上进行分析。例如,清风破、回城术以及运气回复等。我们将先尝试第一种方式,因为这种方式被使用得最多。如果不行,我们再尝试第二种方式。如果还不行,我们就转而尝试第三种方法,然后比较哪种更简单方便。让我们先从简单的开始分析,然后再总结结果。
当我们按下技能快捷键时,游戏会调用相应的技能。但如果当前快捷栏没有配置相应的技能,则按下快捷键是没有效果的。因此,当我们按下数字键一时,游戏肯定会访问背包中的第一个物品。我们首先读取背包中的第一个物品,因为它的下标是零。
理论上,当我们使用这个技能时,游戏会访问这个物品。我们可以尝试通过调试器找到访问这个地址的代码。然而,我们发现有两个地方不断访问快捷栏数组,但按下数字键后并没有新的代码地址增加。这可能意味着还有其他方式可以找到这个对象。
我们先尝试一下其他可能的地方。当我们停止其中一个地址的访问并重新附加后,再次按下数字键,但仍然没有新的代码地址增加。我们尝试了其他几个地址,但结果也一样。
可能情况之一是,所有的背包访问都是通过相同的代码实现的。这两段代码是共用的,既可能用于显示技能信息,也可能用于使用技能时访问快捷栏对象。由于它们共用一段代码,所以按下快捷键时不会出现新的代码地址。
如果我们要移动这个技能对象,那么可能通过以下两种方式之一进行。在这种情况下,如果这段代码是公用的,那么它可能是一个扩展或者一个函数。对于获取背包对象或者类似下标的操作,可能存在这样一个函数,但具体情况还需进一步试验和调试确认。我们可能需要在代码中插入调试语句来观察。实际上,通过反汇编我们也可以大致了解,其中函数的头部和尾部可见。然而,在调试工具中,我们可以清晰地查看到哪些地方调用了特定的函数地址,如15230和其他。我们停止这些调用,并着重标注。
通过调试工具进一步分析这种情况通常是少见的。一般来说,在访问技能栏时,游戏会生成新代码,但在这种情况下,我们需要在现有代码中进行分析。我们注意到在使用技能和上期教程的移动速度时,可能都会经过这里。由于地址415230被频繁访问,我们推测它可能被多处调用。因此,我们需要搜索所有调用了该地址的地方,这可能有三个地方。在确认后,我们需要对每个地方进行详细分析。

现在我们尝试另一种方法。我们将首先尝试通过访问快捷栏下的wife table来查找这段代码。如果我们能够定位到这个代码,我们就可以尝试从中分析出更多信息。我们先删除这两个断点。虽然之前的方法也有可能分析出结果,但可能会更复杂一些,可能需要返回到更高层次的地方。因此,我们现在尝试一个更简单的方法来分析。

如果我们无法脱离当前情境,我们可以选择强制关闭游戏并重新登录。好,我们重新开始。现在我们再次尝试读取第一个格子的内容。现在我们将第一个格子移开一下,观察一下这个对象。现在我们将其移回来。这个对象似乎涉及到waf tb,我们需要再次深入一层。这就是VF table的地址,即虚函数列表的首地址。接着,我们深入一层,这里包含了相关的函数。我们在这个位置设置下一个访问断点,然后选中兔子,按下技能键一。你可以看到它出现了一次。再按一次技能键一。好的,你看,这个时候我们正好两次经过这个地方。这种情况比较容易分析。我们暂时停止这个断点。

我本来打算在下期教程再介绍waf tb,但现在就提前讲一下。之后我们再详细分析。现在我们找到了关键点。在使用技能时,程序会经过这个点。至于EAX,它代表什么?是我们的wif ex,这里是我们的WIFB。我再看一下,EAX可能是我们的技能栏对象,而EDX则不太是技能栏对象。

那么这个1DX和1GX值实际上代表了我们这里技能对象的层级,也就是WIFB,即汉字的虚函数表指针。等会儿我们可以通过插入调试语句来观察这个指针,这是一个关键点。我们可以先退出C1这边的附加,然后交给我们的x debug来分析。
打开X32dd g,然后我们拷贝一下这个关键点的地址,这个地址是关键的。而1DX值实际上是我们取出的技能栏对象,这是因为在这个位置,1DX在分析时肯定代表了技能对象。因为只有在这种情况下,它才会去访问那个地址。
在这个地方,我们可以看到地址46C7A75A40,就是我们的第一个对象。我们查找的时候实际上是在访问这个地址的代码。所以,在这个地方断开时,我们可以看到EA X的值是3F60。嗯,我看一下,应该是E4X或者其他。但是这个地址被我关掉了。另外,你看我有没有复制出来,就是在这个地方时,1X等于多少。应该就是等于这个46C75S零的。我们下个断点就能够证实这个问题。
在这里下个断点,然后我们再次使用这个技能,按键盘上的E。在这里可以证实这个问题,你看EX就是46475A40,这就是我们的第一个。所以,我们之前的思路肯定是正确的,就是在使用技能栏动作或者技能时,肯定会去访问这个第一个。那么第一个的下标是零,是零。他是怎么访问的呢?我们从这里来分析。这个EX是这个库的返回值,这个扩的返回值。实际上,它就是访问这个数组,然后最后返回来的。这个EX就是从这个数组里面读出来的。这个数组我们已经在上期教程分析过了,就是这个数。所以,前面过来的时候,他就是从那个数组里面去读取的。
正是因为这个库,在这里,和我们之前标注的扩不同。我们之前标注了两个地方,一个是这里,第一个地方我标注了一个快捷的对象,但是第二个地方我没有标注。我刚好漏了第二个地方。我们下期教程再来分析这一节。
技能对象的访问,我们可以回到我们的VIP这里,EIP是215。现在我们在这里,技能对象被取出来之后,然后它调用的虚函数是我们的虚函数。那个额外增加了八的空间,就是5f tb指针加八的地方。它调用了这里。这一段很可能就是我们使用那个技能的地方,或者是使用技能栏里的动作。物品也可能使用这个地方。但具体情况我们需要验证,因为每次执行那个动作时都会经过这里。如果不是这里,那么就是更上一层。我们先试试这个地方。如果这里调用不成功,那么我们再返回到上一层看看。
我们找个代码注入器,断开,然后重新连接。我们随便选一个怪物,然后从这里开始。关于参数的测试,我们先取出第一格的对象。这是我们的第一个对象。我们反着写它,放到EX里面。然后我们不去判断它了,它肯定不是零。后面的代码照抄,很简单,只有第一个参数不同。然后我们确定注入到游戏里面看一下。移动到游戏里面之后,我们发现它调用了一次这个。如果还不明显的话,我们可以尝试打坐的。看一下打坐的对象,移动到这之后,打坐的对象就变了。
我们将打坐的对象替换进去。现在是这样,因为在移开窗口之后,它会暂停。我们注入代码后,现在移动到那边去,可以看到它已经实现了打坐,是吧?这个很明显。我们重新再试一下,调用,然后切换到游戏窗口。这是第一个,所以这个调用是成功的。如果不成功的话,我们就再到他的上一层看一下。
这是我们掌握的一个对象,这个是那个清风破。当然,这些值都会变化。虽然说它会变化,我们可以通过前面这个数据来读取它们。读到第一个,我们可以去调用这些对象,然后再把它读出来。他的名字好像我们之前也分享过。
那么,本期教程我们暂时到这里。通过这种方式,我们找到了一种方法可以用来调用这个技能的扩,就是通过技能对象的方法。另外的话,如果我们更深入地研究,应该还有其他的方法,或者是更上层的扩,或者是更下层的 call,都有可能能够实现相同的一个功能。


暮色的狐
这是一只高强度上网冲浪、高质量输出内容的狐狸。主打ACGN杂谈、技术干货分享、第九艺术鉴赏、网梗百科解析、情感树洞鸡汤、正能量价值观~
 最新文章