动机
作者自己是一个DotA 爱好者,某天希望使用某个零X 魔兽助手做一个卡尔的改键脚本,
结果发现他提供的函数无法判断动态添加的技能的状态。在抄起 OD 跑了半天以后,突然醒
悟,为什么一定要修改,不自己写一个呢? 于是在做了一定的工作以后,最终的目标就慢
慢的变成了外挂。
达成目标
既然是外挂,当然要实现一些邪恶的功能~ 这篇文章里,外挂实现了这几个功能:不停
地在小地图上提示敌方英雄位置,神符刷新的时候提示位置和种类,提示Roshan 复活。 外
挂本身也要有一定的隐蔽能力,嗯,无进程无线程无DLL无补丁,听起来很隐蔽吧。
基础知识
如果你玩过魔兽的地图编辑器的话,应该会知道里面有一个东西叫做“触发编辑器”,地图
的行为都是在这里面定义的。实际上,当地图保存以后,这些触发都会被转换成一种脚本语
言,叫做 Jass,这就是地图制作者口中常说的T和J(Trigger, Jass)。
Jass中有两种函数, 一种是通过function命题定义的函数,另一种是通过native关键字
声明的函数。前一种就是一般的函数了,后一种叫做“原生函数”,是魔兽自己实现的,而
不是用脚本写的。 native和Jass的关系就像Windows中Native API (系统调用)和ntdll.dll
中转发函数的关系差不多。对于Jass 来说, native就是脚本与魔兽之间沟通的桥梁。
即使知道了这些函数,也不能随便的调用。比如,在网络对战的时候,如果通过SetUnitX/Y
或者其他类似的函数强行设定某个单位的坐标,就会触发 Desync 而掉线了。所有 extends
handle 的类型,以及随机数(GetRandomInt之类的),是必须同步的,否则就会掉线, string、
integer、real 等类型可以不同步,一些函数,比如 DisplayTimedTextToPlayer,
PingMinimapEx等等,是可以非同步的调用的,这两个函数也是下文需要用到的函数。
经过测试,这些Jass native可以直接调用,与在Jass中调用效果相同。
War3 逆向分析
注:以下所有的地址,都是基于魔兽争霸1.24e的。
既然知道了有 Jass native 这种东西的存在,那么上哪里去找他们的地址呢?祭起 OD,在
Game.dll的领空用Ultra String Reference插件扫描一下,随便查找一个Jass native的
函数名,就能找到像这样的一大坨东西:
6F3D4B60 E8 ABFB0700 call 6F454710
6F3D4B65 68 3CD9956F push 6F95D93C ; ASCII
"(R)R"
6F3D4B6A BA 34D9956F mov edx, 6F95D934 ; ASCII
"Deg2Rad"
6F3D4B6F B9 10353B6F mov ecx, 6F3B3510
6F3D4B74 E8 A7100800 call 6F455C20
6F3D4B79 68 3CD9956F push 6F95D93C ; ASCII
"(R)R"
6F3D4B7E BA 2CD9956F mov edx, 6F95D92C ; ASCII
"Rad2Deg"
6F3D4B83 B9 30353B6F mov ecx, 6F3B3530
6F3D4B88 E8 93100800 call 6F455C20
6F3D4B8D 68 3CD9956F push 6F95D93C ; ASCII
"(R)R"
6F3D4B92 BA 28D9956F mov edx, 6F95D928 ; ASCII
"Sin"
6F3D4B97 B9 50353B6F mov ecx, 6F3B3550 |