无需远程注入DLL,几行代码实现War3魔兽地图全开

从小学学会开始学魔兽地图制作之后,我就彻底爱上了编程,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.定义一个函数指针

typedef void(_war3_Fogable)(bool state);


_war3_Fogable *fog=(_war3_Fogable*)(0x03EABD20);


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


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


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);

}



BOOL 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键就可以了。









### 回答1: 示例代码:#include <windows.h> #include <stdio.h> #include <tlhelp32.h> // 远程线程注入dll BOOL InjectDLL(DWORD dwPID, char *szDLLName); int main(int argc, char *argv[]) { printf("远程线程注入dll演示程序\n"); if (argc == 3) { DWORD dwPID = atoi(argv[1]); char *szDLLName = argv[2]; InjectDLL(dwPID, szDLLName); } else { printf("用法:InjectDLL.exe <PID> <DLLName>\n"); } return 0; } // 远程线程注入dll BOOL InjectDLL(DWORD dwPID, char *szDLLName) { HANDLE hProcess, hThread; LPVOID lpBaseAddress; LPTHREAD_START_ROUTINE lpStartAddress; DWORD dwSize, dwThreadId; char szPath[256]; char szBuffer[1024]; // 打开进程 hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID); if (hProcess == NULL) { printf("OpenProcess() Error: %d\n", GetLastError()); return FALSE; } // 获取DLL的完整路径 GetFullPathName(szDLLName, 256, szPath, NULL); // 在进程中申请虚拟内存 dwSize = strlen(szPath) + 1; lpBaseAddress = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE); if (lpBaseAddress == NULL) { printf("VirtualAllocEx() Error: %d\n", GetLastError()); return FALSE; } // 将DLL路径写入到虚拟内存 int nBytesWritten; WriteProcessMemory(hProcess, lpBaseAddress, szPath, dwSize, &nBytesWritten); if (nBytesWritten != dwSize) { printf("WriteProcessMemory() Error: %d\n", GetLastError()); return FALSE; } // 加载Kernel32.dll HMODULE hKernel32 = GetModuleHandle("Kernel32"); if (hKernel32 == NULL) { printf("GetModuleHandle() Error: %d\n", GetLastError()); return FALSE; } // 获取LoadLibraryA函数地址 lpStartAddress = GetProcAddress(hKernel32, "LoadLibraryA"); if (lpStartAddress == NULL) { printf("GetProcAddress() Error: %d\n", GetLastError()); return FALSE; } // 创建远程线程 hThread = CreateRemoteThread(hProcess, NULL, 0, lpStartAddress, lpBaseAddress, 0, &dwThreadId); if (hThread == NULL) { printf("CreateRemoteThread() Error: %d\n", GetLastError()); return FALSE; } // 等待远程线程结束 WaitForSingleObject(hThread, INFINITE); // 读取线程退出码 DWORD dwExitCode; GetExitCodeThread(hThread, &dwExitCode); if (dwExitCode == 0) { printf("LoadLibrary() Error: %d\n", GetLastError()); return FALSE; } // 关闭句柄 CloseHandle(hProcess); CloseHandle(hThread); return TRUE; }我不能帮助你编写代码,但是我可以提供一些参考资料,帮助你编写远程线程注入dll代码。 ### 回答2: 远程线程注入DLL是一种技术,用于在目标进程中注入自定义的动态链接库(DLL)并执行其中的代码。以下是一个使用C语言编写的远程线程注入DLL代码示例: ```c #include <stdio.h> #include <stdlib.h> #include <windows.h> int main() { // 目标进程的进程ID DWORD pid = 1234; // 加载要注入DLL路径 char dllPath[] = "C:\\path_to_dll\\mydll.dll"; // 获取目标进程句柄 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); if (hProcess == NULL) { printf("无法打开目标进程"); return -1; } // 在目标进程中为DLL路径分配内存 LPVOID dllPathAddr = VirtualAllocEx(hProcess, NULL, sizeof(dllPath), MEM_COMMIT, PAGE_READWRITE); if (dllPathAddr == NULL) { printf("无法在目标进程中分配内存"); CloseHandle(hProcess); return -1; } // 在目标进程中写入DLL路径 if (!WriteProcessMemory(hProcess, dllPathAddr, dllPath, sizeof(dllPath), NULL)) { printf("无法写入DLL路径到目标进程"); VirtualFreeEx(hProcess, dllPathAddr, 0, MEM_RELEASE); CloseHandle(hProcess); return -1; } // 获取Kernel32.dll中LoadLibrary函数的地址 HMODULE kernel32 = GetModuleHandle("kernel32.dll"); FARPROC loadLibrary = GetProcAddress(kernel32, "LoadLibraryA"); // 创建远程线程在目标进程中执行LoadLibrary函数,将DLL路径作为参数 HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)loadLibrary, dllPathAddr, 0, NULL); if (hThread == NULL) { printf("无法在目标进程中创建远程线程"); VirtualFreeEx(hProcess, dllPathAddr, 0, MEM_RELEASE); CloseHandle(hProcess); return -1; } // 等待远程线程执行结束 WaitForSingleObject(hThread, INFINITE); // 清理资源 VirtualFreeEx(hProcess, dllPathAddr, 0, MEM_RELEASE); CloseHandle(hThread); CloseHandle(hProcess); printf("远程线程注入DLL成功"); return 0; } ``` 这段代码首先通过`OpenProcess`函数打开目标进程,然后使用`VirtualAllocEx`在目标进程中为DLL路径分配内存,并使用`WriteProcessMemory`将DLL路径写入目标进程内存。接着,使用`GetModuleHandle`和`GetProcAddress`获取`LoadLibrary`函数的地址,然后使用`CreateRemoteThread`在目标进程中创建一个远程线程,让其执行`LoadLibrary`函数,将DLL路径作为参数传递给它。最后,使用`WaitForSingleObject`等待远程线程执行完毕,并释放之前分配的资源。 ### 回答3: 使用C语言编写远程线程注入DLL代码可以通过以下步骤实现: 1. 首先,需要创建一个目标进程的句柄。可以使用`OpenProcess`函数来打开目标进程,并获得进程的句柄。 2. 接下来,需要在目标进程中分配一块内存空间,用于存储DLL的路径和名称。可以使用`VirtualAllocEx`函数在目标进程内部分配内存。 3. 在分配的内存空间中写入DLL的路径和名称。可以使用`WriteProcessMemory`函数将DLL的路径和名称写入到目标进程的内存中。 4. 使用`GetProcAddress`函数获取`LoadLibraryA`函数的地址,该函数用于加载DLL。可以使用`GetModuleHandle`函数获取kernel32.dll的句柄,然后再调用`GetProcAddress`函数来获取`LoadLibraryA`函数的地址。 5. 使用`CreateRemoteThread`函数在目标进程中创建一个远程线程,将`LoadLibraryA`函数地址作为线程的入口点,将DLL的路径和名称作为线程的参数传递。这样,在目标进程中就会自动加载并执行DLL。 完整的代码示例如下: ```c #include <windows.h> int main() { // Step 1: 打开目标进程句柄 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PROCESS_ID); // Step 2: 分配内存空间 LPVOID lpRemoteBuffer = VirtualAllocEx(hProcess, NULL, MAX_PATH, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); // Step 3: 写入DLL路径和名称 char dllPath[] = "C:\\path\\to\\dll.dll"; WriteProcessMemory(hProcess, lpRemoteBuffer, (LPVOID)dllPath, sizeof(dllPath), NULL); // Step 4: 获取LoadLibraryA函数地址 HMODULE hKernel32 = GetModuleHandleA("kernel32.dll"); FARPROC lpLoadLibraryA = GetProcAddress(hKernel32, "LoadLibraryA"); // Step 5: 创建远程线程注入DLL HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)lpLoadLibraryA, lpRemoteBuffer, 0, NULL); // 关闭句柄 CloseHandle(hThread); CloseHandle(hProcess); return 0; } ``` 以上就是使用C语言编写远程线程注入DLL代码。请注意,使用远程线程注入DLL可能存在一些安全风险,请谨慎使用。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值