use virtualallocex where available

This commit is contained in:
itsmattkc 2021-11-20 00:07:55 -08:00
parent fa70d36585
commit 3816530f4e
2 changed files with 74 additions and 23 deletions

View file

@ -5,6 +5,8 @@
#include "../res/resource.h" #include "../res/resource.h"
typedef LPVOID (WINAPI *VirtualAllocEx_t)(HANDLE hProcess, LPVOID lpAddress, DWORD dwSize, DWORD flAllocationType, DWORD flProtect);
HANDLE Launcher::Launch(HWND parent) HANDLE Launcher::Launch(HWND parent)
{ {
// Find the installation // Find the installation
@ -14,26 +16,13 @@ HANDLE Launcher::Launch(HWND parent)
return NULL; 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 // Extract REBLD.DLL which contains our patches
TCHAR libraryFile[MAX_PATH];
if (!ExtractLibrary(libraryFile, MAX_PATH)) { if (!ExtractLibrary(libraryFile, MAX_PATH)) {
MessageBox(parent, _T("Failed to extract to temp"), NULL, 0); MessageBox(parent, _T("Failed to extract to temp"), NULL, 0);
return NULL; 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 // Get ISLE directory only
TCHAR srcDir[MAX_PATH]; TCHAR srcDir[MAX_PATH];
_tcscpy(srcDir, filename); _tcscpy(srcDir, filename);
@ -41,18 +30,61 @@ HANDLE Launcher::Launch(HWND parent)
// Start launching our copy // Start launching our copy
PROCESS_INFORMATION pi; PROCESS_INFORMATION pi;
STARTUPINFO si; if (!TryCreateProcess(parent, filename, srcDir, TRUE, &pi)) {
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);
return NULL; 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; return pi.hProcess;
} }
@ -213,3 +245,20 @@ BOOL Launcher::ReplacePatternInFile(HANDLE file, const char *pattern, const char
return success; 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;
}

View file

@ -21,6 +21,8 @@ private:
static BOOL ReplacePatternInFile(HANDLE file, const char *pattern, const char *replace, LONG sz); 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 #endif // LAUNCHER_H