Chinaunix首页 | 论坛 | 博客
  • 博客访问: 249761
  • 博文数量: 65
  • 博客积分: 2758
  • 博客等级: 少校
  • 技术积分: 725
  • 用 户 组: 普通用户
  • 注册时间: 2006-02-25 00:23
文章分类

全部博文(65)

文章存档

2011年(4)

2010年(1)

2009年(60)

我的朋友

分类:

2009-11-12 18:58:04

2007-08-09 03:05
关键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断下来,然后按照上面的方法,马上就可以在堆栈中找到
ElementC.00573800 在第一行,而且这行的下面就在堆栈中显示这个call的参数,类似
Arg1 = XXXXXXXX
      Arg2 = XXXXXXXX
眼睛尖的马上就会发现,其中一个参数不就是我选的怪的ID嘛,另外一个就是相关的偏移,马上就可以确定这个就是call了。
拣物品、使用物品等也是类似的,全都是在第一行出现,其实原理很简单,因为是在堆栈里面,必须满足堆栈的处理原则,所以么先入后出,后入先出,呵呵。如果是一个新游戏可能一开始会觉得不太好弄,不过因为大多数程序员都有共同的毛病就是只要功能类似肯定就会选择对某一类动作调用共同的函数进行操作,只是传入的参数不同,所以看多了,很快就可以对哪个才是我们需要的真正call地址做出判断。有时候还有额外的收获,比如说,查找使用技能的call,由于距离怪还有一定的距离,所以要先移动,然后才打,于是会断下很多,其中大部分是w32_send,这个直接判断标题栏就剔除了,而剩下的断中,就包含移动的和使用技能的,注意观察堆栈中调用的参数,只用看第一个调用,很意外的还顺便把移动的call找到了。

阅读(1125) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~