前些天玩了一下某一网游,其中如果选择的是法师职业的话。在每次释放魔法时都会出现一个对话框,其中有一排字符串,也就是所谓的咒语。你可以选择是否输入这段字符串,输入的话可以加快魔法的释放威力和释放速度(瞬间释放)。但是,字符串是随机改变其中大小写的组合的,一旦输入错误,魔法将无法正常释放。所以,就并不能使用类似按键精灵之类的软件来辅助完成咒语输入的工作。因此,Do 1t By m7Se1f  !
        首先,我的思路是找到咒语字符串在内存中的地址。当然,工具必选OD(ollydbg--该工具是Ring 3级的调试工具,使用起来比softice方便一点。)。该网游是由一个登陆程序launch的,所以就使用OD附加程序来调试该网游。要找到咒语字符串的地址是相对比较简单的,只要在游戏中释放了一次之后,回到OD中,在内存中查找相应的字符串就可以了。第一步很快就完成了,找到了关键的咒语字符串地址:0x000e91b4。
        接下来,就要实现从内存中读出字符串,然后模拟键盘操作。问题也就随之而来了,起初本想安装一个全局键盘Hook,用于截获释放魔法的快捷键的动作,因为快捷键是设置在F1~F12之间的,但是试了好多种常用的方法,结果还是拦截不下来。难道是系统按键需要用其他的方式,WH_KEYBOARD_LL?等改天再学习一下。之后,我用键盘钩子截获普通的字母按键,例如V,C,X之类的。然后再去模拟F1~F12按下,从内存中读出咒语,然后再输入到对话框,完成一次瞬间释放魔法。
        模拟输入的问题随之而来,无论使用PostMessage(HWND_BROADCAST,..........)、keybd_event、KEYBDINPUT都无法定位于咒语输入窗口。因此,就需要用SPY++来帮忙,使用SPY++可以很容易的记录下程序窗口的动作,我只须正常输入(自己用手指XX)些字符到咒语输入窗口既可找到该窗口的句柄,然后再到树形视图察看咒语输入窗口是第几个Child,以方便使用GetWindow( )来获取咒语输入窗口的句柄。至此,只需用PostMessage( )即可实现了咒语的输入。
        但是,从始至终我却忽略了一个重要的问题。Hook的处理的概念,即当系统拿到了一个通知,就将其处理好,然后再返回到主程序中。因此,钩子处理先于咒语字符串的更新,所拿到的是上一次的咒语,自动输入了的字符串永远都是错误的。也就是因为这一问题--字符串的更新,我想到了一个更加方便快捷的办法。WriteProcessMemory( ) ,ReadProcessMemory( )的结合。大家也应该不言而喻了吧。对,因为我们已经知道了咒语字符串的地址,用WriteProcessMemory把字符串的第一个字节修改成0xFF,然后使用timer监视,只要ReadProcessMemory出来的字符串首字节不是0xFF,就向咒语窗口PostMessage,完成之后再将咒语修改,继续监视。
        至此,大功告成!