教你编写DOTA外挂(一)

2014-11-24 12:22:31 · 作者: · 浏览: 3
好久木有研究DOTA了,整理篇小菜文章。
首先,我们要提升外挂本身程序权限,使其能够有权限修改war3游戏的内存。这个c++可以使用如下代码


void EnableDebugPriv()//提升程序自身权限
{
HANDLE hToken;
LUID sedebugnameva lue;
TOKEN_PRIVILEGES tkp;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) return;
if (!LookupPrivilegeva lue(NULL, SE_DEBUG_NAME,&sedebugnameva lue))
{
CloseHandle(hToken);
return;
}
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Luid = sedebugnameva lue;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof tkp, NULL, NULL)) CloseHandle(hToken);
}

其次,有了权限以后,我们要找到war3.exe进程ID。并打开进程以供编辑修改内存,到达作弊目的。
获得进程ID:下面这个函数方法就是返回进程的,直接写进程名称,如:GetPIDForProcess(“war3.exe”),还可以用FindWindow的方法,反正能找到进程ID就可以了。

//HWND hwar3=::FindWindow(NULL,TEXT("Warcraft III"));
//DWORD PID, TID;
//TID = ::GetWindowThreadProcessId (hwar3, &PID);
DWORD GetPIDForProcess(char* process)//获取进程ID
{
BOOL working;
PROCESSENTRY32 lppe= {0};
DWORD targetPid=0;
HANDLE hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS ,0);
if (hSnapshot)
{
lppe.dwSize=sizeof(lppe);
working=Process32First(hSnapshot,&lppe);
while (working)
{
if(strcmp((const char *)lppe.szExeFile,process)==0)
{
targetPid=lppe.th32ProcessID;
break;
}working=Process32Next(hSnapshot,&lppe);
}
}
CloseHandle( hSnapshot );
return targetPid;
}

注意:有的名称为War3.exe或war3.exe,用toolhelp32方式需要比较进程名字,这时是会区分大小写的。FindWindow则不用,窗口标题都是固定的Warcraft III。
进程ID已经找到,现在是不是直接打开修改内存作弊呢?不,还早呢。我们修改内存也不能乱来,你得先找到Game.dll判断游戏版本,对应修改,要不会把魔兽搞火了,突然跳出来,那你就崩溃了,后悔都来不及。有木有,有木有?开图导致游戏崩溃的老实交代一下。

下面的方法获取game.dll的基址和路径。GetDLLBase(“game.dll”,PID)直接返回的就是game.dll的基址,这个后面是需要用到的。定义一个全局变量TCHAR LastDLLPath[260],LastDLLPath返回的就是game.dll路径,。


DWORD GetDLLBase(char* DllName, DWORD tPid)
{
HANDLE snapMod;
MODULEENTRY32 me32;
if (tPid == 0) return 0;
snapMod = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, tPid);
me32.dwSize = sizeof(MODULEENTRY32);
if (Module32First(snapMod, &me32))
{
do
{
if (strcmp(DllName,(const char *)me32.szModule) == 0)
{
strcpy(LastDLLPath ,me32.szExePath);//game.dll路径
CloseHandle(snapMod);
return (DWORD) me32.modBaseAddr;
}
}while(Module32Next(snapMod,&me32));
}
else
{
Powers=true;
}
CloseHandle(snapMod);
return 0;
}
还有就是使用native api ZwQueryVirtualMemory来获取gamedll的基址,这个有些麻烦不过还算是稍微底层些

typedef enum _M