查找某棋牌平台李逵劈鱼金币值内存地址的曲折历程

最近承接订做了一个捕鱼的辅助软件,如要读取玩家金币数值,但是查找对应内存地址的过程很曲折,可以说历尽千辛万苦才找到,走了不少弯路。所以将过程记录下来,防止以后遇到类似问题。

下图要找的数据,1000000是金币值,90的发炮时的炮弹大小,也就是打一炮用多少金币。

要查找的内存数据

要查找的内存数据

首先,按照惯例,打开CE,搜索金币值。然而却一个结果都搜不到,数据类型不管是4字节、8字节、浮点数、字符串,全都搜不到。然后根据变化规律,先模糊搜索,然后增加、减少数据,最后还是搜不到。

看来此路不通,得想别的办法。联想到游戏发炮时,应该会判断剩余的金币是不是够打一炮,所以根据访问炮弹大小的代码,应该能找到用到金币值的代码。然后我就开始了验证此想法。

首先,搜索找到炮弹大小的内存值。先搜索90,然后改变炮弹大小,再搜。几次过后就成功找到了这个内存地址。然后“查看什么代码访问了这个地址”,得到3个地方的代码访问了这个内存地址。

找到的炮弹大小内存地址

找到的炮弹大小内存地址

我打了3炮,第三行的代码执行了3次。所以我判断是这个地方附近就会判断剩余金币够不够发炮(事后证明:这个判断带我走了曲折道路,坑!)。

打开OD,定位到第三行代码的位置:0x4240e4。

读取炮弹大小的地方

读取炮弹大小的地方

经过一些简单的下断测试和猜测,这行代码下面都没有直接对比炮弹大小的代码,下面的几个call就第一个(call 00416CD0)用到了炮弹大小作为参数,这个call里面可能有解密金币数量的代码。所以在这里下断,先简单看一下它的4个参数都是什么,做好标记,然后跟进去分析。这个call里面又有好几层call,刚开始的代码还能看懂一些,但是进入里面嵌套的2层、3层call后,代码就越来越看不懂了。花了好几个小时,还是没有头绪。最后有个call就不想分析,直接F8步过,结果游戏进程终止了运行,应该是这个call里面有什么检查机制。我应该庆幸游戏在这里有个检查机制,否则不知道还要继续浪费多少时间。

分析第一个call

分析第一个call

因为游戏进程终止了,所以重新登陆游戏,再用OD附加。现在想想,刚才那个call内部太复杂,可能方向错了,可能是自己想错了。然后进游戏,把金币下掉,让自己的金币不够发炮。然后再在这个地方下断点。结果在游戏内点发炮时,这里不会执行。这就证明判断金币够不够发炮的代码肯定在这个位置的前面,之前的分析都是在做无用功。然后向上翻,逐个地方下断,测试金币够发炮和不够发炮时的运行情况。最后找到了判断金币是否够发炮的地方:

找到了判断金币是否够发炮的地方

找到了判断金币是否够发炮的地方

cmp dword ptr ss:[ebp-0x160],eax这句代码是判断金币是否够发炮的,其中[ebp-0x160]是用户金币,eax是要打的炮大小。然后再前面查找[ebp-0x160]的来源:

获取玩家金币的代码

获取玩家金币的代码

最后找到玩家金币值的来源是:mov dword ptr ss:[ebp-0x160],eax,eax的来源是call 004035C0

这个call内部的代码:

获取玩家金币call内部的代码

获取玩家金币call内部的代码

可以看到, 金币值来自一个和玩家座位号有关的地址。这个金币值的低32位和0xAAAAA969异或,高32位和0x29a异或,之后得到的数值就是玩家真实的金币值。真实金币值除了会临时在堆栈内存:[ebp-0x160]保存一下之外,不会保存在其他内存保存,所以用CE搜索不到。

总结:有的数值用CE搜索不到时,可以尝试先找到可能会使用这个数值的代码位置,然后下断点,断下之后再搜索,这样就可以搜到临时保存在堆栈内存中的数据,然后再分析这个数据的来源。这样可以少走弯路。

此条目发表在CE, OD, 反汇编分类目录,贴了, , , , 标签。将固定链接加入收藏夹。

查找某棋牌平台李逵劈鱼金币值内存地址的曲折历程》有 2 条评论

  1. 高安说:

    这篇文章很好 逻辑清晰有效

发表评论

电子邮件地址不会被公开。 必填项已用*标注

This site uses Akismet to reduce spam. Learn how your comment data is processed.