BOOL cInjector::RunRemoteProc(DWORD dwPid, wstring wDllName, string procName) { if (!FindInjectedModule(dwPid)) { return false; } HANDLE hThread; HANDLE hProc; HMODULE hMod; LPVOID procAddress; hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid); if (hProc) { std::string s; s.assign(wDllName.begin(), wDllName.end()); PE::ulong procOffset = PE::GetFunctionOffset(s, procName); if (procOffset) { long MODULE_BASE = reinterpret_cast<long>(GetRemoteModuleAddress(dwPid, wDllName)); hThread = CreateRemoteThread(hProc, NULL, NULL, reinterpret_cast<LPTHREAD_START_ROUTINE>((LPVOID)(MODULE_BASE + procOffset)), NULL, NULL, NULL); WaitForSingleObject(hThread, INFINITE); CloseHandle(hProc); CloseHandle(hThread); return true; } else { printf("GetProcAddress() failed with error code %d\n", GetLastError()); } CloseHandle(hProc); } else { printf("OpenProcess() failed with error code %d\n", GetLastError()); } return FALSE; }
BOOL cInjector::InjectDLL(DWORD dwPid, wstring wDllName) { HANDLE hThread; HANDLE hProc; HMODULE hKernel32; LPVOID lpLoadLibraryW; LPVOID lpRemoteString; wstring wPath; wPath = BH::wPath; wPath += wDllName; hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid); if(hProc) { hKernel32 = LoadLibrary(L"Kernel32.DLL"); if(hKernel32) { lpLoadLibraryW = GetProcAddress(hKernel32, "LoadLibraryW"); if(lpLoadLibraryW) { lpRemoteString = (LPVOID)VirtualAllocEx(hProc, NULL, MAX_PATH, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); if(lpRemoteString) { WriteProcessMemory(hProc, lpRemoteString, wPath.c_str(), wPath.size() * 2, NULL); hThread = CreateRemoteThread(hProc, NULL, NULL, reinterpret_cast<LPTHREAD_START_ROUTINE>(lpLoadLibraryW), lpRemoteString, NULL, NULL); WaitForSingleObject(hThread, INFINITE); VirtualFreeEx(hProc, lpRemoteString, 0, MEM_RELEASE); FreeLibrary(hKernel32); CloseHandle(hProc); CloseHandle(hThread); // If we're injecting into the wrong version of the D2 client, all the offsets // will be wrong and we'll silently fail on the first call into a D2 function // (generally D2GFX_GetHwnd in BH::Startup). BH::Startup still returns success // however, so check for failed injection by looking for "BH.dll" the game process. if (FindInjectedModule(dwPid)) { return true; } printf("WARNING: this maphack will only work with Diablo II client version 1.13C!\n"); printf("You appear to have a different client version. To learn how to downgrade your\n"); printf("client, see the Guides & Resources section of the slashdiablo subreddit.\n"); return false; } else { printf("VirtualAllocEx() failed with error code %d\n", GetLastError()); } } else { printf("GetProcAddress() failed with error code %d\n", GetLastError()); } FreeLibrary(hKernel32); } else { printf("LoadLibrary() failed with error code %d\n", GetLastError()); } CloseHandle(hProc); } else { printf("OpenProcess() failed with error code %d\n", GetLastError()); } return FALSE; }