半年前[tc]编写这个内存修改器的时候曾经遇到过一个重大问题,昨晚重新翻看的时候,人品爆发,找到了一个可称为“无奈之举”的方案,今天就写了出来。
[问题何在]
此前修改英雄属性的时候,力量、敏捷这两项属性代码十分简易,譬如下面是读取敏捷数据的代码:
6F13CE7B:
8b be a8 00 00 00 mov edi,[esi+000000a8]
然而“智力”却十分难修改,关键性代码有多处,其中最显眼的一处是:
6F088E78:
8b 42 78 mov eax,[edx+78]
可是不幸的是,这段代码并不仅仅是读取智力的,它似乎是一个函数,将一些离散的数据从堆地址传送到临时地址。因此,虽然这里面包含了我们想要修改的内容,但同时包含了许多其他内容。
另一方面,力量、敏捷、智力这三项属性,在内存分配上可谓是毫无联系,应该是动态分配得到的,实际游戏中无法从其中一个地址判断出其他的地址。
[人品爆发]
从大量的数据中滤出所需的“智力”地址,是解决问题的方案之一。
昨晚发现,在有限的时间里,经过6F088E78的代码的eax的取值是十分有限的一些数据,而不是任意多个数据。进一步观察发现,在这些数据中,智力的地址竟然是eax的最大值!
这一惊人的发现,促使下面的方案的形成。
[无奈之举]
嵌入的代码,不用问,和其他的代码是不同的。以往获取力量等属性的时候,一般是将寄存器的内容转移到内存里,以便查阅。而智力这一属性的地址,是“经过6F088E78代码处的eax的值”中的最大值,因此需要挑出最大的一个。
例如,针对上面的例子,获得敏捷的地址,可以嵌入下面的代码:
89 35 08 10 46 00 mov [00461008],esi
那么esi的内容将被转移到00461008处,此后只要查阅[[00461008]+a8],就可以得到并修改敏捷的值。
而针对智力,嵌入下面的代码:
39 15 14 10 46 00 cmp [00461014],edx
77 06 ja 00449E2E
89 15 14 10 46 00 mov [00461014],edx
<原来的代码>
那么edx的最大值将被转移到00461014中,在适当的时候取出[[00461014]+78]就可以获得并修改智力值了!
接下来的问题:什么是“适当的时候”呢?
[tc]无法给出准确的答案,目前的解决方案是:在敏捷获得后的3秒钟时间内获得的数据都是准确有效的数据。为什么安排在敏捷获得之后?主要原因是魔兽3经常运行6F088E78(智力)这里的代码,而不会运行6F13CE7B(敏捷)这里的代码,因此基本上只有运行了敏捷的读取程序才有可能运行智力的读取程序。
这种盲目性决定了本方案是一个“无奈之举”的方案。
[程序现状]
大体上程序就这么定型了。目前的修改器可以实时修改指定英雄的经验值、力量、敏捷、智力、移动速度、攻击频率等属性。事实上,[tc]还可以实现攻击力、防御力、攻击类型(如混乱、穿刺等)、防御类型(如城甲、英雄甲等)等属性,不过意义不大,[tc]没有编写程序。

1 条评论:
不知道你是通过什么来逆向的?SOFTICE?TSEARCH?还是其他什么?也不知道你用什么工具来查找内存地址的?难道就是游戏万能修改器?这软件我不能用,只能找了个俄罗斯人写的ArtMoney SE还勉强可以查查...
发表评论