分类:
2009-11-12 18:58:04
关键Call的找法一直都是个不大不小让人头痛的问题,需要大量的汇编代码分析,还需要很多测试工作,当然还有一种变态的方法,那就是用OD断下后,把前前后后所有的call都测试一边,也能找到关键call,不过面对大量的call和无数次挂游戏,恐怕这个方法只能在理论上实现了。 那么是否有既不需要看大量的汇编代码,有能够经过有限的几个测试找到关键call的方法呢,下面我就把一种另类的找法送给和我一样的懒人和新手吧。 以50打坐和普通攻击的call查找为例。 启动OD加载50,进入游戏后,和传统方法一样,bp send下断,然后等待游戏断一次,按F9直到游戏正常运行(这里等待断一次主要是为了去掉游戏定时与服务器信息和其它信息的干扰),然后马上回到游戏,按0(默认0是打坐),游戏被断下,连续按4次ctrl+F9(通常游戏的前3层都是信息函数等东西,所以直接到第4层啦),然后按F8,此时按alt+k打开堆栈窗口,如下: 调用堆栈 地址 堆栈 函数例程 / 参数 调用来自 框架 0012F524 004542DB ElementC.0059E270 ElementC.004542D6 0012F528 0049959B ElementC.004542C0 ElementC.00499596 0012F538 005410C4 包含 ElementC.0049959B ElementC.005410C1 0012F550 00540E87 ElementC.00540ED0 ElementC.00540E82 1、有很多行,不过我们只需要关系第一行就可以了,其它的不用管,记录下0059E270,如果已经知道打坐的call地址,一看就知道我们已经找到了,不过现在我们架设是第一次找不知道关键call的地址,所以把0059E270记录下来,继续ctrl+F9,F8再进入一层,仍然是按alt+k,查看堆栈窗口,仍然只记录第一行得到004542C0,还是ctrl+F9,F8,alt+k再记录一个0049959B,一般来说游戏的call多在4-6层中,很少有再深的,而且还有另外的判断方法,因为单你再使用ctrl+F9进入下一层时,出现的call就不是单纯的地址了,而是类似call [xxxx+xxx]这样的形式,那么也就说明走过了,所以记录3层就够了。 2、第一步完成了,此时按F9让游戏继续,又断下来了,不过这个时候不用急着按ctrl+f9进入,直接按一个alt+k看看, 调用堆栈 地址 堆栈 函数例程 / 参数 调用来自 框架 035CFEC8 00568A60 WS2_32.send ElementC.00568A5A 035CFECC 00000500 Socket = 500 035CFED0 0C622008 Data = 0C622008 035CFED4 0000000D DataSize = D (13.) 035CFED8 00000000 Flags = 0 035CFEE8 0056DE37 包含 ElementC.00568A60 ElementC.0056DE34 第一行显示的是 ws2_32.send,原来是发送函数,所以不用再进入了,看一下CPU窗口的标题,显示的是CPU-t线程 0000000xxxx,记一下那个xxxx的数字,直接按F9运行游戏,又断下来了,此时看一下CPU窗口的标题,如果xxxx数字一样,说明还是发送函数一类的东西不用进入(你可以都打开堆栈窗口看看验证下),继续按f9运行游戏,如果游戏断下来了而且不是发送函数一类的就都进入看一下,和上面的一样记录下地址,最后直到不再连续断,删除断点,回到游戏,人物已经进入打坐状态,一般简单的操作只会有1到2个需要跟进的断,而复杂的操作可能多一些,不过如果你从简单的call入手,注意观察,复杂操作的call还可以通过总结再去除掉很多无关的断。 3、第三步,好了只有三个地址,而且都没有参数,直接调用测试吧,运气不错第一个0059E270就是了。呵呵,没有分析汇编代码找到了打坐的call 顺便找找取消打坐的call吧,仍然bp send,然后等游戏断一次,按F9直到游戏正常,然后进入游戏,用鼠标在其它地方点一下,游戏断了下来,4次ctrl+f9后按f8,alt+k,直接记录第一行, 调用堆栈 地址 堆栈 函数例程 / 参数 调用来自 框架 0F19FD88 00466D4C ElementC.0059E2B0 ElementC.00466D47 0F19FE2C 00455D8E ElementC.004668C0 ElementC.00455D89 0F19FE30 0F19FE7C Arg1 = 0F19FE7C 0F19FE38 005604D9 包含 ElementC.00455D8E ElementC.005604D6 有了经验就不再继续了,直接测试0059E2B0,果然就是取消打坐。 顺便说一下,注意上面的 0F19FE2C 00455D8E ElementC.004668C0 ElementC.00455D89 0F19FE30 0F19FE7C Arg1 = 0F19FE7C 这两行,如果是有参数的call,就是这样的形态,这里也就是call 004668c0含有一个参数。 普通攻击call的找法,和上面的类似,先选择一个怪,然后切换到OD,bp send,等游戏断一次,按F9直到恢复,然后按数字1(普通攻击默认在1),游戏断下,然后同样的方法,你可以找到 调用堆栈 地址 堆栈 函数例程 / 参数 调用来自 框架 0F19FDCC 00475F71 ElementC.0059DC30 ElementC.00475F6C 0F19FDEC 00475B8E ElementC.00475CE0 ElementC.00475B89 0F19FDF0 10B2A500 Arg1 = 10B2A500 0F19FE20 004639EC 包含 ElementC.00475B8E ElementC.004639E9 0F19FE98 0043A572 包含 ElementC.004639EC ElementC.0043A56F 还是在第一行看到了吗?0059DC30,直接就找到了普通攻击的call。带参数的call的找法,和普通攻击的相似,无非就是记录下来的地址可能会多一些,需要测试的也多一些,不过如果你能够对找出来的地址处的汇编代码进行简单的分析,那么也就还可以再排除大部分地址,减少测试量。 这就是利用堆栈进行关键call的另类找法。本来打算弄点图上去的,不过因为我很懒,也就算了,大家多动手测试下,相信很快就能够掌握一些东西,然后我们多交流共同提高。 比如找怪的call,bp send,等游戏断一下,然后f9恢复运行,切换到游戏,用鼠标点任何一个怪,OD断下来,然后按照上面的方法,马上就可以在堆栈中找到 |