从小学学会开始学魔兽地图制作之后,我就彻底爱上了编程,WE(魔兽地图编辑)一直伴随着我的成长,从学第一门脚本语言(Jass)到现在这么多都是它让我成长起来的。现在war3 也衰败了。朋友让我做个全开的小工具。我试了下,果真可以了。

网上一些让地图全开的方法大多是直接修改内存,如果学过作图的话 。war3 内部其实给作图开发者提供 jass native 函数。jass是 war3的地图脚本语言。其实我猜他是从lua(一种脚本语言)上精简过来的。做过图的朋友都知道,调用这些函数可以直接达到预期的效果。

但是我们现在要做的是在外部调用这些函数。好在war3已经把对应函数表的对应地址给我们了。


我们用OD打开war3 目录下的 Game.dll

搜索字符串 "FogEnable"  

这个是war3 jass api用来启用战争迷雾的函数,我们在作图的时候在Trigger(触发器)中调用这个函数就可以禁用(启用)战争迷雾。

我们会看到如下的代码


6F3D58DA    BA 68C5956F     mov edx,Game.6F95C568                    ; FogMaskEnable
6F3D58DF    B9 50BD3B6F     mov ecx,Game.6F3BBD50
6F3D58E4    E8 37030800     call Game.6F455C20
6F3D58E9    68 E85B946F     push Game.6F945BE8                       ; ()B
6F3D58EE    BA 54C5956F     mov edx,Game.6F95C554                    ; IsFogMaskEnabled
6F3D58F3    B9 70BD3B6F     mov ecx,Game.6F3BBD70
6F3D58F8    E8 23030800     call Game.6F455C20
6F3D58FD    68 A45B946F     push Game.6F945BA4                       ; (B)V
6F3D5902    BA 48C5956F     mov edx,Game.6F95C548                    ; FogEnable
6F3D5907    B9 20BD3B6F     mov ecx,Game.6F3BBD20
6F3D590C    E8 0F030800     call Game.6F455C20
6F3D5911    68 E85B946F     push Game.6F945BE8                       ; ()B
6F3D5916    BA 38C5956F     mov edx,Game.6F95C538                    ; IsFogEnabled
6F3D591B    B9 40BD3B6F     mov ecx,Game.6F3BBD40
6F3D5920    E8 FB020800     call Game.6F455C20



这是游戏开始war3用来注册 jass native api函数的

很显然这是 fastcall

如果在下面再按照它的形式多定义几条的话。我们就可以增加 jass native api ,可以用来扩充war3 的功能

其实 11 平台也是这么实现的。这里的这种方法并不能过掉 11 平台的检测。似乎 11平台 的检测技术确实比较厉害,我想了一下午都没有找到过 11 的方法。

当然这里只是简单的演示。

回归正题。


上面的FogMaskEnable 和 FogEnable 函数就是禁用(启用)战争迷雾和黑色阴影的函数。 分别有一个参数。是bool类型的

他在jass中的native common.j中的定义是。


native FogMaskEnable takes bool b returns nothing
native FogEnable takes bool b returns nothing


我们由此推测 ecx寄存器里面存的就是jass native api对应的物理地址。我们进去看一下头果真的stdcall.而且参数表和注册时压入栈中的一模一样.

然后我们只需要写个dll,然后直接调用ecx里的地址就可以了。


1.定义一个函数指针

2.然后设置一个键盘钩子。当按下哪个按键的时候 就调用 fog(0)和mask(0)

void(_war3_Fogable)(bool state);
 
 *fog=(_war3_Fogable*)(0x03EABD20);

 *mask=(_war3_Fogable*)(0x03EABD50);

HHOOK g_LowKeyBoardHook=NULL;.

LRESULT CALLBACKLowLevelKeyboardProc(intnCode,
WPARAMwParam,
LPARAMlParam
)
 {
if(nCode==HC_ACTION)
{
//当按下home键的时候
if(kblp->vkCode==VK_HOME&&wParam==WM_KEYDOWN)
{
fog(0);
mask(0);
 
 
 
returnTRUE;
}
}
returnCallNextHookEx(g_LowKeyBoardHook,nCode,wParam,lParam);
 }
 
 
 APIENTRYDllMain(HMODULEhModule,
DWORD  ul_reason_for_call,
LPVOID lpReserved
)
 {
 
fog(0);
mask(0);
 
 
 
switch(ul_reason_for_call)
{
 
caseDLL_PROCESS_ATTACH:
{
 
//   MessageBox(NULL, _T("DLL_PROCESS_ATTACH"), _T("!"), MB_OK);
g_LowKeyBoardHook=SetWindowsHookEx(WH_KEYBOARD_LL,(HOOKPROC)LowLevelKeyboardProc,hModule,0);
 
 
}
caseDLL_THREAD_ATTACH:
caseDLL_THREAD_DETACH:
caseDLL_PROCESS_DETACH:
break;
 
 
}
returnTRUE;
 }



3.DLL注入

然后如何把这个DLL注入到war3进程中是个问题。

不过Wc3c.net 上有人发现当war3.exe启动的时候会把 war3\redist\miles 下所有扩展名为 m3d 的模块 载入进程。

所以只需要把dll的扩展名改成m3d放入war3\redist\miles目录下。

当war3启动时就会把它当做默认模块载入到游戏中。进入游戏后按Home键就可以了。