首先声明,本文重在记录写这么一个玩意的过程。因为恢复了系统,所查阅的技术上的资料地址已经丢失,无法贴出来与大家分享,但最后我会附上源码,代码我也已经做了比较详细的注释。为了操作API方便,代码是C++的,程序本身没有什么技术含量,大多内容也都来自网上,文中就不对技术方面过多的解释了,对键盘鼠标模拟关心的朋友直接看代码就可以了。       
    起因是一个哥们勾引我玩天龙八部游戏,3个月前他开始玩天龙八部,现在角色名字已经出现在排行榜上,他的几个同事也都在玩,无疑这是一个很好的环境,不由的动了心。 通常我会在了解了游戏之后,弄个辅助工具减轻一下工作量,玩征服征途的时候,都弄了个简单的补血补蓝,施放辅助技能,捡东西等,自动打怪还没有做过,这次想尝试一下,最简单的自动打怪是根据颜色来的,按键精灵就可以实现。按键精灵可以根据指定图片找到屏幕上相似图片的位置,对于图片的查找,一直没有搞清楚如何来实现,下过一篇论文,用到了小波变换,也没看懂,汗。不用图片当然也可以,那么这就要根据怪物特征色来判断,特征色就是屏幕上只有怪物才有的颜色。有了这个颜色,我们就可以搜索屏幕坐标的颜色来和这个颜色对比,如果足够相似,那么就可以认为是怪物,也就可以找到怪物的坐标,之后的事情就简单了,Attack之就可以了。
      接下来对这个大体思路要细化了,首先如何搜索屏幕坐标,逐行逐列挨个坐标搜索肯定不行,1280*800的分辨率扫描一遍要多久啊。看来不能挨个扫描,那就有个步长或者说是跨度,那么这就有个问题,那如果正好错过了和怪物特征色一样的那个坐标,就漏了这个怪了。那么对于颜色相似的判断,用RGB比较就不如用HUE来比较了,后者使用色调,灰度,饱和度来表示颜色。都是绿色,不管是深绿还是浅绿,他们的色调相差是不大的,也就是H值是差不多的,这样我们用这个来判断坐标在不在怪物身上就方便多了,毕竟我们取得怪物特征色并非只有一个点,一般会有一片都是类似的颜色。并且这样也可以忽略3D游戏中光照对于颜色的影响了。
      颜色比较的方案确定了,接下来考虑找怪的扫描方式。以角色为中心,往四周渐开扫描应该是最好的,这样可以找到距离自己最近的怪。在此呢我又多想了依稀,一般游戏都有小地图,小地图上会有角色以及周边怪物的表示,不论什么怪都是相同的标志,并且能看到的怪物也比屏幕上要多,而且小地图范围很小,逐个像素扫描也是很快的,于是考虑通过小地图来找怪,这样就牵扯到两个坐标系转换的问题,一个坐标原点是小地图角色标志,一个是屏幕中心,能把这两个转换过来就好,找怪速度会快很多。事实证实通过小地图直接找怪这个想法不现实,因为坐标的转换只能通过实践出来一个大体的转换比例关系,并不准确,更多的情况是能指到怪物旁面,并不能指到怪身上。那么只好通过以屏幕中心为中心,渐开跨度扫描怪物特征色的扫描方式来寻找怪了。经过测试,效果还可以。       
      接下来就只剩下鼠标键盘的模拟了,对于鼠标键盘的模拟,最简单的就是mouse_event()keyboard_event()了,同时结合SetCursorPos()就能搞定了,以前就这么干的。没多久,写好了,简单测试一下,ok了,能用了。晚上回到家,打开游戏,一测试,傻眼了,SetCursorPos还可以用,把鼠标如期放到怪物身上了,但是mouse_event()失效了。不小的打击啊,现在游戏放外挂,一般会屏蔽一些API函数。于是开始狂查资料,因为很少用C++,好多东西都不知道,查游戏如何拦截API,查注入,查如何反np,查如何hook API,还看了《windows核心编程》第19章和第22章关于dll和注入的一些,查模拟鼠标键盘的其他方式。很快 一星期过去了,也该回家过年了,关于api hook部分,会单拿出来一篇文章介绍一个简单的vs2005能编译运行的例子(ps网上能找个能运行又清楚的例子着实花了不少时间)。
    年后回来静静心,继续琢磨,到此,我已经用
SendInput()这个更底层的API,和WinIO驱动级模拟实现了,但是在游戏中始终不行,网上也说np可以封到内核API,因为WinIO用了特征码,又大名鼎鼎,也可以被np封了。那难道只能写鼠标驱动了么?不会写啊。我开始考虑我的思路出了问题。既然说mouse_event()被封了,那为什么不一起把SetCursorPos()也封了?下载按键精灵,装上,写个简单脚本,进入游戏,一试,再次傻眼,按键精灵竟然可以。又下了快电7,也可以,打开这两个程序的文件夹发现快电7应该用了自己的驱动级模拟,有个sys文件,但是按键精灵文件夹下有WinIO.Dll以及VXD文件,没有相应的Sys文件,dll文件的大小也比我下载的大了十几k,难道按键精灵重写了这个dll?换上按键精灵文件夹中winiodllvxd,发现程序可以照常编译运行,拿到游戏下依旧不起作用。难道是因为按键精灵的神盾保护了自己的进程不被注入?想到此,我觉得应该查看以下我的程序是否被天龙八部的保护程序给注入了以拦截我程序调用的API。于是从网上下了冰刃,查看的结果又大吃一惊,程序的进程干干净净,除了被安全卫士和灵格斯注入了以外没有其他任何线程。这就奇怪了,百思不得其解。        
    昨天,一怒之下下了好几个鼠标键盘模拟工具,有的可以,有的失效。终于有个键盘鼠标键盘记录的小软件引起了我的关注,软件很小,单独一个exe和一个配置文件,文件里有坐标值以及操作WM_LBUTTONDOWN这样的消息,难道用PostMessage()可以吗?试了一下不行,更加困惑了。一边琢磨一边拿他试,忽然发现一个小细节,在重播我鼠标按键操作的时候,按下和弹起的动作很清晰(游戏中鼠标按下鼠标会变样子),一个小手一勾一勾的,而我的程序完全不会看到有任何动作,因为按下和弹起之间没有一点时间间隔。加个时间间隔试试吧,Sleep0.1秒,一试,天,果然可以了,如果说我这篇文章还有一丁点值得你看的地方也许就在此了,遇到相同问题的朋友不妨在按键按下和弹起的中间加个延迟试试,或许能成功。这个看似很小很没技术含量的操作确着实花了我大部分的时间。做程序有时就是这么有趣。说到这也就没有啥好说的了,程序还不完整只有个大概的基本功能,还有几个地方临时用简单的不完善不雅的方案有待替换。另外对于屏幕没有怪或者怪超出搜索范围的情况,可以用先搜小地图移动到怪物附近再搜大地图的方式解决。        
    对基于颜色的动作式的外挂的学习和实践就到此为止吧,还有更重要的更有意义的事情去做,最后附上代码,希望对大家能有所帮助。
    源码:https://files.cnblogs.com/pcant/tlbb.rar 
posted on 2008-02-14 11:52  绿蚂蚁  阅读(7208)  评论(32编辑  收藏  举报