这两天在写一个游戏辅助工具,卡在了找一个内存基址上。辛苦研究了好几天,各种已经掌握的方法都用尽了,还是找不出基址。最后定位到的地方是MFC71U模块,然后就无法继续找下去了。于是只能开始探索从未用过的新方法。我想,如果我的程序能像OD一样给目标进程下断点,然后读取寄存器的值就好了。网上搜索了一通,还没有找到解决办法,倒是网友们的一个思路提醒了我:就是在想要下断点的地方改写代码,跳到一块空白内存,然后在这块空白内存中写入自己编写的汇编代码,把想要的寄存器值写入到某个内存地址,然后再跳回去。经过这样处理以后,只需要读那个内存地址就可以知道断点处的那个寄存器值是多少了。个人感觉该思路可行,而且简单粗暴!马上上手进行实验。
下面截图是目标的源代码,其中ECX是要找的基址,总是找不到。EAX=[edx+4],EDX的最终来源是ECX,所以EAX=[ecx+4],这里我要跳过这个计算,直接获取EAX,效果一样。因为即使我获取到ECX这个基址,最终目的还是要得到EAX的值。
先在附近找一块没有代码的区域,因为要加入的代码不多,只需要连续20个左右内存单元即可。幸运的是下面不远处就有,地址是0x41EE54。(该文章为猛牛软件原创)阿里云9折优惠码:8JZ7BR
然后再修改自己要加入的代码:
经过这样的修改后,游戏执行到:
0041EDF3 8B4D 08 mov ecx,dword ptr ss:[ebp+0x8] ; 座位号
这句时,就会变成跳转到:0x41EE54这个地址,执行我自己写的代码,把EAX的值保存到我指定的内存地址,然后又跳回去执行他本来应该执行的代码。最后,我直接从我分配的内存地址就可以读到EAX的值了,所以也就不再需要找什么基址了。
修改完毕后先在OD运行测试,完美搞定!
以下部分是我给自己留的备注,方面明天继续工作时回忆。现在脑子不好了,睡一觉什么都忘。
可能因为游戏里面有2个不同地方会调用这部分代码,测试时,EAX可能会出现2个值。所以要判断出哪个值是自己想要的。经测试,[eax]是第一个桌子地址。[eax]或者[[eax]]总是一个固定的值,可以根据是不是这个值来判断。
以上方法经实际运用测试,已完美解决找不到基址的问题,还是我自己太菜了,个人感觉,大神们说的hook可能就是这样吧。
我分析过好几个棋牌游戏大厅,最后追这个ECX值,都会追到这个MFV71U模块
多年前的事了,现在棋牌还有人玩啊?我记得都挺假,而且大厅程序应该也都更新成其他语言的了。