矛与盾----热血江湖实现喊话功能

    这篇文章介绍喊话功能的实现, 游戏还是热血江湖。

1. 原理:

    游戏中, 喊话的函数应该是这样的:

void speak(string contex)
{

doSomthing(contex);

}

    我们要实现喊话功能, 只需要找到speak函数的地址, 压入参数然后调用之即可。

2. speak函数分析

    逆向工程都是从数据开始的。 所以我们首先用CE来分析数据。

    打开CE, 进行如下搜索:

image

    然后,用22222222222过滤

image

    这里我们发现0xD0A784和0x0470766c都可能为喊话内容的地址。修改者两个地址的内容如下:

image

然后在游戏中按下回车, 发现输出的是222222, 所以我们喊话内容的地址就为0x0470766C。

    接下来我们就可以分析是谁调用了这个地址的内容了。用CE查看是谁访问了这个地址:

image

    Ok 下,CE的使命完成, 下面轮到OD上场。

    打开od,附加进程, 首先分析0058735f附近的代码:

image

    这里分析得出,这里是字符串的预处理过程, 所以可以往上查看是谁调用了他。

image

发现是这里, 所以我们可以这样测试一下代码:

1 mov esi, 05FE6758
2 mov edx, [esi]
3 push 0d
4 push 0d
5 push 3ed
6 mov ecx, esi
7 call [edx+4]

验证一下是OK的, 所以这个位置就是喊话的call了。然后我们再来分析各个参数代表的意义,其中0x0D表示的是回车键的键值。

然后esi代表的意义呢, 我们用ce 搜索esi的值,发现如下:

image

所以ESI = [0X03D4A270]

一切OK了, 所以这里只剩下最后一步了, 往保存喊话内容的地址写入我们需要的字符串。首先我们往字符串的地址下一个内存断点,看什么代码往这一块地址写了值image

其中

image

所以在这里我们只需继续查找esi是如何被赋值的。

分析(CTRL+A)看是谁执行到了0043CA07,

image

我们验证一下:

image

发现是OK的。

所以喊话的内容就非常简单了, 执行往[[d0a988]+13c]这个地址写入所需要的字符串,然后调用喊话call就好了。

3. 代码实现

    有了前面的分析,代码的实现就非常简单了:

1 void CGameOperate::speak(char* contex)
2 {
3 int*tmp = (int*)(0x0d0a988);
4 char* s = (char*)(*tmp+0x13c);
5 memcpy(s, contex, strlen(contex));
6 _asm
7 {
8 mov eax, 0X03D4A270
9 mov esi, [eax]
10 mov edx, [esi]
11 push 0x0d
12 push 0x0d
13 push 0x3ed
14 mov ecx, esi
15 call [edx+4]
16 }
17 }

4. 总结

    这个功能代码实现是非常简单, 主要的工作量就体现在分析上。

posted @ 2011-02-20 21:05  sld666666  阅读(1510)  评论(0编辑  收藏  举报