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

全部博文(65)

文章存档

2011年(4)

2010年(1)

2009年(60)

我的朋友

分类:

2009-11-19 15:29:54

作者:重楼
日期:2009-09-02

*所谓的call,其实本质上来说就是一条汇编指令.
*只要找到了关键代码的地址,传入适当参数,就可以借用游戏中已有功能来完成内挂的功能。




目标:武易的喊话CALL
目的:以喊话CALL更深入了解所谓的CALL参数.


问:写一个CALL,如何传入适当的参数?什么是适当的参数?是不是一定要按照反汇编代码来写?


好了,废话就不说了, 用OD载入游戏,武易  并 下bp send 断点.

在游戏中喊一句话,OD便断了下来.



 


好了,这里我们已经非常熟悉了,是send函数的内部,    我们再来看看堆栈中的情况



 


其中 11111111  是我喊出去的话的内容,喊话CALL一般比较好找,因为有比较明确的数据

好了,我们按CTRL+F9 返回



 

这里是第一层,这里是游戏调用 send函数的发包的位置,这里也不说了 我已经在前面几篇 详细的介绍用法.我们继续返回




 

好了 ,我们又来到这一层,这里 在上篇找打坐中也出现过,非常眼熟吧. 这里一层应该是封包组合之类的CALL 我们暂时跳过它.



 


这一层中,我们也在上一篇遇到过,上次断下来后是压入的加密后封包的内容.还有一个应该是时间戳一类的东西.(这里也是猜的,因为不经过深入分析,是无法确认最终的作用.)

*时间戳  是根据时间的变化 而变化的一个数值,经常被用来加在封包内,来检测 封包达到前后 ,或者用来验证封包的真伪.

好了 继续返回.


 


到了这一层,这里 OD显示了压入的封包地址中有我们喊话的内容 (因为写教程的原因不能暂停太长时间所以又喊了一遍,内容可能跟上面不同)

0047218F    68 F0A77001    push    0170A7F0                        ; ASCII "1111111111111"


这里 有一个地址 里面的内容是我们的喊话内容,我们来测试下 这个CALL是不是我们要找的喊话CALL




===========================CALL分析=====================


0047218F    68 F0A77001    push    0170A7F0   


这里 压入了 我们喊话的内容指针地址,这里到我们手里该怎么写呢? 是否一定要按照这个地址来写入我们的喊话内容呢?  其实不然,我说过,一个CALL只要压入适当的参数,他这里 需要的是一个喊话内容的指针地址,而并非一定要 系统指定的,所以我们可以自己找一个空白的,  或 在语言定义一个变量  然后取他的指针地址 来压入堆栈都可以.

这里我说一个用CE+代码注入器 写喊话CALL的 方法.


用ce  写入我们的喊话内容. 并用代码注入器调试.



 


随便 取一个地址 ,将类型改变为 文本型  然后内容 变成我们要喊话的内容



 

这里参数只有一个 我们已经弄好了,  push 4ED056    (4ed056是我选的 喊话内容地址,这里保存着我的喊话你让)

00472194    E8 D7B9FBFF    call    0042DB70


这里是CALL的地址 .  call    0042DB70

写完参数和 CALL地址后  我们还要干嘛?

当然是  看CALL内部是否需要调用  寄存器.



 


我们来看看 CALL内部调用了什么 寄存器 ,我在前几篇中用过很多次这种方法来找CALL所需要的寄存器.其实所谓的适当的参数就是如此,你想要什么我就给你什么~~

当 内部CALL  出现这种,mov ebx,eax    或者  push eax      这个时候 我们往上面看看有没有给EAX赋值的指令,如果没有 的话 ,那么我们需要给EAX赋值了.  因为EAX 本身并不带数据,除了几个特殊的寄存器外,寄存器本身就是用来给我们存放数据的,他本身并没有数据.



0042DB7D    50              push    eax          我们在第四行 找到这样一句,但是上面有一行给EAX赋值的指令所以 EAX一句不需要我们来赋值了.



0042DB83    64:8925 0000000 mov    dword ptr fs:[0], esp  ESP是堆栈指针  , 永远指向 栈顶,属于特殊寄存器,所以也不需要赋值.


0042DB8E    53              push    ebx  这里有一句 ,上面并没有赋值,我们来看看他的值是多少,喊一句话 进入CALL之后 发现EBX一直=0  .  在这里 我们先写入EBX的值=0 (经过后来我们测试发现不用给EBX赋值 也不会出错,这个可能是因为  这里的  PUSH EBX 只是保存寄存器环境用来恢复,或者说 寄存器本身的值为0  不需要写入他也等于0 . 我认为前者可能大一些 )


好了 其他就没了 .我们来整理下
 

push 04ED056   
call    0042DB70
add esp,4            不要忘了堆栈平衡  压入一个堆栈  ESP+4




 


这里 我们没有压入 EBX的值 也没有出错  看来 PUSH EBX 是用于保存寄存器环境.





频道的选择:  这里 我们发现压入的数值并没有频道的参数,如何选择频道呢?

这个时候我们就要不停的测试 来看看他是如何选择频道的.  首先我们在游戏的聊天频道换成喊话 ,在调用刚刚的CALL,  我们发现,喊出来的频道是 喊话 的频道.这个时候我们觉得应该是把频道参数放在某一内存地址里然后调用喊话的时候 在判断是哪个频道.如何用搜索频道所在内存地址呢?

用模糊搜索,  首先搜索 未知数值,  然后变化频道  搜 变化的数值  然后重复就可以了(这里跟找血的基址一样) 



 


这里我们发现有一个1 ,  数值很小 我们变化一下 频道内容 发现 当选择 不同的频道都有固定的值.这个时候我们就可以确认这个是频道的内容 ,我们换下他的值,然后 调用喊话  发现 已经在其他频道喊了.




 


这里 改成3以后  在 帮派频道喊话 , 不过我没有加入 帮派 所以 不能喊话.

=============================分析结束=================

好了 今天的喊话CALL就到这里.在这里有个不好的消息,告诉大家.其实这里的CALL地址在不同的电脑上地址也是不同的...如下图所示(下图是 同一版本,同一区 不同电脑 返回4层后的CALL)


 


发现了吧,参数是一样的 但是CALL地址却不同.这里还是跟上一篇的一样.看来这个游戏有点诡异啊...
人生就是如此,你做了很多努力,你还是会发现原来你做的都是无用功...

好了今天就讲到这里,我们来总结一下



总结:
* CALL的参数地址并不需要CALL本身参数的地址.我们只需要给他想要的,就可以调用这个CALL为我们所用文中我们所调用的这个CALL,传入的并非是他原型中的地址, 却能正确调用,那是因为这个CALL的适当参数 是给CALL一个 有喊话内容的地址,而CALL是不会管这个是不是原来的,所以 这个CALL的适当参数是压入一个喊话指针地址,便可.
阅读(1678) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~