C++实现11阳台魔兽全图外挂

魔兽争霸1.20E理所当然是一个很平稳的本子,不过国人似乎不热爱于付出娱乐而更保养于研发外挂,所以起始出现了dota“互通图”,这种技术相比低端,自己修改J文件,在HF建主挂机2天,让咱们几乎都下载她的盗版图。后来玩家知道了不和进入需要下载地图的主机玩,这几个人又发现了bcc校验,一中略显低端的异或校验,再简单的绕过楼台地图检测,他们发现竟得以任意修改J文件同时进别人主机不需要读图。
这里要说一下暴雪研发魔兽争霸时就筹划了一头机制,每个玩家的动作会发送给其他玩家,仅仅是动作,比如我打了你须臾间,可是爆不暴击仍旧miss就由每个玩家本地运算,为了使我们运算结果一律,游戏开端时会发给各类玩家相同的人身自由种子。咱们运算之后再将结果存在Game Cache(GC),这是公用的地方,要是您的和外人的例外,数据不同步,就会暴发网上大家一直在问的“11阳台检测到不般配”。
而是修改J文件之后你的充足数据是经过魔兽的合法函数修改GC的,外人也会听从这多少个数额测算,就应运而生了“不读主机地图,却可以剑圣无限无敌斩”的动静。
这自己没什么,不过牛逼的先后猿们又发现1.20的致命bug,J文件里能够运作任意机器码。通俗点就是自家修改了地图你一旦下载了自己的地形图和本身一起玩,我就足以通过这张地图格式化你的硬盘!
暴雪还是很负总责的合作社,登时推出了1.22,1.23接入版本,几遍测试后到底在1.24彻底解决互通地图问题,冰蛙的地图不扶助新本子魔兽(因为他还运用的是GC),也乘机魔兽的更新及时更改GC为当今的哈希表。
实则并未破解不了的先后,可是对于低玩的大家或者说外挂还不够发展的1.24E本子,如今结束刷钱秒杀修改属性等还不是很容易,因为不佳突破魔兽的联手机制。不过互通还是可以够实现的,即使魔兽争霸3摈弃了bcc换了高级一点的校验,但md5都能没破解,过地图校验没什么。
既然同步欠好过,那就干点不同台的事————开图!
你在此间开个全图是不会发送给旁人的,所以不会并发 数据非凡。值得注意的少数就是:开了图可以选中敌方阴影中的单位,这么些选中动作会发送出去,记录在拍照中,所以举报的话无疑。
多少魔兽地图本身自带反mh的,比如在不可见区域建立一个魔法特效,什么人看见了就表明什么人开图。但dota从没见何人打-AntiHack(-ah),冰蛙也不主修反mh,所以地图反mh这一关尽管过了。
那剩下的就是过楼台检测。
11阳台的检测机制自我没有研商,我是win7的微机,没开XT研商钩子,但从自己用的外挂来看有一点足以一定:各类房间的检测机制不一致。我在教育房玩从未被检测,但一去双线房立马被关小黑屋。
刚起初自我用CE间接修改人物属性,金钱,很洋洋得意,可是我修改过的数额假诺需要上传立刻被T,我还天真的想怎么能成就修改,后来一查资料心就凉了:以自己眼前的水平所能精通的唯一办法就是所有人同一时间修改数据,这不是废话么!
立时我就改成思路了,既然做外挂的都做不出来自我一个生疏更无法探讨出来,于是就很具体的把对象转向全图。
脚下网上能搜到的全图代码不多,百度文库有一份修改单机版的,依然修改game.dll的,修改完了后头每趟都是开全图,想不开都极度。我的目的是想开的时候才开。
于是自己就打起了自身使用的这些外挂的主张,没学过破解,不知情怎么分析汇编代码,可是好在他不曾壳,我领会这类外挂重要就是修改内存,不会涉嫌注入线程之类的,所以直接OD附加对“写内存”函数下断,花了半天时间找到了具有需要修改的内存地址,并记下了改动未来的值。
自家在网上查到说魔兽的不可见区域存在一个放在当地内存中的2维数组里,修改那里可以高达效果。
但据自己“破译”的自己这款外挂修改的内存来看,他改动的应有是函数,我看见了不少“e9”“90”字节。
如上是对本人2天来寻觅以及考虑的结果有个交代,下边的话说怎么用C++实现开图。
第一步,打开魔兽进程。
此间自己用自己事先帖子里提过的万能开首发现不好用了!网上一查发现权限不够,我就搜了一段提升权限的代码,之后就足以打开魔兽进程了(魔兽争霸3的窗口标题是“Warcraft III”,这一个三可糟糕打了!)。

初稿链接:http://blogread.cn/it/article/5920?f=wb

    如今在接手立异大家的精灵 AI
的底部模块。这部分谋划是希望得以由她们来一贯配备而不是提交需求文档让程序实现。

    大家的前一个本子有较大的性质问题,光是空跑一些面貌,没有玩家的情事下
CPU
符合都一定之高了。我觉得是允许策划的布置项过于细节,以及底层模块实现的办法不对,导致了大气没用的
lua 脚本空转导致的。

    如今的 AI 脚本是各样挂在独立的 NPC 上,利用心跳(大约是 0.5s
五遍),定期让 NPC
去思考现在应该去干些什么。那一个干些什么的现实逻辑在很细节的规模都是要去运转一个谋划配置的本子在一个沙盒中运作的。在骨子里监测中,一个心跳的一段
AI 脚本居然会跑上万行 lua 代码,想不慢都难啊。

    游戏支付和广大其他软件开发的一个高大区别就是,你不能把程序拿到正确结果真是任务的形成。运行时刻多次变成最紧要的封锁规范。假若一件业务在确定的年华片执行不完,代码实现的再正确都未曾意义了。而有的的优化热点往往也意义不大。因为只要只是急需小幅度的滋长性能,那么采购好一些的硬件就够了。一个模块的性质,要从数额级上的加强,必须另行考虑需要,改变需求,重定义大家要做怎么着。

    我说了算看看星际争霸2 的地形图编辑器是肿么办事的。

    我尚未玩过魔兽争霸3 的编辑器,也从未玩过星际 2
的。但如同,它们得以让用户自定义出各个花样的玩乐来,并不局限在 RTS
一种档次中。我深信这多少个发展了超过十年的自定义地图的编辑格局,一定有不少老谋深算的业务抽象。

    有限的刻钟内,我从没从网上找到太多的有关资料。在暴雪的官方网站也没能看到完好的文档。星际2
的编辑器内建了一个叫作银河(Galaxy)的脚本语言,似乎有着 GUI
界面上的编辑器操作,都足以全部的呼应成一段 galaxy
脚本。很可惜的是,暴雪似乎鼓励玩家用 GUI
编辑器创立地图,而脚本只是背后之物,galaxy 的手册我并从未找到。

    我不得不自己把弄编辑器,在友好的施用中,推想暴雪解决问题的笔触。短短两天的探究肯定会有众多谬误和疏漏,也期待借公开的
blog ,有行家看到可以赐教。


    简单而言,自定义星际2
的地形图,编写控制脚本的人是以上帝视角来对待世界的。脚本并不独立挂在单个
NPC 单位上。这和大家事先的统筹很不平等。

    自定义游戏,是由数量加代码构成的。数据包括了时局数据,放置在地形图上的单位,还有路径、点、区域等等类型的目的构成。这个足以很有益的用
GUI 编辑器生成。后边在代码中引用。

    而代码,是由一个个 Trigger 构成的。官方翻译为触发器。每张地图有多少
Trigger
,每个都有大局的名字,平坦的存在于地图的数据结构中。从编辑器角度看,这些Trigger
必须一开头一切实现好,在地形图加载时加载到内存中。后续代码能做的业务只是翻开或关闭部分
Trigger。

    从剧本角度看,Trigger
似乎是一个动态目的,能够动态变化,而不是一段静态的代码。可是编辑器里如同做不到动态创立Trigger ,看起来暴雪也不鼓励那种动态创造过程。

    Trigger 由事件(伊夫(Eve)nt) 条件(Condition) 动作(Action)
局部变量四有的组成。

    伊芙(Eve)nt
全体是足以枚举出来的东西,不设有自定义事件这种事物。所以在编辑器里能够透过菜单接纳。暴雪在编辑器设计上下了一番功夫。所有的事件都有一个英文短词用于脚本方法的概念,同时有一个长句子用来展现在编辑器选单中。依照使用者的言语,可以安排为比如中文的。另还有一段长说明,方便使用者领悟用途。

    伊夫nt
可以说一切是大局事件,比如单位死亡,单位受到攻击,单位进入区域等等,可以指定一个对象,也可以监督一类或任何目的。UI
事件也被纳入同一系列,比如有 UI 按钮被按下这种事件。

    伊芙(Eve)nt 可以说是 Trigger 的过滤器,系统精晓如何时候该考虑怎样 Trigger
可能需要举办。

    Trigger 是否被触发还需要看条件是否被知足,这就要看 Condition
的布局了。如果你需要刺蛇被攻击时做一些如何,也可以定义 伊夫(Eve)nt
为擅自单位被攻击,再在条件里写上单位项目为刺蛇。

    Action
就是内需完成的一多元工作了。这个业务都是瞬发的,比如把单位移到你定义好的点,删除单位等等。

    不同的 Trigger 可以有所同等的 伊夫nt
以及同样的尺度,那么事件触发,且条件满足时,六个 Trigger
会同时运行。当然这么些同时是逻辑上的,内部如故有一个主次,我想见是一个近乎
coroutine 的体制来驱动的。因为 Action
里的事务都得以立即完成(这里有个例外,下边会涉嫌),所以不会有争论。

    这一个,即使要实施的政工是一个内需很长日子才能做完的动作怎么做?比如你需要把一个单位按定义好的移位速度,沿正常的寻路得到的路径移动到一个目标地。这就得引入指令体系这些定义。

    每个单位身上都有一个下令队列,保存的是一多级的指令 (order) 。指令和
Action
是两类完全两样的事物。比如让一个单位从此时此刻职务移动到一个点就是一个 order
,而把单位(不经过游戏内在机制)弹指移到不行点就是一个 action 。order
是在队列中循序执行的。在 Trigger 里能做的是充分一个 action,这几个 action
是把 order
参与队列中。当然加的法子有三类:清空现有队列,参加一条指令;把指令加到队列最终;把指令插入到当下职务(立刻实施,但不清掉原有指令)。

    Trigger 里可以有两个 Action ,它们只有进行顺序的。但 Trigger
之间可以出现。大部分 Action 都会即时执行完毕,只有一类相当的 Action
会把如今的 Trigger 挂起,只到基准满意才会履行后续的 action 。

    这类特殊的 action 叫做等待。方今我意识有两种等待指令。

    最常用的是等待一段(游戏)时间,比如咱们可以动用它在玩乐先河后 10
秒突显一行字。只需要把嬉戏先河事件加到一个 Trigger 中,在 action
里依次进入等待 10 秒,彰显文字。

    别的五个是等待一个 Trigger
被触发,以及等待一个标准化表明式成立。我难以置信它们可以用来 Trigger
间的协作,但并未深刻钻研商竟咋做。可是可以规定的是,Trigger
是图灵完备的,它能够有分支和循环(它们是特其余 Action)。Trigger
也得以看做是某种意义上的历史观函数,可以不给 Trigger
设置事件和标准化,而用一个 Action 直接运行一个 Trigger 。


    指令和动作的定义分离对自家的启迪很大。

    也就是说,基于 Trigger 的流水线控制是面对 action 的,而 Trigger
属于所有社会风气而不是单个对象。order 则是隶属在对象上,对象的流程控制用
order 组成。order 只能循序的排列在队列中,Action
则可以有千丝万缕的控制结构。

    如果我们需要让一个单位活动到 A 点,然后驻留 5 秒,再移动到 B
点。最近在星际的编辑器中很难简单完成。关键在于让单位停留一段时间,我从未在
order 列表中找到。假若要贯彻,大约是这么的。添加一个 order 让单位活动到
A 点。另外写一个 trigger 在单位到达 A 点时接触,在这个 trigger 内等待 10
秒,再发送下一个命令让其运动到 B 点。

    这里,倘使援助让一个让单位等待一段时间的下令,它和现有的等候一段时间的
Action
一定是两样东西。而大家前边的规划没有分别这两者,所以实现的很不根本。

代码:

  HWND hwnd = ::FindWindow(NULL,"Warcraft III");
  if (!hwnd)
  {
    MessageBox("请先运行游戏!");
    return;
  }
  DWORD processid;
  ::GetWindowThreadProcessId(hwnd,&processid);

  //提升打开魔兽争霸的权限
  TOKEN_PRIVILEGES tkp; 
  HANDLE hToken; 
  OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,&hToken);
  LookupPrivilegeValue(NULL, SE_DEBUG_NAME,&tkp.Privileges[0].Luid); 
  tkp.PrivilegeCount = 1; 
  tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 
  AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES) NULL, 0); 


  HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS,false,processid);
  if (!handle)
  {
    MessageBox("进程打开失败!");
    return;
  }
  

晋级权限这里我也没弄得特别明白,紧要就是先查看权限,在收获本进程访问令牌的句柄,之后升任权限。
其次步,获取基地址。
其一基地址是怎么2天时间里我也没去研商,是本人从外挂里反汇编出来的,用ce在魔兽里搜得到的。刚开始走了个弯路,ce里突显这么些基地址是“ntdll.dll+102480”,要先查到nedll.dll的基地址。这可苦于了,我最烦的就是枚举进程,没办法,硬着头皮搜遍互联网,发现大部分人都喜爱注入dll使用getmodulehandle,我讨厌dll,终于找到自己以为最便利的寻找目的经过里模块地址的法子(后来在编制外挂时废弃了,这里依然贴出来,因为有些外挂还是急需枚举进程的)。

代码:

//枚举魔兽争霸进程获取ntdll.dll基地址
  MODULEENTRY32 me32        = {0};  //枚举到的模块存在这里
  me32.dwSize = sizeof(MODULEENTRY32); 
  HANDLE hModuleSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,processid);//为目标进程照个快 //照,返回“照片”句柄
  CString modulename;
  if (Module32First(hModuleSnap, &me32))//这条命令是把照片里的第一个模块放进、//me32里,没有就不执行if
  {
    do 
    {
      modulename=me32.szExePath;   //找到的模块全路径,最后几位是模块名
      if(modulename.Right(9)=="ntdll.dll")//取全路径后9位
        break;

    } while (Module32Next(hModuleSnap, &me32));//与Module32First相对,   //继续寻找快照中下一个模块

  }
  CloseHandle (hModuleSnap);

新兴本人发现ntdll.dll+102480以此基址中不肯定每回都是+102480,我无奈了。后来又找到另一基址:War3.exe+0X6A4DC,这多少个好,因为war3.exe每一趟都是00400000,所以我们的基址直接取46a4dc.
其三步就是修改内存了。
因为要想达到可观的全图即大地图迷雾,呈现单位,突显隐形,分辨幻想,呈现神符等等需要修改20多处内存,这里自己只举个中外图迷雾的例证。
要高达去除大地图迷雾共索要修改1处内存:
[46a4dc]+0x74D1BA
此处原本的值我忘了,改过将来应该是:7015,修改2个字节。
上面我们用代码实现。

代码:

/*******************************大地图迷雾************************************/
  ::ReadProcessMemory(handle,(LPCVOID)(0X46A4DC),(LPVOID)&addr,4,NULL);
//读取基址中的数据到addr中
        base11=addr+0x74D1BA;  //偏移74D1ba是大地图迷雾,修改2字节       
  char ch11[2]={0x15,0x70};
  ::ReadProcessMemory(handle,(LPCVOID)base11,(LPVOID)&re11,2,NULL);
/*这一句为了关闭全图,我设置了char re11[2]为类成员变量保存原来的2字节,以便还原,         base11也是类成员变量,记录了修改的地址*/
  ::WriteProcessMemory(handle,(LPVOID)base11,(LPVOID)&ch11,2,NULL);

终极清理现场就好了。

代码:

  CloseHandle(handle);
  MessageBox("开启成功!");

图片 1

新建MFC添加个按钮,复制代码进去就ok了,我就不上传exe了,首假使被封了自家也用持续了。等自己假使把它的运转规律研究出来,可以随着11更新,我再把产品上传。

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website