前几天有网友问我,在游戏找call的时候遇到了动态地址的call,无法下手了,
什么情况呢?就是每次启动游戏,call的地址都会变化。。。。。。。。。。
这样,这个call就没发使用了,注意原因就是 基址重定位 的问题,想深入了解的同学,请自行百度”PE结构“去吧!
这里,我那QQ斗地主角色版 为例 来讲一下,如何去找到基址会动态变化的call的方法,简而言之就是怎样可以有效的在每次游戏启动都能准确的获取到游戏的功能call的准确地址。
下面均以
为例,
另外本帖只做技术研究,请各位勿做他用!!!
找call的方法就不多说了,如果你连call都找不到的话,就不用往下看了。
-------------
(我是以经找好了,这个游戏喊话下send断点不好使,但是他们的程序哥哥在开发时候不太认真,打印了好多调试信息,所以,,,,你们懂的如何查找了吧)
。。。
1207366E |. 45 INC EBP
1207366F |. 50PUSH EAX/Arg2
12073670 |. 55PUSH EBP|Arg1
12073671 |. 8BCEMOV ECX,ESI|
12073673 |. E8 A8000000CALL 12073720\CUQG_ocx.12073720, 真正的游戏喊话call
。。。
我们找到的真正喊话call,如下:
mov eax,0AF20000 ; 申请一块内存地址,放入“123”的喊话内容
mov ebp,4 ; 喊话的长度是4
mov esi,105DCDD4 ; 这次游戏的平衡值
PUSH EAX ; 喊话内容
PUSH EBP ; 喊话内容长度+1
MOV ECX,ESI ; ecx平衡地址
CALL12073720; 这次游戏的call地址值(动态变化的,因为这个方法位于dll中,基址被重定位)
特征码:8B 54 24 10 6A 00 8D 4C 24 14 C6 44 24 50 01 8B 6A F8 找下面第2个call
然后测试一下,发现可以啦!
但是你也看到了,call的地址 两次游戏的启动,明显变化了,这是不符合我们预期想要的call结果
不止是call的变化了,ecx平衡值也是变化的(多试几次就会发现)
==========================================================
动态call地址变化,如何解决?
思路:这个游戏主进程是:ddzrpg.exe,然后喊话的call位于模块:CUQG.ocx中,
所以可以先找到 喊话call,单独位于CUQG.ocx的位置:addr1;
然后再在游戏进程中去获取模块CUQG.ocx的加载地址:addr2 ;
那么,最后这个call的地址就是 addr = addr1+addr2 (理解这一点是非常重要的)
解决:
思路有了就开始动手解决,先找单独CUQG.ocx中的 call地址;其次找取他位于游戏中的地址;
1.找CUQG.ocx中的call地址,方法:
OD直接附加CUQG.ocx(ocx也是属于dll动态链接库范畴的)
先把这个文件从游戏目录中拿出来:
用特征码搜索, 最后得到的地址是:10003720 ,我们所需要的有效地址实际上就是一个偏移值: 0x00003720
(上面这个步骤其实不用找也无所谓的,很明显就是 0x3720偏移)
2.找模块CUQG.ocx加载到游戏里面的地址,方法:
这个地址是因为游戏先把主程序加载到 0x04000000,然后再加载CUQG.ocx,所以只能被重定位了,这里就需要编程去取模块地址(句柄)了。
用到的一个函数是:GetModuleHandle( ) ,百度一下:
函数的声明
HMODULE GetModuleHandle(LPCTSTR lpModuleName);
功能说明
获取一个特定的应用程序或动态链接库的模块句柄,且这个模块必须已经被加载到调用者的进程空间中。
参数说明
lpModuleName 模块名称
返回值
如执行成功成功,则返回模块句柄。零表示失败。通过GetLastError获得错误信息
注意
前提是:只有欲获取的模块已映射到调用该函数的进程内,才会正确得到模块句柄。常用模块映射函数:LoadLibrary(..)。
这第二步是最重要的,我只给大家讲好思路,剩下的就是你们去编程了!就是去拿到 CUQG.ocx模块在游戏进程中句柄即可。。。。
=======================================
以上两步就可以找到喊话call的地址了!!!! 本次游戏中的句柄是 120F0000
=======================================
另外还有一个重要的ecx平衡值需要解决:
[105DCDD4]=1212 6F48
[105DBBBC]=1212 6F48
[105DBEB4]=1212 6F48
这是一个很头疼的问题,目前没有什么好的方法,可以发现这个地址对应的内容值是有规律的:1212 6F48(后四位固定,前四位是动态变化的)
这里类比一下找call的动态地址,很容易发现一个规律 12120000 - 00030000 = 120F0000 正好是找call时后的找的CUQG.ocx模块的载入地址(句柄)
这里注意有个 00030000h 的 差值,发现这个规律也就好继续往下做了
那么就直接内存搜索:12126F48,就会得到 ecx 平衡值;
我能力有限,关于找平衡值的解决的方法就是整个搜索内存了,方法很笨!也希望有大神指点一二。
(我尝试过使用OD跟踪,和CE跟踪这个平衡值,可惜没有找到)
=====================
最后的效果如下:
上面是用易语言写的测试程序,如需程序源码,请有偿联系作者吧!
再次重申,请勿用学的的知识去做非法勾当!!!