外挂制作之------游戏DLL注入

先谈下游戏,游戏每个动作都会调用函数。比方游戏设计人员是这样设计游戏的: void zhixing() //执行函数 { dazuo(); ....... //@1 } void dazuo() //打坐函数 { jimi("...."); //加密函数 return; } void jimi(char *s) { //对s加密处理,赋值给str变量 fashong(str); //发送函数 return; } void fashong(char *s) { send(s); return; } 你要打坐,你就必须要调用相对应的函数。上面的游戏只要你调用dazuo()就会在游戏中执行打坐这个动作。 而通过OD可以把游戏执行在内存中的代码反汇编出来。比如说你下断点bp send,意思就是当调用函数send时就断下来。你断下来后,当你按1次ctrl+f9,就返回到jimi函数中,按第2次ctrl+f9,就返回到dazuo函数中,再按一次ctrl+f9,就返回到zhixing函数中的@1位置,这样,上一行就是dazuo的函数。 你就可以通过调用call 地址执行这个动作了。 而为什么要DLL注入呢? 因为win NT系统是每个进程独立的,只有自己进程才能执行(调用自己进程的函数) 你把dll注入到游戏进程空间,dll就可以调用游戏进程空间中的函数了。 再打个比方:你call 0072e7a8,就是执行本进程空间的0072e7a8位置的函数。 你如果不注入,而在自己程序中执行call 0072e7a8,也就是调用自己进程0072e7a8地址的函数,那当然有问题啦,游戏的函数全在游戏进程中。你外挂进程0072e7a8是什么,与游戏执行无关。 再谈基址问题吧。 游戏中任何数据都在内存中存在,不管是血,蓝,等级,怪物名字,地图名字,只要是数据。全在内存中。 只要你读取那个内存地址就能显示出血来。 其实说白了,游戏客户端显示的数据也是读取的内存中的数据而显示出来的。 struct renwu //人物结构 { DWORD xue; //血 DWORD lan; //蓝 DWORD dengji; //等级 ........ }; void init() //游戏初始化函数 { struct renwu *dwRW; dwRW = new struct renwu; } 游戏初始化了,dwRW在内存中的地址是固定的,这就是基地址 而new是动态分配的,谁也不知道系统会分配哪个地址给你。 比如说dwRW在内存中的地址是0026762e, 这样,你只需要 [0026762e]就可以得到dwRW结构的地址,偏移0就是血的地址, 偏移4就是蓝的地址,偏移8就是等级的地址了。 再谈谈f12呼出外挂吧。 想在游戏中按f12键呼出外挂,当然就是截取在游戏中按f12键的消息了。想到要截取某进程的某消息, 第一想法就应该是想到挂钩子。钩子就是hook,就是把游戏钩住的意思,比如你给游戏安装一个键盘钩子,这样,只要在游戏进程中的程序,有键盘消息,都会先执行你的钩子函数,所以,你只需要挂个钩子,在钩子函数中,判断按钮是否为F12,如果是,就显示外挂窗口,不是,就放弃这个消息,让游戏自己去处理。 如果只想在游戏执行后,在游戏中按F12,就呼出外挂,就必须把安装钩子和钩子函数写到dll,因为只有dll才能映射到别的进程空间去,exe程序是不行的,dll中的钩子函数映射到游戏进程空间去了,就可以只钩住这个进程的键盘消息了,(所以如果你不把安装钩子和钩子函数写到dll的话,就成了全局钩子了,全局钩子是钩住windows平台中所有的进程的,在任何时候你按f12,都会呼出外挂的

经验分享 程序员 微信小程序 职场和发展