注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

风雨夜归人

专业收集资料,个人爱好!

 
 
 

日志

 
 

外挂教程动态内存篇  

2009-06-20 08:30:51|  分类: 外挂学习 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

现在的游戏全是双地址效验内存,内存地址不断变化,现在E里面有很多模块,读写内存,取颜色,模拟键盘,模拟鼠标,如果内存是静态的,我相信各位全用不上API,就光用模块就能写出简单的内挂了,当然内挂的准确度还要看各位用什么样的方式来解决各种问题了,可是内存是动态的,每次启动游戏内存就全会变,我们不能每次让玩家来用金山游侠查找血地址输入到你外挂里然后再启动外挂啊,呵呵,所以下面我说说我是如何解决动态内存的,我说3个方法,第3个也就是我的疑问了!好了,不废话了,我进入正题!

第一种方法:在外挂里设置个编辑框,让玩家把自己的姓名或者游戏里的ID输入,然后点外挂初始化,好了,利用API去查找内存玩家的姓名ID等信息,找到后就能得到一个地址了,而后血地址,法地址等全是与这个地址有一个固定的偏移量的,在外挂启动的时候只要能把初试的地址固定,偏移量也就固定了,这个试用于征服这样的游戏,还要看游戏机制而言,不是万能的!首先要看在整个进程的内存中或者某模块进程中玩家的姓名或者ID是否是唯一的!

第二种方法就是比较笨的方法了,自己去用WINHEX截取模块内存和整个内存,全分析一下,分析模块中的PE头代码,然后在整个进程中去搜索这组字节集,出现了多少个就是在进程里有多少个子程序入口,因为模块头的代码与别的部分的代码绝对不可能吻合,并且有的程序入口的字节集是在整个进程ID里也是唯一的,因为某些子程序有着特定的返回值,好了,这个先不去管他了,找到多少个子程序入口后,你去用金山搜索血地址,然后用WINHEX来到这个地址,分析血格式,比如问道游戏的血格式;11 2D 00 00 15 3A 00 00 11 2D 00 00 15 3A 00 00 00 00 00 00 00 00 00 00 54

这里第一个和第3个112D代表血上限,并且是2D11的10进制,这里是倒着写的,而第2个和第4个153A是目前血的数值,也是倒着写的,你要把数据的格式分析透彻,好了,这里分析完格式就可以往上找了,往少找到一个刚刚查到的入口的代码,比如是54 01 2E 00 FF 1A,这里的地址是00400000,那就确定了004000000到这个程序的结尾之间是血的地址所在,那好,从血地址开始到00400000之间我们分析吧,在这之间你要去找到多次启动游戏固定不变且在整个进程内存中唯一的字节集数据(取这个信息是最艰难的一步,需要你的耐性和多次实践去观察分析,一定能找到的)好了,找到了唯一并且永远不变的字节集的地址了,算出血与他的偏移量,那么就可以干活了,后面的步骤就和第一种方法一样了!!!这类也不是绝对通用的,在问道里可行,也要看游戏的机制,所以大家要几种方法全试试吧!

好了,第三种方法是通用的,适合任何游戏,不过难度比较高,要对汇编有初步了解,会用反汇编工具,动态的我们叫动态调试,不管动态或者静态,全是反汇编,好了,下面开始,还是利用金山游侠,找到血地址,比如是:01B629CC,我去把这个数值修改成FF,回到游戏,游戏人物的血变了,那就说明我们的地址是正确的(当然不能用来修改游戏了,我们修改的是本地的数据,本地的血变了,而服务端你的血是没变的,当你血收到外部攻击或者你吃药,只要一变化,血就会回到原来的数值的,我们的目的是确定地址是正确的就可以了),既然地址是正确的,我就用SOFTICE下断点,bpm  01b629cc  w,这句话意思就是在内存这个位置写入数据的时候就会中断,好了,我们回到游戏,继续游戏,怪物打了我一下,游戏中断了,中断的地方是0212A1AA,我们看中断的这里有个eax,那我们就用d  [eax]命令来查看eax里的数值,当然了,如果你用的是Ollydbg那么就不用下命令来看eax里面存放的是什么了,直接就能看到的!我们看到里面出现了刚我们查到的血数值地址01b629cc ,那就说明在这个地址会给血数值申请一个存放空间或者改变一个存放空间,那怎么办啊.....EAX里的数据在这里无法直接调用出来啊,那我就要在外挂启动的时候写个补丁程序了,我要对内存进行操作,来把它固定,在内存里有个区域是空白数据的,好了,我们就利用这片空间吧,我要把EAX里的数值存放在055ea1a2这个位置,我们在写外挂的时候就可以直接访问这个位置来取数值,取到的数值就是血数值的内存地址了,那怎么写呢?在汇编里:0212A1AA   mov  055ea1a2,[eax]  这句话的意思就是吧在0212a1aa位置把EAX里的数值存放到055ea1a2这个领域来,然后我们在写外挂就象我上面说的,直接从055ea1a2这个地址里就能取到血的内存地址了,呵呵,我相信这么说大家应该能明白了吧?

★★★★★★★★★★★★★★★★★★★★★★★那么下面我的问题也产生了,请问高手这句汇编我应该在E里怎么写,E里怎么去嵌入汇编代码?谢谢高手指点!★★★★★★★★★★★★★★

写个dll.调用就行了.

临时字节 = 到字节集 ({ 104 }) + 到字节集 (内存地址 [3]) + 到字节集 ({ 255, 21 }) + 到字节集 (内存地址 [1]) + 到字节集 ({ 104 }) + 到字节集 (内存地址 [4]) + 到字节集 ({ 80, 255, 21 }) + 到字节集 (内存地址 [2]) + 到字节集 ({ 255, 208, 195 })

' 这里就是汇编的机器码。。。。。。。。。。。

====这是e写入=汇编的吧=================

.子程序 _按钮1_被单击

编辑框1.内容 = “”

窗口句柄 = API_寻找顶级窗口 (“SciCalc”, “计算器”)

输出 (“窗口句柄”, 窗口句柄)

线程标识 = API_取进程标识符 (窗口句柄, 进程标识)

输出 (“线程标识”, 线程标识)

输出 (“进程标识”, 进程标识)

进程句柄 = API_打开进程 (2035711, 0, 进程标识)

输出 (“进程句柄”, 进程句柄)

模块句柄 = API_取程序或DLL句柄 (“Kernel32.dll”)

输出 (“模块句柄”, 模块句柄)

函数地址 [1] = API_取DLL函数地址 (模块句柄, “LoadLibraryA”)

输出 (“函数地址 [1]”, 函数地址 [1])

函数地址 [2] = API_取DLL函数地址 (模块句柄, “GetProcAddress”)

输出 (“函数地址 [2]”, 函数地址 [2])

内存地址 [1] = API_申请内存空间 (进程句柄, 0, 12, 4096, 4)

输出 (“内存地址 [1]”, 内存地址 [1])

API_写内存字节 (进程句柄, 内存地址 [1], 到字节集 (函数地址 [1]), 4, 0)

内存地址 [2] = 内存地址 [1] + 4

输出 (“内存地址 [2]”, 内存地址 [2])

API_写内存字节 (进程句柄, 内存地址 [2], 到字节集 (函数地址 [2]), 4, 0)

临时字节 = 到字节集 (取运行目录 () + “\MYDLL.dll”) + { 0, 0, 0 }

内存地址 [3] = API_申请内存空间 (进程句柄, 0, 取字节集长度 (临时字节), 4096, 4)

输出 (“内存地址 [3]”, 内存地址 [3])

API_写内存字节 (进程句柄, 内存地址 [3], 临时字节, 取字节集长度 (临时字节), 0)

临时字节 = 到字节集 (“MYDLL”) + { 0, 0, 0 }

内存地址 [4] = API_申请内存空间 (进程句柄, 0, 取字节集长度 (临时字节), 4096, 4)

输出 (“内存地址 [4]”, 内存地址 [4])

API_写内存字节 (进程句柄, 内存地址 [4], 临时字节, 取字节集长度 (临时字节), 0)

临时字节 = 到字节集 ({ 104 }) + 到字节集 (内存地址 [3]) + 到字节集 ({ 255, 21 }) + 到字节集 (内存地址 [1]) + 到字节集 ({ 104 }) + 到字节集 (内存地址 [4]) + 到字节集 ({ 80, 255, 21 }) + 到字节集 (内存地址 [2]) + 到字节集 ({ 255, 208, 195 })

' 这里就是汇编的机器码。。。。。。。。。。。

内存地址 [5] = API_申请内存空间 (进程句柄, 0, 取字节集长度 (临时字节), 4096, 4)  ' 这里是把汇编机器码写到内存中!

输出 (“内存地址 [5]”, 内存地址 [5])

API_写内存字节 (进程句柄, 内存地址 [5], 临时字节, 取字节集长度 (临时字节), 0)

线程句柄 = API_运行远程线程 (进程句柄, 0, 0, 内存地址 [5], 0, 0, 0)

输出 (“线程句柄”, 线程句柄)

' API_监测对象 (线程句柄, 4294967295)  ' 这里功能是 等待远程线程运行完毕

我详细给你解释一下就是。 我们知道局部变量是临时的  也就是当这个过程晚了以后局部变量也就不会存在

一般的游戏是这样的   你要获取的诸如像血,蓝 这些都是全局变量,  在内存中本来是不会变的。!这个是对于C语言的编译器而言 而其他的高级语言比如  Delphi什么的  也不会这样处理了 他会动态申请内存! 而且游戏一般也用指针来指向一个结构 包括了血的 多少,血的剩余,和其他属性的 一些结构。 而真正这些结构的实质就是像易语言中的字节集  我们操作的时候实际上是根据指针在操作, 而且这个字节集决不会固定,那么在这种情况下,就只能找到读取 或者写入这个 结构的语句的地址 从而Smc一句  大概就是读取或者写入操作的同时 把要写入或者读取的值保存到一个内存固定的位置, 比如程序的代码段中  从有空隙的。  

通过这样方式来拦截。

 

  评论这张
 
阅读(686)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017