From 3816530f4e723f9bccf7b6117eb6285562b0b736 Mon Sep 17 00:00:00 2001 From: itsmattkc <34096995+itsmattkc@users.noreply.github.com> Date: Sat, 20 Nov 2021 00:07:55 -0800 Subject: [PATCH] use virtualallocex where available --- src/launcher.cpp | 95 ++++++++++++++++++++++++++++++++++++------------ src/launcher.h | 2 + 2 files changed, 74 insertions(+), 23 deletions(-) diff --git a/src/launcher.cpp b/src/launcher.cpp index ff65787..479a847 100644 --- a/src/launcher.cpp +++ b/src/launcher.cpp @@ -5,6 +5,8 @@ #include "../res/resource.h" +typedef LPVOID (WINAPI *VirtualAllocEx_t)(HANDLE hProcess, LPVOID lpAddress, DWORD dwSize, DWORD flAllocationType, DWORD flProtect); + HANDLE Launcher::Launch(HWND parent) { // Find the installation @@ -14,26 +16,13 @@ HANDLE Launcher::Launch(HWND parent) return NULL; } - // If we found it, make a copy to temp - TCHAR copiedFile[MAX_PATH]; - TCHAR libraryFile[MAX_PATH]; - if (!CopyIsleToTemp(filename, copiedFile)) { - MessageBox(parent, _T("Failed to copy to temp"), NULL, 0); - return NULL; - } - // Extract REBLD.DLL which contains our patches + TCHAR libraryFile[MAX_PATH]; if (!ExtractLibrary(libraryFile, MAX_PATH)) { MessageBox(parent, _T("Failed to extract to temp"), NULL, 0); return NULL; } - // Patch our copied ISLE to import our DLL - if (!PatchIsle(copiedFile)) { - MessageBox(parent, _T("Failed to patch import"), NULL, 0); - return NULL; - } - // Get ISLE directory only TCHAR srcDir[MAX_PATH]; _tcscpy(srcDir, filename); @@ -41,18 +30,61 @@ HANDLE Launcher::Launch(HWND parent) // Start launching our copy PROCESS_INFORMATION pi; - STARTUPINFO si; - - ZeroMemory(&pi, sizeof(pi)); - ZeroMemory(&si, sizeof(si)); - - if (!CreateProcess(NULL, copiedFile, NULL, NULL, FALSE, 0, NULL, srcDir, &si, &pi)) { - TCHAR err[2048]; - _stprintf(err, _T("Failed to create process with error 0x%lx"), GetLastError()); - MessageBox(parent, err, NULL, 0); + if (!TryCreateProcess(parent, filename, srcDir, TRUE, &pi)) { return NULL; } + int dllPathLength = strlen(libraryFile) + 1; + + LPVOID remoteDllAddress = NULL; + if (VirtualAllocEx_t virtualAllocEx = (VirtualAllocEx_t)GetProcAddress(GetModuleHandle(TEXT("KERNEL32.DLL")), TEXT("VirtualAllocEx"))) { + remoteDllAddress = virtualAllocEx(pi.hProcess, NULL, dllPathLength, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); + } + + if (remoteDllAddress) { + // For Windows NT, we can use the standard VirtualAllocEx/WriteProcessMemory/CreateRemoteThread + // injection system. + if (!WriteProcessMemory(pi.hProcess, remoteDllAddress, (LPVOID)libraryFile, dllPathLength, NULL)) { + MessageBox(parent, TEXT("Failed to write memory in remote process"), NULL, 0); + TerminateProcess(pi.hProcess, 0); + return NULL; + } + + DWORD thread_id; + HANDLE remote_thread = CreateRemoteThread(pi.hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE) LoadLibrary, remoteDllAddress, NULL, &thread_id); + if (!remote_thread) { + char buf[100]; + sprintf(buf, "Failed to create remote thread: 0x%lx", GetLastError()); + MessageBox(parent, buf, NULL, 0); + TerminateProcess(pi.hProcess, 0); + return NULL; + } + + WaitForSingleObject(remote_thread, INFINITE); + CloseHandle(remote_thread); + ResumeThread(pi.hThread); + } else { + // For Windows 9x, we wrap WINMM.DLL because 9x doesn't support VirtualAllocEx or CreateRemoteThread. + TerminateProcess(pi.hProcess, 0); + + // Copy ISLE to temp + TCHAR copiedFile[MAX_PATH]; + if (!CopyIsleToTemp(filename, copiedFile)) { + MessageBox(parent, _T("Failed to copy to temp"), NULL, 0); + return NULL; + } + + // Patch our copied ISLE to import our DLL + if (!PatchIsle(copiedFile)) { + MessageBox(parent, _T("Failed to patch import"), NULL, 0); + return NULL; + } + + if (!TryCreateProcess(parent, copiedFile, srcDir, FALSE, &pi)) { + return NULL; + } + } + return pi.hProcess; } @@ -213,3 +245,20 @@ BOOL Launcher::ReplacePatternInFile(HANDLE file, const char *pattern, const char return success; } + +BOOL Launcher::TryCreateProcess(HWND parent, LPSTR filename, LPCSTR working_dir, BOOL suspended, PROCESS_INFORMATION *pi) +{ + STARTUPINFO si; + + ZeroMemory(pi, sizeof(PROCESS_INFORMATION)); + ZeroMemory(&si, sizeof(si)); + + if (!CreateProcess(NULL, filename, NULL, NULL, FALSE, suspended ? CREATE_SUSPENDED : 0, NULL, working_dir, &si, pi)) { + TCHAR err[2048]; + _stprintf(err, _T("Failed to create process with error 0x%lx"), GetLastError()); + MessageBox(parent, err, NULL, 0); + return FALSE; + } + + return TRUE; +} diff --git a/src/launcher.h b/src/launcher.h index 4d54718..6e158a3 100644 --- a/src/launcher.h +++ b/src/launcher.h @@ -21,6 +21,8 @@ private: static BOOL ReplacePatternInFile(HANDLE file, const char *pattern, const char *replace, LONG sz); + static BOOL TryCreateProcess(HWND parent, LPSTR filename, LPCSTR working_dir, BOOL suspended, PROCESS_INFORMATION *pi); + }; #endif // LAUNCHER_H