dota玩了很多很多年,其中知道有些玩家很假,但是心想开图毕竟是少数,直到自己开了一次图才发现,开图真不是少数,原因就是外挂程序太简单了,并不想深入,所以很多结构性代码我直接写死了,下面是针对我自己成功的案例,1.24版本!
// test.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include
#include
#include
#pragma comment(lib, "version.lib")
HMODULE fnGetProcessBase(DWORD PID);
DWORD GetLastErrorBox(HWND hWnd, LPSTR lpTitle);
#define _120E 0
#define _124B 1
#define _124E 2
#define _125B 3
#define _126B 4
char GameDLL[512] = { 0 };
char FileVer[64] = { 0 };
int g_WarVer = 1.20;
typedef enum _MEMORY_INFORMATION_CLASS
{
MemoryBasicInformation,
MemoryWorkingSetList,
MemorySectionName,
MemoryBasicVlmInformation
} MEMORY_INFORMATION_CLASS;
typedef long (NTAPI * PF_ZwQueryVirtualMemory)
(IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
IN MEMORY_INFORMATION_CLASS MemoryInformationClass,
OUT PVOID MemoryInformation,
IN ULONG MemoryInformationLength,
OUT PULONG ReturnLength OPTIONAL
);
typedef struct _UNICODE_STRING
{
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
DWORD GetGameDLLAddr(HANDLE hWar3Handle, WCHAR * ModuleName)
{
DWORD startAddr;
BYTE buffer[MAX_PATH * 2 + 4];
MEMORY_BASIC_INFORMATION memBI;
PUNICODE_STRING secName;
PF_ZwQueryVirtualMemory ZwQueryVirtualMemory;
startAddr = 0x00000000;
ZwQueryVirtualMemory = (PF_ZwQueryVirtualMemory)GetProcAddress(GetModuleHandleA("ntdll"), "ZwQueryVirtualMemory");
do {
if (ZwQueryVirtualMemory(hWar3Handle, (PVOID)startAddr, MemoryBasicInformation, &memBI, sizeof(memBI), 0) >= 0 &&
(memBI.Type == MEM_IMAGE))
{
if (ZwQueryVirtualMemory(hWar3Handle, (PVOID)startAddr, MemorySectionName, buffer, sizeof(buffer), 0) >= 0)
{
secName = (PUNICODE_STRING)buffer;
if (_wcsicmp(ModuleName, wcsrchr(secName->Buffer, '\\') + 1) == 0)
{
return startAddr;
}
}
// 递增基址,开始下一轮查询!
}
startAddr += 0x10000;
} while (startAddr < 0x80000000);
return 0;
};
DWORD GetFileVer(LPTSTR FileName, LPTSTR lpVersion, DWORD nSize)
{
TCHAR SubBlock[64];
DWORD InfoSize = GetFileVersionInfoSize(FileName, NULL);
if (InfoSize == 0) {
return 0;
}
TCHAR* InfoBuff = new TCHAR[InfoSize];
GetFileVersionInfo(FileName, 0, InfoSize, InfoBuff);
unsigned int cbTranslate = 0;
struct LONGANDCODEPAGE
{
WORD wLanguage;
WORD wCodePage;
} *lpTranslate;
VerQueryValue(InfoBuff, TEXT("\\VarFileInfo\\Translation"), (LPVOID*)&lpTranslate, &cbTranslate);
wsprintf(SubBlock, TEXT("\\StringFileInfo\\%04x%04x\\FileVersion"), lpTranslate[0].wLanguage, lpTranslate[0].wCodePage);
void* lpBuffer = NULL;
unsigned int dwBytes = 0;
VerQueryValue(InfoBuff, SubBlock, &lpBuffer, &dwBytes);
lstrcpyn(lpVersion, (LPTSTR)lpBuffer, nSize);
delete InfoBuff;
return dwBytes;
}
void GetWar3Ver()
{
TCHAR fileVer[128] = { 0 };
/*ODV(TEXT("%s"), GameDLL);*/
GetFileVer(GameDLL, FileVer, 64);
/*ODV(TEXT("%s"), FileVer);*/
if (lstrcmpi(FileVer, TEXT("1, 20, 4, 6074")) == 0)
{
g_WarVer = _120E;
}
else if (lstrcmpi(FileVer, TEXT("1, 24, 1, 6374")) == 0)
{
g_WarVer = _124B;
}
else if (lstrcmpi(FileVer, TEXT("1, 24, 4, 6387")) == 0)
{
g_WarVer = _124E;
}
else if (lstrcmpi(FileVer, TEXT("1, 25, 1, 6397")) == 0)
{
g_WarVer = _125B;
}
else if (lstrcmpi(FileVer, TEXT("1, 26, 0, 6401")) == 0)
{
g_WarVer = _126B;
}
else
{
g_WarVer = -1;
}
}
DWORD GetDllBaseAddr(char* dllName, DWORD PID)
{
//获取进程基址
HANDLE hSnapShot;
//通过CreateToolhelp32Snapshot和线程ID,获取进程快照
hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, PID);
if (hSnapShot == INVALID_HANDLE_VALUE)
{
GetLastErrorBox(NULL, "无法创建快照");
return NULL;
}
MODULEENTRY32 ModuleEntry32;
ModuleEntry32.dwSize = sizeof(ModuleEntry32);
if (Module32First(hSnapShot, &ModuleEntry32))
{
do
{
TCHAR szExt[5];
strcpy_s(szExt, ModuleEntry32.szExePath + strlen(ModuleEntry32.szExePath) - 4);
for (int i = 0; i < 4; i++)
{
if ((szExt[i] >= 'a') && (szExt[i] <= 'z'))
{
szExt[i] = szExt[i] - 0x20;
}
}
if (strcmp(dllName, (const char*)ModuleEntry32.szModule) == 0)
{
strcpy_s(GameDLL, ModuleEntry32.szExePath);
CloseHandle(hSnapShot);
return (DWORD)ModuleEntry32.modBaseAddr;
}
} while (Module32Next(hSnapShot, &ModuleEntry32));
}
CloseHandle(hSnapShot);
return NULL;
}
DWORD GetDllBaseAddrEX(char* dllName, DWORD PID)
{
//获取进程基址
HANDLE hSnapShot;
//通过CreateToolhelp32Snapshot和线程ID,获取进程快照
hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, PID);
if (hSnapShot == INVALID_HANDLE_VALUE)
{
GetLastErrorBox(NULL, "无法创建快照");
return NULL;
}
MODULEENTRY32 ModuleEntry32;
ModuleEntry32.dwSize = sizeof(ModuleEntry32);
if (Module32First(hSnapShot, &ModuleEntry32))
{
do
{
TCHAR szExt[5];
strcpy_s(szExt, ModuleEntry32.szExePath + strlen(ModuleEntry32.szExePath) - 4);
for (int i = 0; i < 4; i++)
{
if ((szExt[i] >= 'a') && (szExt[i] <= 'z'))
{
szExt[i] = szExt[i] - 0x20;
}
}
if (strcmp(dllName, (const char*)ModuleEntry32.szModule) == 0)
{
strcpy_s(GameDLL, ModuleEntry32.szExePath);
CloseHandle(hSnapShot);
return (DWORD)ModuleEntry32.modBaseAddr;
}
} while (Module32Next(hSnapShot, &ModuleEntry32));
}
CloseHandle(hSnapShot);
return NULL;
}
HMODULE fnGetProcessBase(DWORD PID)
{
//获取进程基址
HANDLE hSnapShot;
//通过CreateToolhelp32Snapshot和线程ID,获取进程快照
hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, PID);
if (hSnapShot == INVALID_HANDLE_VALUE)
{
GetLastErrorBox(NULL, "无法创建快照");
return NULL;
}
MODULEENTRY32 ModuleEntry32;
ModuleEntry32.dwSize = sizeof(ModuleEntry32);
if (Module32First(hSnapShot, &ModuleEntry32))
{
do
{
TCHAR szExt[5];
strcpy_s(szExt, ModuleEntry32.szExePath + strlen(ModuleEntry32.szExePath) - 4);
for (int i = 0; i < 4; i++)
{
if ((szExt[i] >= 'a') && (szExt[i] <= 'z'))
{
szExt[i] = szExt[i] - 0x20;
}
}
if (!strcmp(szExt, ".EXE"))
{
CloseHandle(hSnapShot);
return ModuleEntry32.hModule;
}
} while (Module32Next(hSnapShot, &ModuleEntry32));
}
CloseHandle(hSnapShot);
return NULL;
}
// 显示错误信息
DWORD GetLastErrorBox(HWND hWnd, LPSTR lpTitle)
{
LPVOID lpv;
DWORD dwRv;
if (GetLastError() == 0) return 0;
dwRv = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
GetLastError(),
MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
(LPSTR)&lpv,
0,
NULL);
MessageBox(hWnd, (LPCSTR)lpv, lpTitle, MB_OK);
if (dwRv)
LocalFree(lpv);
SetLastError(0);
return dwRv;
}
BOOL WINAPI EnablePrivileges()
{
HANDLE hToken;
TOKEN_PRIVILEGES tkp;
if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
return(FALSE);
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);
if (GetLastError() != ERROR_SUCCESS)
return FALSE;
return TRUE;
}
int main()
{
HWND hwnd = ::FindWindow(NULL,_T("Warcraft III"));
if (!hwnd)
{
return 0;
}
DWORD processid;
::GetWindowThreadProcessId(hwnd, &processid);
EnablePrivileges();
HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS|PROCESS_TERMINATE|PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE, false, processid);
if (!handle)
{
int a=GetLastError();
return 0;
}
//WCHAR dll[64] = L"Game.dll";
DWORD gameDllBase1 = GetGameDLLAddr(handle, L"Game.dll");
DWORD gameDllBase = GetDllBaseAddr("Game.dll", processid);
HMODULE hModule = fnGetProcessBase(processid);
printf("%X", hModule);
GetWar3Ver();
::ReadProcessMemory(handle, (LPCVOID)(gameDllBase+ 0x361EAB), (LPVOID)test, 24, NULL);
printf("十六进制%%x输出:%x\n", test);*/
DWORD bsAddr = 0;
::ReadProcessMemory(handle, (LPCVOID)gameDllBase, (LPVOID)&bsAddr, 4, NULL);
//去除迷雾
//::WriteProcessMemory(handle, (LPVOID)(gameDllBase + 0x74D1B9), "\xB2\x00\x90\x90\x90\x90", 6, NULL);
//大地图显示单位
::WriteProcessMemory(handle, (LPVOID)(gameDllBase + 0x39EBBC), "\x75", 1, NULL);
::WriteProcessMemory(handle, (LPVOID)(gameDllBase + 0x3A2030), "\x90\x90", 2, NULL);
::WriteProcessMemory(handle, (LPVOID)(gameDllBase + 0x3A20DB), "\x90\x90", 2, NULL);
//显示隐形单位
::WriteProcessMemory(handle, (LPVOID)(gameDllBase + 0x362391), "\x3B", 1, NULL);
::WriteProcessMemory(handle, (LPVOID)(gameDllBase + 0x362394), "\x85", 1, NULL);
::WriteProcessMemory(handle, (LPVOID)(gameDllBase + 0x39A51B), "\x90\x90\x90\x90\x90\x90", 6, NULL);
::WriteProcessMemory(handle, (LPVOID)(gameDllBase + 0x39A52E), "\x90\x90\x90\x90\x90\x90\x90\x90\x33\xC0\x40", 11, NULL);
//小地图显示单位
::WriteProcessMemory(handle, (LPVOID)(gameDllBase + 0x361F7C), "\x00", 1, NULL);
CloseHandle(handle);
return 0;
}