From d9a8a19dd55d42ae179379c90151ee7c96e92948 Mon Sep 17 00:00:00 2001 From: Broihon Date: Sun, 8 Aug 2021 15:37:57 +0200 Subject: [PATCH] Added Win7, Win8, Win8.1, Win10 1507 - 21H1 and Win11 21H2 support, many bug fixes and reworks --- GH Injector Library/Download Manager.h | 6 +- GH Injector Library/Error.h | 9 +- .../GH Injector Library.vcxproj | 12 +- .../GH Injector Library.vcxproj.filters | 33 +- GH Injector Library/Import Handler WOW64.cpp | 304 +++--- GH Injector Library/Import Handler.cpp | 185 +++- GH Injector Library/Import Handler.h | 116 ++- .../Injection Generic WOW64.cpp | 92 +- GH Injector Library/Injection Generic.cpp | 348 ++++++- GH Injector Library/Injection Internal.h | 57 +- GH Injector Library/Injection.cpp | 9 + GH Injector Library/KernelCallback WOW64.cpp | 4 +- GH Injector Library/Manual Mapping WOW64.cpp | 66 +- GH Injector Library/Manual Mapping.cpp | 904 +++++++++++------- GH Injector Library/Manual Mapping.h | 82 +- GH Injector Library/NT Defs.h | 773 +++++++++++++++ GH Injector Library/NT Funcs.h | 417 ++++++++ GH Injector Library/NT Stuff.h | 904 ------------------ GH Injector Library/NtCreateThreadEx.cpp | 2 +- GH Injector Library/Process Info.cpp | 368 ++++--- GH Injector Library/Process Info.h | 22 +- GH Injector Library/Symbol Parser.cpp | 13 +- GH Injector Library/Symbol Parser.h | 2 +- GH Injector Library/Tools.cpp | 180 ++-- GH Injector Library/Tools.h | 41 +- GH Injector Library/VEH Shell.cpp | 158 +++ GH Injector Library/VEH Shell.h | 54 ++ GH Injector Library/WOW64 Shells.h | 40 +- GH Injector Library/Win10.h | 201 ++++ GH Injector Library/Win11.h | 205 ++++ GH Injector Library/Win7.h | 161 ++++ GH Injector Library/Win8.h | 238 +++++ GH Injector Library/Win81.h | 222 +++++ GH Injector Library/main.cpp | 14 +- GH Injector Library/pch.cpp | 4 + GH Injector Library/pch.h | 6 +- .../GH Injector SM/GH Injector SM.vcxproj | 6 +- GH Injector SM/GH Injector SM/main.cpp | 7 +- 38 files changed, 4456 insertions(+), 1809 deletions(-) create mode 100644 GH Injector Library/NT Defs.h create mode 100644 GH Injector Library/NT Funcs.h delete mode 100644 GH Injector Library/NT Stuff.h create mode 100644 GH Injector Library/VEH Shell.cpp create mode 100644 GH Injector Library/VEH Shell.h create mode 100644 GH Injector Library/Win10.h create mode 100644 GH Injector Library/Win11.h create mode 100644 GH Injector Library/Win7.h create mode 100644 GH Injector Library/Win8.h create mode 100644 GH Injector Library/Win81.h diff --git a/GH Injector Library/Download Manager.h b/GH Injector Library/Download Manager.h index 6d1be75..5ac1678 100644 --- a/GH Injector Library/Download Manager.h +++ b/GH Injector Library/Download Manager.h @@ -20,9 +20,9 @@ class DownloadManager : public IBindStatusCallback HRESULT __stdcall QueryInterface(const IID & riid, void ** ppvObject); - ULONG STDMETHODCALLTYPE AddRef(void); + ULONG STDMETHODCALLTYPE AddRef(); - ULONG STDMETHODCALLTYPE Release(void); + ULONG STDMETHODCALLTYPE Release(); virtual HRESULT STDMETHODCALLTYPE OnStartBinding(DWORD dwReserved, IBinding * pib); @@ -32,7 +32,7 @@ class DownloadManager : public IBindStatusCallback virtual HRESULT STDMETHODCALLTYPE OnStopBinding(HRESULT hresult, LPCWSTR szError); - virtual HRESULT STDMETHODCALLTYPE GetBindInfo(DWORD * grfBINDF, BINDINFO *pbindinfo); + virtual HRESULT STDMETHODCALLTYPE GetBindInfo(DWORD * grfBINDF, BINDINFO * pbindinfo); virtual HRESULT STDMETHODCALLTYPE OnDataAvailable(DWORD grfBSCF, DWORD dwSize, FORMATETC * pformatetc, STGMEDIUM * pstgmed); diff --git a/GH Injector Library/Error.h b/GH Injector Library/Error.h index dfdb9bd..6235aec 100644 --- a/GH Injector Library/Error.h +++ b/GH Injector Library/Error.h @@ -77,6 +77,13 @@ #define INJ_ERR_WCSRCHR_FAILED 0x00000038 //wcsrchr : - : wcsrchr failed to find a character in a string (usually '\\' in a path) #define INJ_ERR_TARGET_EXE_NAME_IS_NULL 0x00000039 //internal error : - : the length of the name of the specified process is 0 #define INJ_ERR_LDR_ENTRY_IS_NULL 0x0000003A //internal error : - : LdrpLoadDll(Internal) didn't return a valid LDR_DATA_TABLE_ENTRY pointer +#define INJ_ERR_NOT_SUPPORTED 0x0000003B //internal error : - : the requested operation is not supported on the current operating system +#define INJ_ERR_CREATE_EVENT_FAILED 0x0000003C //CreateEventEx : win32 error : failed to create an event for wow64 process +#define INJ_ERR_CREATE_PROCESS_FAILED 0x0000003D //CreateProcessW : win32 error : failed to create process for wow64 module addresses +#define INJ_ERR_WAIT_FAILED 0x0000003E //WaitForSingleObject : win32 error : failed to wait for an event to trigger +#define INJ_ERR_WAIT_TIMEOUT 0x0000003F //WaitForSingleObject : - : event timed out +#define INJ_ERR_WINDOWS_VERSION 0x00000040 //internal error : - : failed to resolve the version number of the operating system +#define INJ_ERR_WINDOWS_TOO_OLD 0x00000041 //internal error : - : the injection library only runs on Windows 7 or higher /////////////////// @@ -298,7 +305,7 @@ #define SYMBOL_CANT_OPEN_PROCESS 0x40000014 //OpenProcess : can't get PROCESS_QUERY_LIMITED_INFORMATION handle to current process #define SYMBOL_ERR_COPYFILE_FAILED 0x40000015 //CopyFileA : copying the file from the cache directory failed #define SYMBOL_ERR_INTERRUPT 0x40000016 //internal error : download has been interrupted - +#define SYMBOL_ERR_CANNOT_CONNECT 0x40000017 //InternetCheckConnectionW : GetLastError returned ERROR_INTERNET_CANNOT_CONNECT which might be caused by a firewall rule /// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/GH Injector Library/GH Injector Library.vcxproj b/GH Injector Library/GH Injector Library.vcxproj index afb9093..e2f7499 100644 --- a/GH Injector Library/GH Injector Library.vcxproj +++ b/GH Injector Library/GH Injector Library.vcxproj @@ -22,7 +22,7 @@ 15.0 {AC732425-E265-40FF-842F-C59CECE9A96C} GHInjectorLibrary - 10.0.19041.0 + 10.0.22000.0 @@ -174,13 +174,20 @@ - + + + + + + + + @@ -222,6 +229,7 @@ + diff --git a/GH Injector Library/GH Injector Library.vcxproj.filters b/GH Injector Library/GH Injector Library.vcxproj.filters index 2ba83a0..1b1bb01 100644 --- a/GH Injector Library/GH Injector Library.vcxproj.filters +++ b/GH Injector Library/GH Injector Library.vcxproj.filters @@ -34,6 +34,9 @@ {d3c5e067-fa7b-4ff9-9579-418c449c7978} + + {844b590b-6d34-422e-8d4f-d27e3e5defb5} + @@ -45,9 +48,6 @@ Headerdateien - - Headerdateien - Headerdateien @@ -87,6 +87,30 @@ Headerdateien + + Headerdateien\NT + + + Headerdateien\NT + + + Headerdateien\NT + + + Headerdateien\NT + + + Headerdateien\NT + + + Headerdateien\NT + + + Headerdateien\NT + + + Headerdateien\Injection Methods + @@ -176,6 +200,9 @@ Quelldateien\wow64\Start Routine Methods + + Quelldateien\native\Injection Methods + diff --git a/GH Injector Library/Import Handler WOW64.cpp b/GH Injector Library/Import Handler WOW64.cpp index b15c1aa..9721eec 100644 --- a/GH Injector Library/Import Handler WOW64.cpp +++ b/GH Injector Library/Import Handler WOW64.cpp @@ -35,54 +35,164 @@ DWORD ResolveImports_WOW64(ERROR_DATA & error_data) { LOG(" ResolveImports_WOW64 called\n"); - g_hNTDLL_WOW64 = GetModuleHandleExW_WOW64(L"ntdll.dll"); - if (!g_hNTDLL_WOW64) + PROCESS_INFORMATION pi{ 0 }; + STARTUPINFOW si{ 0 }; + si.cb = sizeof(si); + si.dwFlags = STARTF_USESHOWWINDOW; + si.wShowWindow = SW_HIDE; + + SECURITY_ATTRIBUTES sa{ 0 }; + sa.nLength = sizeof(SECURITY_ATTRIBUTES); + sa.bInheritHandle = TRUE; + + HANDLE hEventStart = CreateEventEx(&sa, nullptr, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS); + if (!hEventStart) { - INIT_ERROR_DATA(error_data, INJ_ERR_ADVANCED_NOT_DEFINED); + INIT_ERROR_DATA(error_data, GetLastError()); - LOG(" Failed to get WOW64 ntdll.dll\n"); + LOG(" CreateEventEx failed: %08X\n", error_data.AdvErrorCode); - return INJ_ERR_WOW64_NTDLL_MISSING; + return INJ_ERR_CREATE_EVENT_FAILED; } - DWORD WOW64_dummy_process_id = 0; - auto hKernel32_WOW64 = GetModuleHandleExW_WOW64(L"kernel32.dll", &WOW64_dummy_process_id); - if (!hKernel32_WOW64) + HANDLE hEventEnd = CreateEventEx(&sa, nullptr, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS); + if (!hEventEnd) { - INIT_ERROR_DATA(error_data, INJ_ERR_ADVANCED_NOT_DEFINED); + INIT_ERROR_DATA(error_data, GetLastError()); + + LOG(" CreateEventEx failed: %08X\n", error_data.AdvErrorCode); - LOG(" Failed to get WOW64 kernel32.dll\n"); + CloseHandle(hEventStart); - return INJ_ERR_WOW64_KERNEL32_MISSING; + return INJ_ERR_CREATE_EVENT_FAILED; } - HANDLE hWOW64_dummy_process = OpenProcess(PROCESS_VM_READ, FALSE, WOW64_dummy_process_id); - if (!hWOW64_dummy_process) + wchar_t hEventStart_string[9]{ 0 }; + _ultow_s(MDWD(hEventStart), hEventStart_string, 0x10); + + wchar_t hEventEnd_string[9]{ 0 }; + _ultow_s(MDWD(hEventEnd), hEventEnd_string, 0x10); + + wchar_t RootPath[MAX_PATH * 2]{ 0 }; + StringCbCopyW(RootPath, sizeof(RootPath), g_RootPathW.c_str()); + StringCbCatW(RootPath, sizeof(RootPath), SM_EXE_FILENAME86); + + wchar_t cmdLine[MAX_PATH]{ 0 }; + StringCbCatW(cmdLine, sizeof(cmdLine), L"\"" SM_EXE_FILENAME86 "\" " ID_WOW64 " "); + StringCbCatW(cmdLine, sizeof(cmdLine), hEventStart_string); + StringCbCatW(cmdLine, sizeof(cmdLine), L" "); + StringCbCatW(cmdLine, sizeof(cmdLine), hEventEnd_string); + + if (!CreateProcessW(RootPath, cmdLine, nullptr, nullptr, TRUE, CREATE_NO_WINDOW, nullptr, nullptr, &si, &pi)) { INIT_ERROR_DATA(error_data, GetLastError()); - LOG(" Failed to attach to WOW64 process\n"); + LOG(" CreateProcessW failed: %08X\n", error_data.AdvErrorCode); + + CloseHandle(hEventStart); + CloseHandle(hEventEnd); + + return INJ_ERR_CREATE_PROCESS_FAILED; + } + + DWORD dwWaitRet = WaitForSingleObject(hEventStart, 1000); + if (dwWaitRet != WAIT_OBJECT_0) + { + DWORD err_ret = INJ_ERR_WAIT_FAILED; + + if (dwWaitRet == WAIT_FAILED) + { + INIT_ERROR_DATA(error_data, GetLastError()); + } + else + { + INIT_ERROR_DATA(error_data, dwWaitRet); + err_ret = INJ_ERR_WAIT_TIMEOUT; + } + + LOG(" WaitForSingleObject failed: %08X\n", error_data.AdvErrorCode); + + SetEvent(hEventEnd); + + CloseHandle(hEventStart); + CloseHandle(hEventEnd); + + CloseHandle(pi.hThread); + CloseHandle(pi.hProcess); + + return err_ret; + } + + auto wow64_pid = GetProcessId(pi.hProcess); + LOG(" Successfully spawned wow64 dummy process: %08X (%d)\n", wow64_pid, wow64_pid); + + g_hNTDLL_WOW64 = GetModuleHandleExW_WOW64(pi.hProcess, L"ntdll.dll"); + auto hKernel32_WOW64 = GetModuleHandleExW_WOW64(pi.hProcess, L"kernel32.dll"); + + if (!g_hNTDLL_WOW64 || !hKernel32_WOW64) + { + INIT_ERROR_DATA(error_data, INJ_ERR_ADVANCED_NOT_DEFINED); + + if (!g_hNTDLL_WOW64) + { + LOG(" Failed to get WOW64 ntdll.dll\n"); + } + + if (!hKernel32_WOW64) + { + LOG(" Failed to get WOW64 kernel32.dll\n"); + } + + SetEvent(hEventEnd); - return INJ_ERR_OPEN_WOW64_PROCESS; + CloseHandle(hEventStart); + CloseHandle(hEventEnd); + + CloseHandle(pi.hThread); + CloseHandle(pi.hProcess); + + return INJ_ERR_WOW64_NTDLL_MISSING; } - if (!GetProcAddressEx_WOW64(hWOW64_dummy_process, hKernel32_WOW64, "LoadLibraryExW", WOW64::LoadLibraryExW_WOW64) || !GetProcAddressEx_WOW64(hWOW64_dummy_process, hKernel32_WOW64, "GetLastError", WOW64::GetLastError_WOW64)) + LOG(" WOW64 kernel32.dll loaded at %08X\n", MDWD(hKernel32_WOW64)); + + bool b_lle = GetProcAddressEx_WOW64(pi.hProcess, hKernel32_WOW64, "LoadLibraryExW", WOW64::LoadLibraryExW_WOW64); + bool b_gle = GetProcAddressEx_WOW64(pi.hProcess, hKernel32_WOW64, "GetLastError", WOW64::GetLastError_WOW64); + + SetEvent(hEventEnd); + + CloseHandle(hEventStart); + CloseHandle(hEventEnd); + + CloseHandle(pi.hThread); + CloseHandle(pi.hProcess); + + if (!b_lle || !b_gle) { INIT_ERROR_DATA(error_data, INJ_ERR_ADVANCED_NOT_DEFINED); - LOG(" Missing WOW64 specific imports\n"); + if (!b_lle) + { + LOG(" Failed to resolve WOW64 address of LoadLibrarExW\n"); + } - CloseHandle(hWOW64_dummy_process); + if (!b_gle) + { + LOG(" Failed to resolve WOW64 address of GetLastError\n"); + } return INJ_ERR_GET_PROC_ADDRESS_FAIL; } - CloseHandle(hWOW64_dummy_process); + LOG(" LoadLibraryExW = %08X\n", WOW64::LoadLibraryExW_WOW64); + LOG(" GetLastError = %08X\n", WOW64::GetLastError_WOW64); - LOG(" Waiting for wow64 symbol parser to finish initialization\n"); + LOG(" Waiting for WOW64 symbol parser to finish initialization\n"); while (sym_ntdll_wow64_ret.wait_for(std::chrono::milliseconds(100)) != std::future_status::ready); + LOG(" WOW64 ntdll.dll loaded at %08X\n", MDWD(g_hNTDLL_WOW64)); + DWORD sym_ret = sym_ntdll_wow64_ret.get(); if (sym_ret != SYMBOL_ERR_SUCCESS) { @@ -95,117 +205,73 @@ DWORD ResolveImports_WOW64(ERROR_DATA & error_data) LOG(" Start loading WOW64 ntdll symbols\n"); - if (LoadNtSymbolWOW64(S_FUNC(LdrLoadDll))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolWOW64(S_FUNC(LdrUnloadDll))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolWOW64(S_FUNC(LdrLoadDll))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolWOW64(S_FUNC(LdrUnloadDll))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolWOW64(S_FUNC(LdrpLoadDll))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolWOW64(S_FUNC(LdrpLoadDll))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolWOW64(S_FUNC(LdrpLoadDllInternal))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolWOW64(S_FUNC(LdrGetDllHandleEx))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolWOW64(S_FUNC(LdrGetProcedureAddress))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolWOW64(S_FUNC(LdrGetDllHandleEx))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolWOW64(S_FUNC(LdrGetProcedureAddress))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolWOW64(WOW64::memmove_WOW64, "memmove")) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolWOW64(S_FUNC(RtlZeroMemory))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolWOW64(S_FUNC(RtlAllocateHeap))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolWOW64(S_FUNC(RtlFreeHeap))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolWOW64(WOW64::memmove_WOW64, "memmove")) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolWOW64(S_FUNC(RtlZeroMemory))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolWOW64(S_FUNC(RtlAllocateHeap))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolWOW64(S_FUNC(RtlFreeHeap))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolWOW64(S_FUNC(RtlAnsiStringToUnicodeString))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolWOW64(S_FUNC(RtlAnsiStringToUnicodeString))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolWOW64(S_FUNC(RtlRbRemoveNode))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolWOW64(S_FUNC(NtOpenFile))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolWOW64(S_FUNC(NtReadFile))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolWOW64(S_FUNC(NtSetInformationFile))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolWOW64(S_FUNC(NtQueryInformationFile))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolWOW64(S_FUNC(NtOpenFile))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolWOW64(S_FUNC(NtReadFile))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolWOW64(S_FUNC(NtSetInformationFile))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolWOW64(S_FUNC(NtQueryInformationFile))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - - if (LoadNtSymbolWOW64(S_FUNC(NtClose))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolWOW64(S_FUNC(NtClose))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolWOW64(S_FUNC(NtAllocateVirtualMemory))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolWOW64(S_FUNC(NtFreeVirtualMemory))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolWOW64(S_FUNC(NtProtectVirtualMemory))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - - if (LoadNtSymbolWOW64(S_FUNC(LdrpPreprocessDllName))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolWOW64(S_FUNC(RtlInsertInvertedFunctionTable))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolWOW64(S_FUNC(LdrpHandleTlsData))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolWOW64(S_FUNC(NtAllocateVirtualMemory))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolWOW64(S_FUNC(NtFreeVirtualMemory))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolWOW64(S_FUNC(NtProtectVirtualMemory))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolWOW64(S_FUNC(LdrLockLoaderLock))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolWOW64(S_FUNC(LdrUnlockLoaderLock))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolWOW64(S_FUNC(NtCreateSection))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolWOW64(S_FUNC(NtMapViewOfSection))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolWOW64(S_FUNC(LdrpModuleBaseAddressIndex))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolWOW64(S_FUNC(LdrpMappingInfoIndex))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolWOW64(S_FUNC(LdrpHeap))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolWOW64(S_FUNC(LdrpInvertedFunctionTable))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolWOW64(S_FUNC(RtlInsertInvertedFunctionTable))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolWOW64(S_FUNC(LdrpHandleTlsData))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - LOG(" WOW64 ntdll symbols loaded\n"); + if (LoadNtSymbolWOW64(S_FUNC(LdrLockLoaderLock))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolWOW64(S_FUNC(LdrUnlockLoaderLock))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - return INJ_ERR_SUCCESS; -} - -HINSTANCE GetModuleHandleExW_WOW64(const wchar_t * szModuleName, DWORD * PidOut) -{ - HINSTANCE hRet = NULL; + if (LoadNtSymbolWOW64(S_FUNC(RtlAddVectoredExceptionHandler))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolWOW64(S_FUNC(RtlRemoveVectoredExceptionHandler))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if (LoadNtSymbolWOW64(S_FUNC(LdrpHeap))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolWOW64(S_FUNC(LdrpInvertedFunctionTable))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (hSnap == INVALID_HANDLE_VALUE) + if (IsWin7OrGreater() && !IsWin8OrGreater()) { - while (GetLastError() == ERROR_BAD_LENGTH) - { - hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); - - if (hSnap != INVALID_HANDLE_VALUE) - { - break; - } - } - - Sleep(5); + if (LoadNtSymbolWOW64(S_FUNC(LdrpDefaultPath))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; } - if (hSnap == INVALID_HANDLE_VALUE || !hSnap) + if (IsWin8OrGreater()) { - return NULL; + if (LoadNtSymbolWOW64(S_FUNC(RtlRbRemoveNode))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolWOW64(S_FUNC(LdrpModuleBaseAddressIndex))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolWOW64(S_FUNC(LdrpMappingInfoIndex))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; } - PROCESSENTRY32W PE32{ 0 }; - PE32.dwSize = sizeof(PROCESSENTRY32W); - - BOOL bRet = Process32FirstW(hSnap, &PE32); - - for (; bRet; bRet = Process32NextW(hSnap, &PE32)) + if (IsWin81OrGreater()) { - HANDLE hProc = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_VM_READ, FALSE, PE32.th32ProcessID); - if (!hProc) - { - continue; - } - - BOOL bWOW64 = FALSE; - if (!IsWow64Process(hProc, &bWOW64) || !bWOW64) - { - CloseHandle(hProc); - - continue; - } - - hRet = GetModuleHandleExW_WOW64(hProc, szModuleName); - - CloseHandle(hProc); - - if (hRet) - { - if (PidOut) - { - *PidOut = PE32.th32ProcessID; - } + if (LoadNtSymbolWOW64(S_FUNC(LdrProtectMrdata))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + } - break; - } + if (IsWin10OrGreater()) + { + if (LoadNtSymbolWOW64(S_FUNC(LdrpPreprocessDllName))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolWOW64(S_FUNC(LdrpLoadDllInternal))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; } - CloseHandle(hSnap); + LOG(" WOW64 ntdll symbols loaded\n"); - return hRet; + return INJ_ERR_SUCCESS; } HINSTANCE GetModuleHandleExW_WOW64(HANDLE hTargetProc, const wchar_t * lpModuleName) @@ -235,15 +301,33 @@ HINSTANCE GetModuleHandleExW_WOW64(HANDLE hTargetProc, const wchar_t * lpModuleN } BOOL bRet = Module32FirstW(hSnap, &ME32); - do + while (bRet) { - if (!_wcsicmp(ME32.szModule, lpModuleName) && (ME32.modBaseAddr < (BYTE *)0x7FFFF000)) + if (ME32.modBaseAddr && !_wcsicmp(ME32.szModule, lpModuleName) && (ME32.modBaseAddr < (BYTE *)0x7FFFF000)) { + BYTE header[0x1000]; + if (!ReadProcessMemory(hTargetProc, ME32.modBaseAddr, header, sizeof(header), nullptr)) + { + bRet = Module32NextW(hSnap, &ME32); + + continue; + } + + IMAGE_DOS_HEADER * pDos = ReCa(header); + IMAGE_NT_HEADERS32 * pNT = ReCa(header + pDos->e_lfanew); + + if (pNT->FileHeader.Machine != IMAGE_FILE_MACHINE_I386) + { + bRet = Module32NextW(hSnap, &ME32); + + continue; + } + break; } bRet = Module32NextW(hSnap, &ME32); - } while (bRet); + } CloseHandle(hSnap); diff --git a/GH Injector Library/Import Handler.cpp b/GH Injector Library/Import Handler.cpp index 165fdf2..492a47a 100644 --- a/GH Injector Library/Import Handler.cpp +++ b/GH Injector Library/Import Handler.cpp @@ -2,6 +2,71 @@ #include "Import Handler.h" +bool IsWin7OrGreater() +{ + return (GetOSVersion() >= g_Win7); +} + +bool IsWin8OrGreater() +{ + return (GetOSVersion() >= g_Win8); +} + +bool IsWin81OrGreater() +{ + return (GetOSVersion() >= g_Win81); +} + +bool IsWin10OrGreater() +{ + return (GetOSVersion() >= g_Win10); +} + +bool IsWin11OrGreater() +{ + return (GetOSVersion() >= g_Win10 && GetOSBuildVersion() >= g_Win11_21H2); +} + +DWORD GetOSVersion(DWORD * error_code) +{ + if (g_OSVersion != 0) + { + return g_OSVersion; + } + +#ifdef _WIN64 + PEB * pPEB = ReCa(__readgsqword(0x60)); +#else + PEB * pPEB = ReCa(__readfsdword(0x30)); +#endif + + if (!pPEB) + { + if (error_code) + { + *error_code = INJ_ERR_CANT_GET_PEB; + } + + return 0; + } + + DWORD v_hi = pPEB->OSMajorVersion; + DWORD v_lo = pPEB->OSMinorVersion; + + for (; v_lo >= 10; v_lo /= 10); + + g_OSVersion = v_hi * 10 + v_lo; + + g_OSBuildNumber = pPEB->OSBuildNumber; + + return g_OSVersion; +} + +DWORD GetOSBuildVersion() +{ + return g_OSBuildNumber; +} + using namespace NATIVE; #define S_FUNC(f) f, #f @@ -27,8 +92,30 @@ DWORD ResolveImports(ERROR_DATA & error_data) { LOG(" ResolveImports called\n"); + DWORD err = ERROR_SUCCESS; + if (!GetOSVersion(&err)) + { + INIT_ERROR_DATA(error_data, err); + + LOG(" Failed to determine Windows version\n"); + + return INJ_ERR_WINDOWS_VERSION; + } + + if (GetOSVersion() < g_Win7) + { + INIT_ERROR_DATA(error_data, INJ_ERR_ADVANCED_NOT_DEFINED); + + LOG(" This Windows version is not supported\n"); + + return INJ_ERR_WINDOWS_TOO_OLD; + } + g_hNTDLL = GetModuleHandle(TEXT("ntdll.dll")); + printf(" ntdll.dll loaded at %p\n", g_hNTDLL); + printf(" OSVersion = %d\n OSBuildVersion = %d\n", GetOSVersion(), GetOSBuildVersion()); + HINSTANCE hK32 = GetModuleHandle(TEXT("kernel32.dll")); if (!hK32) { @@ -65,54 +152,84 @@ DWORD ResolveImports(ERROR_DATA & error_data) return INJ_ERR_SYMBOL_INIT_FAIL; } + printf("LoadLibrary: %p\n", LoadLibraryExW); + LOG(" Start loading native ntdll symbols\n"); - if (LoadNtSymbolNative(S_FUNC(LdrLoadDll))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolNative(S_FUNC(LdrUnloadDll))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolNative(S_FUNC(LdrLoadDll))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolNative(S_FUNC(LdrUnloadDll))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + + if (LoadNtSymbolNative(S_FUNC(LdrpLoadDll))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolNative(S_FUNC(LdrpLoadDll))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolNative(S_FUNC(LdrpLoadDllInternal))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolNative(S_FUNC(LdrGetDllHandleEx))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolNative(S_FUNC(LdrGetProcedureAddress))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolNative(S_FUNC(LdrGetDllHandleEx))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolNative(S_FUNC(LdrGetProcedureAddress))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolNative(S_FUNC(NtQueryInformationProcess))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolNative(S_FUNC(NtQuerySystemInformation))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolNative(S_FUNC(NtQueryInformationThread))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolNative(S_FUNC(NtQueryInformationProcess))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolNative(S_FUNC(NtQuerySystemInformation))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolNative(S_FUNC(NtQueryInformationThread))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolNative(NATIVE::memmove, "memmove")) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; //I hate compilers + if (LoadNtSymbolNative(S_FUNC(RtlZeroMemory))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolNative(S_FUNC(RtlAllocateHeap))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolNative(S_FUNC(RtlFreeHeap))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolNative(NATIVE::memmove, "memmove")) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; //I hate compilers - if (LoadNtSymbolNative(S_FUNC(RtlZeroMemory))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolNative(S_FUNC(RtlAllocateHeap))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolNative(S_FUNC(RtlFreeHeap))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolNative(S_FUNC(RtlAnsiStringToUnicodeString))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolNative(S_FUNC(RtlAnsiStringToUnicodeString))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolNative(S_FUNC(NtOpenFile))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolNative(S_FUNC(NtReadFile))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolNative(S_FUNC(NtSetInformationFile))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolNative(S_FUNC(NtQueryInformationFile))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolNative(S_FUNC(RtlRbRemoveNode))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolNative(S_FUNC(NtOpenFile))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolNative(S_FUNC(NtReadFile))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolNative(S_FUNC(NtSetInformationFile))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolNative(S_FUNC(NtQueryInformationFile))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolNative(S_FUNC(NtClose))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolNative(S_FUNC(NtClose))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolNative(S_FUNC(NtAllocateVirtualMemory))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolNative(S_FUNC(NtFreeVirtualMemory))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolNative(S_FUNC(NtProtectVirtualMemory))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolNative(S_FUNC(NtAllocateVirtualMemory))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolNative(S_FUNC(NtFreeVirtualMemory))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolNative(S_FUNC(NtProtectVirtualMemory))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolNative(S_FUNC(NtCreateSection))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolNative(S_FUNC(NtMapViewOfSection))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolNative(S_FUNC(NtCreateThreadEx))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolNative(S_FUNC(RtlQueueApcWow64Thread))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolNative(S_FUNC(NtCreateThreadEx))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolNative(S_FUNC(RtlQueueApcWow64Thread))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolNative(S_FUNC(LdrpPreprocessDllName))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolNative(S_FUNC(RtlInsertInvertedFunctionTable))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolNative(S_FUNC(LdrpHandleTlsData))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolNative(S_FUNC(RtlInsertInvertedFunctionTable))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolNative(S_FUNC(LdrpHandleTlsData))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolNative(S_FUNC(LdrLockLoaderLock))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolNative(S_FUNC(LdrUnlockLoaderLock))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolNative(S_FUNC(LdrLockLoaderLock))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolNative(S_FUNC(LdrUnlockLoaderLock))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolNative(S_FUNC(LdrpModuleBaseAddressIndex))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolNative(S_FUNC(LdrpMappingInfoIndex))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolNative(S_FUNC(LdrpHeap))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; - if (LoadNtSymbolNative(S_FUNC(LdrpInvertedFunctionTable))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolNative(S_FUNC(RtlAddVectoredExceptionHandler))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolNative(S_FUNC(RtlRemoveVectoredExceptionHandler))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + + if (LoadNtSymbolNative(S_FUNC(LdrpHeap))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolNative(S_FUNC(LdrpInvertedFunctionTable))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + + if (IsWin7OrGreater() && !IsWin8OrGreater()) + { + if (LoadNtSymbolNative(S_FUNC(LdrpDefaultPath))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + } + + if (IsWin8OrGreater()) + { + if (LoadNtSymbolNative(S_FUNC(RtlRbRemoveNode))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolNative(S_FUNC(LdrpModuleBaseAddressIndex))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolNative(S_FUNC(LdrpMappingInfoIndex))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + } + + if (IsWin81OrGreater()) + { + if (LoadNtSymbolNative(S_FUNC(LdrProtectMrdata))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + } + + if (IsWin10OrGreater()) + { + if (LoadNtSymbolNative(S_FUNC(LdrpPreprocessDllName))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + if (LoadNtSymbolNative(S_FUNC(LdrpLoadDllInternal))) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; + } + +#ifdef _WIN64 + if (LoadNtSymbolNative(NATIVE::RtlAddFunctionTable, "RtlAddFunctionTable")) return INJ_ERR_GET_SYMBOL_ADDRESS_FAILED; +#endif LOG(" Native ntdll symbols loaded\n"); diff --git a/GH Injector Library/Import Handler.h b/GH Injector Library/Import Handler.h index 1b9d285..7fde11d 100644 --- a/GH Injector Library/Import Handler.h +++ b/GH Injector Library/Import Handler.h @@ -1,11 +1,13 @@ #pragma once -#include "NT Stuff.h" +#include "NT Funcs.h" #include "Symbol Parser.h" inline ERROR_DATA import_handler_error_data; inline std::shared_future import_handler_ret; +//Macros for import definitions + #define NT_FUNC(func) inline f_##func func = nullptr #define NT_FUNC_LOCAL(func) f_##func func #define NT_FUNC_CONSTRUCTOR_INIT(func) this->func = NATIVE::func @@ -19,6 +21,78 @@ inline std::shared_future import_handler_ret; #define WOW64_FUNCTION_POINTER_LOCAL(func) DWORD func #define WOW64_FUNC_CONSTRUCTOR_INIT(func) this->func = WOW64::func##_WOW64 +//Command line codes for "GH Injector SM - XX.exe" + +#define ID_SWHEX "0" //use for SetWindowsHookEx +#define ID_WOW64 "1" //use for wow64 addresses +#define ID_KC "2" //use for KernelCallbackTable + +//Global variable to store the base address of the current image of the injector. Initialized in DllMain. +inline HINSTANCE g_hInjMod = NULL; + +//Global variable to store the root directory of the module +inline std::wstring g_RootPathW; + +inline DWORD g_OSVersion = 0; +inline DWORD g_OSBuildNumber = 0; + +#define g_Win7 61 +#define g_Win8 62 +#define g_Win81 63 +#define g_Win10 100 +#define g_Win11 100 + +#define g_Win7_SP1 7601 +#define g_Win8_SP1 9600 +#define g_Win10_1507 10240 +#define g_Win10_1511 10586 +#define g_Win10_1607 14393 +#define g_Win10_1703 15063 +#define g_Win10_1709 16299 +#define g_Win10_1803 17134 +#define g_Win10_1809 17763 +#define g_Win10_1903 18362 +#define g_Win10_1909 18363 +#define g_Win10_2004 19041 +#define g_Win10_20H2 19042 +#define g_Win10_21H1 19043 +#define g_Win11_21H2 22000 + +bool IsWin7OrGreater(); +bool IsWin8OrGreater(); +bool IsWin81OrGreater(); +bool IsWin10OrGreater(); +bool IsWin11OrGreater(); +//These functions are used to determine the currently running version of windows. GetNTDLLVersion needs to be successfully called before these work. +// +//Arguements: +// none +// +//Returnvalue (bool): +/// true: Running OS is equal or newer than specified in the function name. +/// false: Running OS is older than specified in the function name. + +DWORD GetOSVersion(DWORD * error_code = nullptr); +//This function is used to determine the version of the operating system. +// +//Arguments: +// errode_code (DWORD *): +/// A reference to a DWORD which will receive an error code if the function fails (optional). +// +//Returnvalue (DWORD): +/// On success: The version of the operating system to 1 decimal place (multiplied by 10 as an integer) +/// On failure: 0. + +DWORD GetOSBuildVersion(); +//This function is used to determine the build version of the operating system. +// +//Arguments: +// none +// +//Returnvalue (DWORD): +/// On success: The build version of the operating system. +/// On failure: 0. + namespace NATIVE { WIN32_FUNC(LoadLibraryExW); @@ -54,6 +128,7 @@ namespace NATIVE NT_FUNC(RtlAnsiStringToUnicodeString); + NT_FUNC(RtlRbInsertNodeEx); NT_FUNC(RtlRbRemoveNode); NT_FUNC(NtOpenFile); @@ -67,10 +142,23 @@ namespace NATIVE NT_FUNC(NtFreeVirtualMemory); NT_FUNC(NtProtectVirtualMemory); + NT_FUNC(NtCreateSection); + NT_FUNC(NtMapViewOfSection); + + NT_FUNC(LdrProtectMrdata); + + NT_FUNC(RtlAddVectoredExceptionHandler); + NT_FUNC(RtlRemoveVectoredExceptionHandler); + NT_FUNC(LdrpModuleBaseAddressIndex); NT_FUNC(LdrpMappingInfoIndex); NT_FUNC(LdrpHeap); NT_FUNC(LdrpInvertedFunctionTable); + NT_FUNC(LdrpDefaultPath); + +#ifdef _WIN64 + NT_FUNC(RtlAddFunctionTable); +#endif } DWORD ResolveImports(ERROR_DATA & error_data); @@ -134,10 +222,19 @@ namespace WOW64 WOW64_FUNCTION_POINTER(NtFreeVirtualMemory); WOW64_FUNCTION_POINTER(NtProtectVirtualMemory); + WOW64_FUNCTION_POINTER(NtCreateSection); + WOW64_FUNCTION_POINTER(NtMapViewOfSection); + + WOW64_FUNCTION_POINTER(LdrProtectMrdata); + + WOW64_FUNCTION_POINTER(RtlAddVectoredExceptionHandler); + WOW64_FUNCTION_POINTER(RtlRemoveVectoredExceptionHandler); + WOW64_FUNCTION_POINTER(LdrpModuleBaseAddressIndex); WOW64_FUNCTION_POINTER(LdrpMappingInfoIndex); WOW64_FUNCTION_POINTER(LdrpHeap); WOW64_FUNCTION_POINTER(LdrpInvertedFunctionTable); + WOW64_FUNCTION_POINTER(LdrpDefaultPath); } DWORD ResolveImports_WOW64(ERROR_DATA & error_data); @@ -151,26 +248,13 @@ DWORD ResolveImports_WOW64(ERROR_DATA & error_data); /// On success: INJ_ERR_SUCCESS (0) /// On failure: An error code. See Error.h. -HINSTANCE GetModuleHandleExW_WOW64(const wchar_t * lpModuleName, DWORD * PidOut = nullptr); -//Uses CreateToolHelp32Snapshot with Process32FirstW/NextW and IsWow46Process to find a wow64 process and then forwards the call to GetModuleHandleExW_WOW64 with a process handle (see next declaration). -// -//Arguments: -// szModuleName (const wchar_t*): -/// The name of the module including the file extension. -// PidOut (DWORD*): -/// The PID of the wow64 process that was used to determine the address of the module. This parameter can be 0. -// -//Returnvalue (HINSTANCE): -/// On success: base address of the image. -/// On failure: NULL. - HINSTANCE GetModuleHandleExW_WOW64(HANDLE hTargetProc, const wchar_t * lpModuleName); //Uses CreateToolHelp32Snapshot and Module32First/Next to retrieve the baseaddress of an image. //Only scans WOW64 modules of a process. // //Arguments: // hTargetProc (HANDLE): -/// A handle to the target process with either PROCESS_QUERY_INFORMATION or PROCESS_QUERY_LIMITED_INFORMATION. +/// A handle to the target process with PROCESS_VM_READ and PROCESS_QUERY_INFORMATION or PROCESS_QUERY_LIMITED_INFORMATION. // szModuleName (const wchar_t*): /// The name of the module including the file extension. // @@ -184,7 +268,7 @@ bool GetProcAddressExW_WOW64(HANDLE hTargetProc, const wchar_t * szModuleName, c // //Arguments: // hTargetProc (HANDLE): -/// A handle to the target process with either PROCESS_QUERY_INFORMATION or PROCESS_QUERY_LIMITED_INFORMATION. +/// A handle to the target process with PROCESS_VM_READ and PROCESS_QUERY_INFORMATION or PROCESS_QUERY_LIMITED_INFORMATION. // szModuleName (const wchar_t*): /// The name of the module including the file extension. // szProcName (const char*): diff --git a/GH Injector Library/Injection Generic WOW64.cpp b/GH Injector Library/Injection Generic WOW64.cpp index c1e8f6b..fdf435a 100644 --- a/GH Injector Library/Injection Generic WOW64.cpp +++ b/GH Injector Library/Injection Generic WOW64.cpp @@ -3,7 +3,6 @@ #ifdef _WIN64 #include "Injection Internal.h" -#include "Manual Mapping.h" #include "WOW64 Shells.h" using namespace WOW64; @@ -20,8 +19,10 @@ DWORD InjectDLL_WOW64(const wchar_t * szDllFile, HANDLE hTargetProc, INJECTION_M } INJECTION_DATA_INTERNAL_WOW64 data{ 0 }; - data.Flags = Flags; - data.Mode = Mode; + data.Flags = Flags; + data.Mode = Mode; + data.OSVersion = GetOSVersion(); + data.OSBuildNumber = GetOSBuildVersion(); size_t len = 0; HRESULT hr = StringCbLengthW(szDllFile, sizeof(data.Path), &len); @@ -50,11 +51,19 @@ DWORD InjectDLL_WOW64(const wchar_t * szDllFile, HANDLE hTargetProc, INJECTION_M LOG(" Shell data initialized\n"); ULONG_PTR ShellSize = sizeof(InjectionShell_WOW64); - SIZE_T AllocationSize = sizeof(INJECTION_DATA_INTERNAL_WOW64) + ShellSize + 0x10; + ULONG_PTR VEHShellSize = sizeof(VectoredHandlerShell_WOW64); + if (!(Flags & INJ_UNLINK_FROM_PEB)) + { + VEHShellSize = 0; + } + + SIZE_T AllocationSize = sizeof(INJECTION_DATA_INTERNAL_WOW64) + ShellSize + BASE_ALIGNMENT; BYTE * pAllocBase = ReCa(VirtualAllocEx(hTargetProc, nullptr, AllocationSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE)); - BYTE * pArg = pAllocBase; - BYTE * pShell = ReCa(ALIGN_UP(ReCa(pArg + sizeof(INJECTION_DATA_INTERNAL_WOW64)), 0x10)); + + BYTE * pArg = pAllocBase; + BYTE * pShell = ReCa(ALIGN_UP(ReCa(pArg + sizeof(INJECTION_DATA_INTERNAL_WOW64)), BASE_ALIGNMENT)); + BYTE * pVEHShell = nullptr; if (!pArg) { @@ -65,14 +74,44 @@ DWORD InjectDLL_WOW64(const wchar_t * szDllFile, HANDLE hTargetProc, INJECTION_M return INJ_ERR_OUT_OF_MEMORY_EXT; } + if (VEHShellSize) + { + pVEHShell = ReCa(VirtualAllocEx(hTargetProc, nullptr, VEHShellSize + sizeof(VEH_SHELL_DATA) + BASE_ALIGNMENT, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE)); + //VEH_SHELL_DATA is bigger than the wow64 version of it, no need to define it + + if (!pVEHShell) + { + INIT_ERROR_DATA(error_data, GetLastError()); + + LOG(" VirtualAllocEx failed: %08X\n", error_data.AdvErrorCode); + + VirtualFreeEx(hTargetProc, pAllocBase, 0, MEM_RELEASE); + + return INJ_ERR_OUT_OF_MEMORY_EXT; + } + + data.pVEHShell = MDWD(pVEHShell); + data.VEHShellSize = MDWD(VEHShellSize); + } + LOG(" Shellsize = %IX\nTotal size = %08X\npArg = %p\npShell = %p\n", ShellSize, (DWORD)AllocationSize, pArg, pShell); + if (VEHShellSize) + { + LOG(" pVEHShell = %p\n", pVEHShell); + } + if (!WriteProcessMemory(hTargetProc, pArg, &data, sizeof(INJECTION_DATA_INTERNAL_WOW64), nullptr)) { INIT_ERROR_DATA(error_data, GetLastError()); LOG(" WriteProcessMemory failed: %08X\n", error_data.AdvErrorCode); + if (pVEHShell) + { + VirtualFreeEx(hTargetProc, pVEHShell, 0, MEM_RELEASE); + } + VirtualFreeEx(hTargetProc, pAllocBase, 0, MEM_RELEASE); return INJ_ERR_WPM_FAIL; @@ -84,6 +123,11 @@ DWORD InjectDLL_WOW64(const wchar_t * szDllFile, HANDLE hTargetProc, INJECTION_M LOG(" WriteProcessMemory failed: %08X\n", error_data.AdvErrorCode); + if (pVEHShell) + { + VirtualFreeEx(hTargetProc, pVEHShell, 0, MEM_RELEASE); + } + VirtualFreeEx(hTargetProc, pAllocBase, 0, MEM_RELEASE); return INJ_ERR_WPM_FAIL; @@ -91,6 +135,27 @@ DWORD InjectDLL_WOW64(const wchar_t * szDllFile, HANDLE hTargetProc, INJECTION_M LOG(" Shell written to memory\n"); + if (VEHShellSize) + { + if (!WriteProcessMemory(hTargetProc, pVEHShell, VectoredHandlerShell, VEHShellSize, nullptr)) + { + INIT_ERROR_DATA(error_data, GetLastError()); + + LOG(" WriteProcessMemory failed: %08X\n", error_data.AdvErrorCode); + + if (pVEHShell) + { + VirtualFreeEx(hTargetProc, pVEHShell, 0, MEM_RELEASE); + } + + VirtualFreeEx(hTargetProc, pAllocBase, 0, MEM_RELEASE); + + return INJ_ERR_WPM_FAIL; + } + + LOG(" VEHShell written to memory\n"); + } + LOG(" Entering StartRoutine_WOW64\n"); DWORD remote_ret = 0; @@ -104,6 +169,11 @@ DWORD InjectDLL_WOW64(const wchar_t * szDllFile, HANDLE hTargetProc, INJECTION_M if (Method != LAUNCH_METHOD::LM_QueueUserAPC && !(Method == LAUNCH_METHOD::LM_HijackThread && dwRet == SR_HT_ERR_REMOTE_TIMEOUT)) { + if (pVEHShell) + { + VirtualFreeEx(hTargetProc, pVEHShell, 0, MEM_RELEASE); + } + VirtualFreeEx(hTargetProc, pAllocBase, 0, MEM_RELEASE); } @@ -120,6 +190,11 @@ DWORD InjectDLL_WOW64(const wchar_t * szDllFile, HANDLE hTargetProc, INJECTION_M if (Method != LAUNCH_METHOD::LM_QueueUserAPC) { + if (pVEHShell) + { + VirtualFreeEx(hTargetProc, pVEHShell, 0, MEM_RELEASE); + } + VirtualFreeEx(hTargetProc, pAllocBase, 0, MEM_RELEASE); } @@ -176,8 +251,13 @@ INJECTION_FUNCTION_TABLE_WOW64::INJECTION_FUNCTION_TABLE_WOW64() WOW64_FUNC_CONSTRUCTOR_INIT(NtProtectVirtualMemory); + WOW64_FUNC_CONSTRUCTOR_INIT(RtlAddVectoredExceptionHandler); + WOW64_FUNC_CONSTRUCTOR_INIT(LdrProtectMrdata); + WOW64_FUNC_CONSTRUCTOR_INIT(LdrpInvertedFunctionTable); + WOW64_FUNC_CONSTRUCTOR_INIT(LdrpModuleBaseAddressIndex); WOW64_FUNC_CONSTRUCTOR_INIT(LdrpMappingInfoIndex); + WOW64_FUNC_CONSTRUCTOR_INIT(LdrpDefaultPath); } #endif \ No newline at end of file diff --git a/GH Injector Library/Injection Generic.cpp b/GH Injector Library/Injection Generic.cpp index 1330344..8ea430b 100644 --- a/GH Injector Library/Injection Generic.cpp +++ b/GH Injector Library/Injection Generic.cpp @@ -1,7 +1,13 @@ #include "pch.h" #include "Injection Internal.h" -#include "Manual Mapping.h" + +#define UNLINK_IF(e) \ +if (e.Flink && e.Blink) \ +{ \ + e.Flink->Blink = e.Blink; \ + e.Blink->Flink = e.Flink; \ +} using namespace NATIVE; @@ -25,8 +31,10 @@ DWORD InjectDLL(const wchar_t * szDllFile, HANDLE hTargetProc, INJECTION_MODE Mo } INJECTION_DATA_INTERNAL data{ 0 }; - data.Flags = Flags; - data.Mode = Mode; + data.Flags = Flags; + data.Mode = Mode; + data.OSVersion = GetOSVersion(); + data.OSBuildNumber = GetOSBuildVersion(); size_t len = 0; HRESULT hr = StringCbLengthW(szDllFile, sizeof(data.Path), &len); @@ -54,13 +62,21 @@ DWORD InjectDLL(const wchar_t * szDllFile, HANDLE hTargetProc, INJECTION_MODE Mo LOG(" Shell data initialized\n"); - ULONG_PTR ShellSize = ReCa(InjectionShell_End) - ReCa(InjectionShell); - SIZE_T AllocationSize = sizeof(INJECTION_DATA_INTERNAL) + ShellSize + 0x10; + ULONG_PTR ShellSize = ReCa(InjectionShell_End) - ReCa(InjectionShell); + ULONG_PTR VEHShellSize = ReCa(VectoredHandlerShell_End) - ReCa(VectoredHandlerShell); + + if (!(Flags & INJ_UNLINK_FROM_PEB)) + { + VEHShellSize = 0; + } - BYTE * pAllocBase = ReCa(VirtualAllocEx(hTargetProc, nullptr, AllocationSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE)); - BYTE * pArg = pAllocBase; - BYTE * pShell = ReCa(ALIGN_UP(ReCa(pArg) + sizeof(INJECTION_DATA_INTERNAL), 0x10)); + SIZE_T AllocationSize = sizeof(INJECTION_DATA_INTERNAL) + ShellSize + BASE_ALIGNMENT; + BYTE * pAllocBase = ReCa(VirtualAllocEx(hTargetProc, nullptr, AllocationSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE)); + BYTE * pArg = pAllocBase; + BYTE * pShell = ReCa(ALIGN_UP(ReCa(pArg) + sizeof(INJECTION_DATA_INTERNAL), BASE_ALIGNMENT)); + BYTE * pVEHShell = nullptr; + if (!pArg) { INIT_ERROR_DATA(error_data, GetLastError()); @@ -70,14 +86,43 @@ DWORD InjectDLL(const wchar_t * szDllFile, HANDLE hTargetProc, INJECTION_MODE Mo return INJ_ERR_OUT_OF_MEMORY_EXT; } + if(VEHShellSize) + { + pVEHShell = ReCa(VirtualAllocEx(hTargetProc, nullptr, VEHShellSize + sizeof(VEH_SHELL_DATA) + BASE_ALIGNMENT, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE)); + + if (!pVEHShell) + { + INIT_ERROR_DATA(error_data, GetLastError()); + + LOG(" VirtualAllocEx failed: %08X\n", error_data.AdvErrorCode); + + VirtualFreeEx(hTargetProc, pAllocBase, 0, MEM_RELEASE); + + return INJ_ERR_OUT_OF_MEMORY_EXT; + } + + data.pVEHShell = pVEHShell; + data.VEHShellSize = MDWD(VEHShellSize); + } + LOG(" Shellsize = %IX\n Total size = %08X\n pArg = %p\n pShell = %p\n", ShellSize, (DWORD)AllocationSize, pArg, pShell); + if (VEHShellSize) + { + LOG(" pVEHShell = %p\n", pVEHShell); + } + if (!WriteProcessMemory(hTargetProc, pArg, &data, sizeof(INJECTION_DATA_INTERNAL), nullptr)) { INIT_ERROR_DATA(error_data, GetLastError()); LOG(" WriteProcessMemory failed: %08X\n", error_data.AdvErrorCode); + if (pVEHShell) + { + VirtualFreeEx(hTargetProc, pVEHShell, 0, MEM_RELEASE); + } + VirtualFreeEx(hTargetProc, pAllocBase, 0, MEM_RELEASE); return INJ_ERR_WPM_FAIL; @@ -89,6 +134,11 @@ DWORD InjectDLL(const wchar_t * szDllFile, HANDLE hTargetProc, INJECTION_MODE Mo LOG(" WriteProcessMemory failed: %08X\n", error_data.AdvErrorCode); + if (pVEHShell) + { + VirtualFreeEx(hTargetProc, pVEHShell, 0, MEM_RELEASE); + } + VirtualFreeEx(hTargetProc, pAllocBase, 0, MEM_RELEASE); return INJ_ERR_WPM_FAIL; @@ -96,6 +146,27 @@ DWORD InjectDLL(const wchar_t * szDllFile, HANDLE hTargetProc, INJECTION_MODE Mo LOG(" Shell written to memory\n"); + if (VEHShellSize) + { + if (!WriteProcessMemory(hTargetProc, pVEHShell, VectoredHandlerShell, VEHShellSize, nullptr)) + { + INIT_ERROR_DATA(error_data, GetLastError()); + + LOG(" WriteProcessMemory failed: %08X\n", error_data.AdvErrorCode); + + if (pVEHShell) + { + VirtualFreeEx(hTargetProc, pVEHShell, 0, MEM_RELEASE); + } + + VirtualFreeEx(hTargetProc, pAllocBase, 0, MEM_RELEASE); + + return INJ_ERR_WPM_FAIL; + } + + LOG(" VEHShell written to memory\n"); + } + LOG(" Entering StartRoutine\n"); DWORD remote_ret = 0; @@ -109,6 +180,11 @@ DWORD InjectDLL(const wchar_t * szDllFile, HANDLE hTargetProc, INJECTION_MODE Mo if (Method != LAUNCH_METHOD::LM_QueueUserAPC && !(Method == LAUNCH_METHOD::LM_HijackThread && dwRet == SR_HT_ERR_REMOTE_TIMEOUT)) { + if (pVEHShell) + { + VirtualFreeEx(hTargetProc, pVEHShell, 0, MEM_RELEASE); + } + VirtualFreeEx(hTargetProc, pAllocBase, 0, MEM_RELEASE); } @@ -125,6 +201,11 @@ DWORD InjectDLL(const wchar_t * szDllFile, HANDLE hTargetProc, INJECTION_MODE Mo if (Method != LAUNCH_METHOD::LM_QueueUserAPC) { + if (pVEHShell) + { + VirtualFreeEx(hTargetProc, pVEHShell, 0, MEM_RELEASE); + } + VirtualFreeEx(hTargetProc, pAllocBase, 0, MEM_RELEASE); } @@ -170,11 +251,9 @@ DWORD __declspec(code_seg(".inj_sec$1")) __stdcall InjectionShell(INJECTION_DATA return INJ_ERR_NO_DATA; } - DWORD dwRet = INJ_ERR_SUCCESS; + INJECTION_FUNCTION_TABLE * f = &pData->f; + pData->ModuleFileName.szBuffer = pData->Path; - INJECTION_FUNCTION_TABLE * f = &pData->f; - pData->ModuleFileName.szBuffer = pData->Path; - if (pData->Mode == INJECTION_MODE::IM_LoadLibraryExW) { pData->hRet = f->pLoadLibraryExW(pData->ModuleFileName.szBuffer, nullptr, NULL); @@ -183,48 +262,79 @@ DWORD __declspec(code_seg(".inj_sec$1")) __stdcall InjectionShell(INJECTION_DATA { pData->LastError = f->pGetLastError(); - dwRet = INJ_ERR_LLEXW_FAILED; + return INJ_ERR_LLEXW_FAILED; } } else if (pData->Mode == INJECTION_MODE::IM_LdrLoadDll) { - pData->LastError = (DWORD)f->LdrLoadDll(nullptr, NULL, &pData->ModuleFileName, ReCa(&pData->hRet)); + ULONG Flags = NULL; - if (NT_FAIL(pData->LastError)) + LDR_SEARCH_PATH optPath{ 0 }; + if (pData->OSVersion == g_Win7) { - return INJ_ERR_LDRLDLL_FAILED; + optPath.szSearchPath = f->LdrpDefaultPath->szBuffer; + } + else + { + optPath.NoPath = TRUE; } - } - else if (pData->Mode == INJECTION_MODE::IM_LdrpLoadDll || pData->Mode == INJECTION_MODE::IM_LdrpLoadDllInternal) - { - pData->ModuleFileNameBundle.String.MaxLength = sizeof(pData->ModuleFileNameBundle.StaticBuffer); - pData->ModuleFileNameBundle.String.szBuffer = pData->ModuleFileNameBundle.StaticBuffer; - LDRP_LOAD_CONTEXT_FLAGS ctx_flags{ 0 }; - pData->LastError = (DWORD)f->LdrpPreprocessDllName(&pData->ModuleFileName, &pData->ModuleFileNameBundle, nullptr, &ctx_flags); + pData->LastError = (DWORD)f->LdrLoadDll(optPath, &Flags, &pData->ModuleFileName, ReCa(&pData->hRet)); if (NT_FAIL(pData->LastError)) { - return INJ_ERR_LDRP_PREPROCESS_FAILED; + return INJ_ERR_LDRLDLL_FAILED; } - - pData->SearchPathContext.OriginalFullDllName = pData->ModuleFileNameBundle.String.szBuffer; - + } + else if (pData->OSVersion >= g_Win10) + { LDR_DATA_TABLE_ENTRY * entry_out = nullptr; + LDRP_LOAD_CONTEXT_FLAGS ctx_flags{ 0 }; + + LDRP_PATH_SEARCH_CONTEXT * ctx = &pData->SearchPathContext; + ctx->OriginalFullDllName = pData->Path; if (pData->Mode == INJECTION_MODE::IM_LdrpLoadDll) { - pData->LastError = (DWORD)f->LdrpLoadDll(&pData->ModuleFileNameBundle.String, &pData->SearchPathContext, ctx_flags, &entry_out); + if (pData->OSBuildNumber <= g_Win10_1803) + { + auto _LdrpLoadDll = ReCa(f->LdrpLoadDll); - if (NT_FAIL(pData->LastError)) + if (pData->OSBuildNumber <= g_Win10_1511) + { + ReCa(ctx)->OriginalFullDllName = pData->Path; + ctx->OriginalFullDllName = nullptr; + } + + pData->LastError = _LdrpLoadDll(&pData->ModuleFileName, ctx, ctx_flags, TRUE, &entry_out); + } + else { - return INJ_ERR_LDRPLDLL_FAILED; + pData->LastError = f->LdrpLoadDll(&pData->ModuleFileName, ctx, ctx_flags, &entry_out); } } else { + pData->ModuleFileNameBundle.String.szBuffer = pData->ModuleFileNameBundle.StaticBuffer; + + pData->LastError = (DWORD)f->LdrpPreprocessDllName(&pData->ModuleFileName, &pData->ModuleFileNameBundle, nullptr, &ctx_flags); + + if (NT_FAIL(pData->LastError)) + { + return INJ_ERR_LDRP_PREPROCESS_FAILED; + } + ULONG_PTR unknown = 0; - pData->LastError = (DWORD)f->LdrpLoadDllInternal(&pData->ModuleFileNameBundle.String, &pData->SearchPathContext, ctx_flags, 4, nullptr, nullptr, &entry_out, &unknown); + + if (pData->OSBuildNumber > g_Win10_21H1) + { + auto _LdrpLoadDllInternal = ReCa(f->LdrpLoadDllInternal); + pData->LastError = _LdrpLoadDllInternal(&pData->ModuleFileNameBundle.String, ctx, ctx_flags, 4, nullptr, nullptr, &entry_out, &unknown, 0); + } + else + { + pData->LastError = f->LdrpLoadDllInternal(&pData->ModuleFileNameBundle.String, ctx, ctx_flags, 4, nullptr, nullptr, &entry_out, &unknown); + } if (NT_FAIL(pData->LastError)) { @@ -239,16 +349,86 @@ DWORD __declspec(code_seg(".inj_sec$1")) __stdcall InjectionShell(INJECTION_DATA pData->hRet = ReCa(entry_out->DllBase); } - else + else if (pData->OSVersion == g_Win81 && pData->Mode == INJECTION_MODE::IM_LdrpLoadDll) { - return INJ_ERR_INVALID_INJ_METHOD; - } + auto _LdrpLoadDll = ReCa(f->LdrpLoadDll); + + LDRP_PATH_SEARCH_CONTEXT_WIN81 ctx{ 0 }; + ctx.OriginalFullDllName = pData->ModuleFileName.szBuffer; + + LDRP_LOAD_CONTEXT_FLAGS ctx_flags{ 0 }; + + LDR_DATA_TABLE_ENTRY_WIN81 * entry_out = nullptr; + LDR_DDAG_NODE_WIN81 * ddag_out = nullptr; + + pData->LastError = (DWORD)_LdrpLoadDll(&pData->ModuleFileName, &ctx, ctx_flags, TRUE, &entry_out, &ddag_out); - if (dwRet != INJ_ERR_SUCCESS) + if (NT_FAIL(pData->LastError)) + { + return INJ_ERR_LDRPLDLL_FAILED; + } + + if (!entry_out) + { + return INJ_ERR_LDR_ENTRY_IS_NULL; + } + + pData->hRet = ReCa(entry_out->DllBase); + } + else if (pData->OSVersion == g_Win8 && pData->Mode == INJECTION_MODE::IM_LdrpLoadDll) { - return dwRet; + auto _LdrpLoadDll = ReCa(f->LdrpLoadDll); + + LDRP_PATH_SEARCH_CONTEXT_WIN8 ctx{ 0 }; + ctx.OriginalFullDllName = pData->ModuleFileName.szBuffer; + ctx.unknown2 = TRUE; + + LDRP_LOAD_CONTEXT_FLAGS ctx_flags{ 0 }; + + LDR_DATA_TABLE_ENTRY_WIN8 * entry_out = nullptr; + LDR_DDAG_NODE_WIN8 * ddag_out = nullptr; + + pData->LastError = (DWORD)_LdrpLoadDll(&pData->ModuleFileName, &ctx, ctx_flags, TRUE, &entry_out, &ddag_out); + + if (NT_FAIL(pData->LastError)) + { + return INJ_ERR_LDRPLDLL_FAILED; + } + + if (!entry_out) + { + return INJ_ERR_LDR_ENTRY_IS_NULL; + } + + pData->hRet = ReCa(entry_out->DllBase); } + else if (pData->OSVersion == g_Win7 && pData->Mode == INJECTION_MODE::IM_LdrpLoadDll) + { + auto _LdrpLoadDll = ReCa(f->LdrpLoadDll); + LDRP_LOAD_CONTEXT_FLAGS ctx_flags{ 0 }; + + LDR_DATA_TABLE_ENTRY_WIN7 * entry_out = nullptr; + + pData->LastError = (DWORD)_LdrpLoadDll(&pData->ModuleFileName, f->LdrpDefaultPath, ctx_flags, TRUE, nullptr, &entry_out); + + if (NT_FAIL(pData->LastError)) + { + return INJ_ERR_LDRPLDLL_FAILED; + } + + if (!entry_out) + { + return INJ_ERR_LDR_ENTRY_IS_NULL; + } + + pData->hRet = ReCa(entry_out->DllBase); + } + else + { + return INJ_ERR_INVALID_INJ_METHOD; + } + if (!(pData->Flags & (INJ_UNLINK_FROM_PEB | INJ_FAKE_HEADER | INJ_ERASE_HEADER))) { return INJ_ERR_SUCCESS; @@ -279,7 +459,7 @@ DWORD __declspec(code_seg(".inj_sec$1")) __stdcall InjectionShell(INJECTION_DATA auto * nt_headers = ReCa(ReCa(pData->hRet) + dos_header->e_lfanew); SIZE_T header_size = nt_headers->OptionalHeader.SizeOfHeaders; - HANDLE hProc = MPTR(-1); + HANDLE hProc = NtCurrentProcess(); ULONG old_access = NULL; void * base = ReCa(pData->hRet); @@ -336,26 +516,89 @@ DWORD __declspec(code_seg(".inj_sec$1")) __stdcall InjectionShell(INJECTION_DATA { return INJ_ERR_CANT_FIND_MOD_PEB; } + + auto * veh_shell_data = ReCa(ALIGN_UP(pData->pVEHShell + pData->VEHShellSize, BASE_ALIGNMENT)); + + veh_shell_data->ImgBase = ReCa(pEntry->DllBase); + veh_shell_data->ImgSize = pEntry->SizeOfImage; + veh_shell_data->OSVersion = pData->OSVersion; + veh_shell_data->_LdrpInvertedFunctionTable = f->LdrpInvertedFunctionTable; + veh_shell_data->_LdrProtectMrdata = f->LdrProtectMrdata; + + bool veh_shell_fixed = FindAndReplacePtr(pData->pVEHShell, pData->VEHShellSize, VEHDATASIG, ReCa(veh_shell_data)); + + if (veh_shell_fixed) + { + f->RtlAddVectoredExceptionHandler(0, ReCa(pData->pVEHShell)); + } + + UNLINK_IF(pEntry->InLoadOrderLinks); + UNLINK_IF(pEntry->InInitializationOrderLinks); + UNLINK_IF(pEntry->InMemoryOrderLinks); + UNLINK_IF(pEntry->HashLinks); - pEntry->InLoadOrderLinks.Flink->Blink = pEntry->InLoadOrderLinks.Blink; - pEntry->InLoadOrderLinks.Blink->Flink = pEntry->InLoadOrderLinks.Flink; - pEntry->InInitializationOrderLinks.Flink->Blink = pEntry->InInitializationOrderLinks.Blink; - pEntry->InInitializationOrderLinks.Blink->Flink = pEntry->InInitializationOrderLinks.Flink; - pEntry->InMemoryOrderLinks.Flink->Blink = pEntry->InMemoryOrderLinks.Blink; - pEntry->InMemoryOrderLinks.Blink->Flink = pEntry->InMemoryOrderLinks.Flink; - pEntry->HashLinks.Flink->Blink = pEntry->HashLinks.Blink; - pEntry->HashLinks.Blink->Flink = pEntry->HashLinks.Flink; + size_t ldr_size = sizeof(LDR_DATA_TABLE_ENTRY); + size_t ddag_size = sizeof(LDR_DDAG_NODE); + void * pDDag = nullptr; + + if (pData->OSVersion == g_Win7) + { + auto * pEntry7 = ReCa(pEntry); + UNLINK_IF(pEntry7->ForwarderLinks); + UNLINK_IF(pEntry7->ServiceTagLinks); + UNLINK_IF(pEntry7->StaticLinks); + + ldr_size = sizeof(LDR_DATA_TABLE_ENTRY_WIN7); + } + else + { + f->RtlRbRemoveNode(f->LdrpModuleBaseAddressIndex, &pEntry->BaseAddressIndexNode); + f->RtlRbRemoveNode(f->LdrpMappingInfoIndex, &pEntry->MappingInfoIndexNode); - f->RtlRbRemoveNode(f->LdrpModuleBaseAddressIndex, &pEntry->BaseAddressIndexNode); - f->RtlRbRemoveNode(f->LdrpMappingInfoIndex, &pEntry->MappingInfoIndexNode); + if (pData->OSVersion == g_Win8) + { + ldr_size = sizeof(LDR_DATA_TABLE_ENTRY_WIN8); + ddag_size = sizeof(LDR_DDAG_NODE_WIN8); + } + else if (pData->OSVersion == g_Win81) + { + ldr_size = sizeof(LDR_DATA_TABLE_ENTRY_WIN81); + ddag_size = sizeof(LDR_DDAG_NODE_WIN81); + } + else if (pData->OSVersion >= g_Win10) //Win10 or Win11, same OSVersion... + { + if (pData->OSBuildNumber <= g_Win10_1511) //1507 - 1511 + { + ldr_size = offsetof(LDR_DATA_TABLE_ENTRY_WIN10, DependentLoadFlags); + } + else if (pData->OSBuildNumber <= g_Win10_1607) //1607 + { + ldr_size = offsetof(LDR_DATA_TABLE_ENTRY_WIN10, SigningLevel); + } + else if (pData->OSBuildNumber <= g_Win10_21H1) //1703 - 21H1 + { + ldr_size = sizeof(LDR_DATA_TABLE_ENTRY_WIN10); + ddag_size = sizeof(LDR_DDAG_NODE_WIN10); + } + else //21H2+ (Win11) + { + ldr_size = sizeof(LDR_DATA_TABLE_ENTRY_WIN11); + ddag_size = sizeof(LDR_DDAG_NODE_WIN11); + } + } + + pDDag = pEntry->DdagNode; + } f->RtlZeroMemory(pEntry->BaseDllName.szBuffer, pEntry->BaseDllName.MaxLength); f->RtlZeroMemory(pEntry->FullDllName.szBuffer, pEntry->FullDllName.MaxLength); - LDR_DDAG_NODE * pDDagNode = pEntry->DdagNode; + f->RtlZeroMemory(pEntry, ldr_size); - f->RtlZeroMemory(pEntry, sizeof(LDR_DATA_TABLE_ENTRY)); - f->RtlZeroMemory(pDDagNode, sizeof(LDR_DDAG_NODE)); + if (pDDag) + { + f->RtlZeroMemory(pDDag, ddag_size); + } } return INJ_ERR_SUCCESS; @@ -384,6 +627,11 @@ INJECTION_FUNCTION_TABLE::INJECTION_FUNCTION_TABLE() NT_FUNC_CONSTRUCTOR_INIT(NtProtectVirtualMemory); + NT_FUNC_CONSTRUCTOR_INIT(RtlAddVectoredExceptionHandler); + NT_FUNC_CONSTRUCTOR_INIT(LdrProtectMrdata); + NT_FUNC_CONSTRUCTOR_INIT(LdrpInvertedFunctionTable); + NT_FUNC_CONSTRUCTOR_INIT(LdrpModuleBaseAddressIndex); NT_FUNC_CONSTRUCTOR_INIT(LdrpMappingInfoIndex); + NT_FUNC_CONSTRUCTOR_INIT(LdrpDefaultPath); } \ No newline at end of file diff --git a/GH Injector Library/Injection Internal.h b/GH Injector Library/Injection Internal.h index 9902f2f..97d54eb 100644 --- a/GH Injector Library/Injection Internal.h +++ b/GH Injector Library/Injection Internal.h @@ -1,6 +1,7 @@ #pragma once #include "Start Routine.h" +#include "Manual Mapping.h" ALIGN struct INJECTION_FUNCTION_TABLE { @@ -19,28 +20,38 @@ ALIGN struct INJECTION_FUNCTION_TABLE ALIGN NT_FUNC_LOCAL(RtlRbRemoveNode); ALIGN NT_FUNC_LOCAL(NtProtectVirtualMemory); + + ALIGN NT_FUNC_LOCAL(RtlAddVectoredExceptionHandler); + ALIGN NT_FUNC_LOCAL(LdrProtectMrdata); + ALIGN NT_FUNC_LOCAL(LdrpInvertedFunctionTable); ALIGN NT_FUNC_LOCAL(LdrpModuleBaseAddressIndex); ALIGN NT_FUNC_LOCAL(LdrpMappingInfoIndex); + ALIGN NT_FUNC_LOCAL(LdrpDefaultPath); INJECTION_FUNCTION_TABLE(); }; -ALIGN struct INJECTION_DATA_INTERNAL +struct INJECTION_DATA_INTERNAL { - ALIGN HINSTANCE hRet; - ALIGN DWORD LastError; - - ALIGN DWORD Flags; - ALIGN INJECTION_MODE Mode; + ALIGN HINSTANCE hRet = nullptr; + ALIGN DWORD LastError = 0; - ALIGN UNICODE_STRING ModuleFileName; - ALIGN wchar_t Path[MAX_PATH]; + ALIGN DWORD Flags = NULL; + ALIGN INJECTION_MODE Mode = INJECTION_MODE::IM_LoadLibraryExW; - ALIGN LDRP_UNICODE_STRING_BUNDLE ModuleFileNameBundle; + ALIGN UNICODE_STRING ModuleFileName{ 0 }; + ALIGN wchar_t Path[MAX_PATH]{ 0 }; - ALIGN LDRP_PATH_SEARCH_CONTEXT SearchPathContext; + ALIGN LDRP_UNICODE_STRING_BUNDLE ModuleFileNameBundle{ 0 }; + ALIGN LDRP_PATH_SEARCH_CONTEXT SearchPathContext{ 0 }; + ALIGN DWORD OSVersion = 0; + ALIGN DWORD OSBuildNumber = 0; + + ALIGN BYTE * pVEHShell = nullptr; + ALIGN DWORD VEHShellSize = 0; + ALIGN INJECTION_FUNCTION_TABLE f; }; @@ -66,26 +77,36 @@ ALIGN_86 struct INJECTION_FUNCTION_TABLE_WOW64 ALIGN_86 WOW64_FUNCTION_POINTER_LOCAL(NtProtectVirtualMemory); + ALIGN_86 WOW64_FUNCTION_POINTER_LOCAL(RtlAddVectoredExceptionHandler); + ALIGN_86 WOW64_FUNCTION_POINTER_LOCAL(LdrProtectMrdata); + ALIGN_86 WOW64_FUNCTION_POINTER_LOCAL(LdrpInvertedFunctionTable); + ALIGN_86 WOW64_FUNCTION_POINTER_LOCAL(LdrpModuleBaseAddressIndex); ALIGN_86 WOW64_FUNCTION_POINTER_LOCAL(LdrpMappingInfoIndex); + ALIGN_86 WOW64_FUNCTION_POINTER_LOCAL(LdrpDefaultPath); INJECTION_FUNCTION_TABLE_WOW64(); }; ALIGN_86 struct INJECTION_DATA_INTERNAL_WOW64 { - ALIGN_86 DWORD hRet; - ALIGN_86 DWORD LastError; + ALIGN_86 DWORD hRet = 0; + ALIGN_86 DWORD LastError = 0; + + ALIGN_86 DWORD Flags = NULL; + ALIGN_86 INJECTION_MODE Mode = INJECTION_MODE::IM_LoadLibraryExW; - ALIGN_86 DWORD Flags; - ALIGN_86 INJECTION_MODE Mode; + ALIGN_86 UNICODE_STRING_32 ModuleFileName{ 0 }; + ALIGN_86 wchar_t Path[MAX_PATH]{ 0 }; - ALIGN_86 UNICODE_STRING32 ModuleFileName; - ALIGN_86 wchar_t Path[MAX_PATH]; + ALIGN_86 LDRP_UNICODE_STRING_BUNDLE_32 ModuleFileNameBundle{ 0 }; + ALIGN_86 LDRP_PATH_SEARCH_CONTEXT_32 SearchPathContext{ 0 }; - ALIGN_86 LDRP_UNICODE_STRING_BUNDLE32 ModuleFileNameBundle; + ALIGN_86 DWORD OSVersion = 0; + ALIGN_86 DWORD OSBuildNumber = 0; - ALIGN_86 LDRP_PATH_SEARCH_CONTEXT32 SearchPathContext; + ALIGN_86 DWORD pVEHShell = 0; + ALIGN_86 DWORD VEHShellSize = 0; ALIGN_86 INJECTION_FUNCTION_TABLE_WOW64 f; }; diff --git a/GH Injector Library/Injection.cpp b/GH Injector Library/Injection.cpp index cfda75d..8117fc1 100644 --- a/GH Injector Library/Injection.cpp +++ b/GH Injector Library/Injection.cpp @@ -139,6 +139,15 @@ DWORD __stdcall InjectW(INJECTIONDATAW * pData) return RetVal; } + + if (pData->Mode == INJECTION_MODE::IM_LdrpLoadDllInternal && !IsWin10OrGreater()) + { + INIT_ERROR_DATA(error_data, INJ_ERR_ADVANCED_NOT_DEFINED); + + LOG(" LdrpLoadDllInternal is only supported on Windows 10\n"); + + return InitErrorStruct(nullptr, pData, -1, INJ_ERR_NOT_SUPPORTED, error_data); + } if (!pData->szDllPath) { diff --git a/GH Injector Library/KernelCallback WOW64.cpp b/GH Injector Library/KernelCallback WOW64.cpp index 6cf5dc9..a597e58 100644 --- a/GH Injector Library/KernelCallback WOW64.cpp +++ b/GH Injector Library/KernelCallback WOW64.cpp @@ -53,8 +53,8 @@ DWORD SR_KernelCallback_WOW64(HANDLE hTargetProc, f_Routine_WOW64 pRoutine, DWOR return SR_KC_ERR_CANT_GET_PEB; } - PEB32 peb; - if (!ReadProcessMemory(hTargetProc, pPEB, &peb, sizeof(PEB32), nullptr)) + PEB_32 peb; + if (!ReadProcessMemory(hTargetProc, pPEB, &peb, sizeof(PEB_32), nullptr)) { INIT_ERROR_DATA(error_data, GetLastError()); diff --git a/GH Injector Library/Manual Mapping WOW64.cpp b/GH Injector Library/Manual Mapping WOW64.cpp index 10ec96d..8627b41 100644 --- a/GH Injector Library/Manual Mapping WOW64.cpp +++ b/GH Injector Library/Manual Mapping WOW64.cpp @@ -13,7 +13,9 @@ DWORD MMAP_WOW64::ManualMap_WOW64(const wchar_t * szDllFile, HANDLE hTargetProc, LOG(" Begin ManualMap_WOW64\n"); MANUAL_MAPPING_DATA_WOW64 data{ 0 }; - data.Flags = Flags; + data.Flags = Flags; + data.OSVersion = GetOSVersion(); + data.OSBuildNumber = GetOSBuildVersion(); size_t len = 0; HRESULT hr = StringCbLengthW(szDllFile, sizeof(data.szPathBuffer), &len); @@ -92,12 +94,26 @@ DWORD MMAP_WOW64::ManualMap_WOW64(const wchar_t * szDllFile, HANDLE hTargetProc, LOG(" Shift offset = %04X\n", shift_offset); } - ULONG_PTR ShellSize = sizeof(ManualMapping_Shell_WOW64); - auto AllocationSize = sizeof(MANUAL_MAPPING_DATA_WOW64) + ShellSize + BASE_ALIGNMENT; + ULONG_PTR ShellSize = sizeof(ManualMapping_Shell_WOW64); + ULONG_PTR VEHShellSize = sizeof(VectoredHandlerShell_WOW64); + + if ((Flags & INJ_MM_ENABLE_EXCEPTIONS) == 0) + { + VEHShellSize = 0; + } + + auto AllocationSize = sizeof(MANUAL_MAPPING_DATA_WOW64) + ShellSize + VEHShellSize + BASE_ALIGNMENT * 2; BYTE * pAllocBase = ReCa(VirtualAllocEx(hTargetProc, nullptr, AllocationSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE)); - BYTE * pArg = pAllocBase; - BYTE * pShell = ReCa(ALIGN_UP(ReCa(pArg) + sizeof(MANUAL_MAPPING_DATA_WOW64), 0x10)); + BYTE * pArg = pAllocBase; + BYTE * pShell = ReCa(ALIGN_UP(ReCa(pArg) + sizeof(MANUAL_MAPPING_DATA_WOW64), BASE_ALIGNMENT)); + BYTE * pVEHShell = ReCa(ALIGN_UP(ReCa(pShell) + ShellSize, BASE_ALIGNMENT)); + + if (VEHShellSize) + { + data.pVEHShell = MDWD(pVEHShell); + data.VEHShellSize = MDWD(VEHShellSize); + } if (!pArg) { @@ -110,6 +126,11 @@ DWORD MMAP_WOW64::ManualMap_WOW64(const wchar_t * szDllFile, HANDLE hTargetProc, LOG(" Shellsize = %IX\n Total size = %08X\n pArg = %p\n pShell = %p\n", ShellSize, (DWORD)AllocationSize, pArg, pShell); + if (VEHShellSize) + { + LOG(" pVEHShell = %p\n", pVEHShell); + } + if (!WriteProcessMemory(hTargetProc, pArg, &data, sizeof(MANUAL_MAPPING_DATA_WOW64), nullptr)) { INIT_ERROR_DATA(error_data, GetLastError()); @@ -121,6 +142,8 @@ DWORD MMAP_WOW64::ManualMap_WOW64(const wchar_t * szDllFile, HANDLE hTargetProc, return INJ_ERR_WPM_FAIL; } + LOG(" Shelldata written to memory\n"); + if (!WriteProcessMemory(hTargetProc, pShell, ManualMapping_Shell_WOW64, ShellSize, nullptr)) { INIT_ERROR_DATA(error_data, GetLastError()); @@ -134,6 +157,22 @@ DWORD MMAP_WOW64::ManualMap_WOW64(const wchar_t * szDllFile, HANDLE hTargetProc, LOG(" Shell written to memory\n"); + if (VEHShellSize) + { + if (!WriteProcessMemory(hTargetProc, pVEHShell, VectoredHandlerShell_WOW64, VEHShellSize, nullptr)) + { + INIT_ERROR_DATA(error_data, GetLastError()); + + LOG(" WriteProcessMemory failed: %08X\n", error_data.AdvErrorCode); + + VirtualFreeEx(hTargetProc, pAllocBase, 0, MEM_RELEASE); + + return INJ_ERR_WPM_FAIL; + } + + LOG(" VEHShell written to memory\n"); + } + LOG(" Entering StartRoutine_WOW64\n"); DWORD remote_ret = 0; @@ -214,15 +253,20 @@ MANUAL_MAPPING_FUNCTION_TABLE_WOW64::MANUAL_MAPPING_FUNCTION_TABLE_WOW64() WOW64_FUNC_CONSTRUCTOR_INIT(NtProtectVirtualMemory); WOW64_FUNC_CONSTRUCTOR_INIT(NtFreeVirtualMemory); + WOW64_FUNC_CONSTRUCTOR_INIT(NtCreateSection); + WOW64_FUNC_CONSTRUCTOR_INIT(NtMapViewOfSection); + WOW64_FUNC_CONSTRUCTOR_INIT(memmove); WOW64_FUNC_CONSTRUCTOR_INIT(RtlZeroMemory); WOW64_FUNC_CONSTRUCTOR_INIT(RtlAllocateHeap); WOW64_FUNC_CONSTRUCTOR_INIT(RtlFreeHeap); - WOW64_FUNC_CONSTRUCTOR_INIT(LdrGetDllHandleEx); + WOW64_FUNC_CONSTRUCTOR_INIT(LdrpLoadDll); WOW64_FUNC_CONSTRUCTOR_INIT(LdrpLoadDllInternal); WOW64_FUNC_CONSTRUCTOR_INIT(LdrGetProcedureAddress); + WOW64_FUNC_CONSTRUCTOR_INIT(LdrUnloadDll); + WOW64_FUNC_CONSTRUCTOR_INIT(RtlAnsiStringToUnicodeString); WOW64_FUNC_CONSTRUCTOR_INIT(LdrpPreprocessDllName); @@ -232,10 +276,18 @@ MANUAL_MAPPING_FUNCTION_TABLE_WOW64::MANUAL_MAPPING_FUNCTION_TABLE_WOW64() WOW64_FUNC_CONSTRUCTOR_INIT(LdrLockLoaderLock); WOW64_FUNC_CONSTRUCTOR_INIT(LdrUnlockLoaderLock); + WOW64_FUNC_CONSTRUCTOR_INIT(LdrProtectMrdata); + + WOW64_FUNC_CONSTRUCTOR_INIT(RtlAddVectoredExceptionHandler); + WOW64_FUNC_CONSTRUCTOR_INIT(RtlRemoveVectoredExceptionHandler); + WOW64_FUNC_CONSTRUCTOR_INIT(LdrpModuleBaseAddressIndex); WOW64_FUNC_CONSTRUCTOR_INIT(LdrpMappingInfoIndex); WOW64_FUNC_CONSTRUCTOR_INIT(LdrpHeap); - WOW64_FUNC_CONSTRUCTOR_INIT(LdrpInvertedFunctionTable); + WOW64_FUNC_CONSTRUCTOR_INIT(LdrpInvertedFunctionTable); + WOW64_FUNC_CONSTRUCTOR_INIT(LdrpDefaultPath); + + pLdrpHeap = 0; } #endif \ No newline at end of file diff --git a/GH Injector Library/Manual Mapping.cpp b/GH Injector Library/Manual Mapping.cpp index c5328bc..6d4e6c7 100644 --- a/GH Injector Library/Manual Mapping.cpp +++ b/GH Injector Library/Manual Mapping.cpp @@ -1,6 +1,7 @@ #include "pch.h" #include "Manual Mapping.h" + using namespace NATIVE; using namespace MMAP_NATIVE; @@ -12,12 +13,17 @@ DWORD MMAP_NATIVE::ManualMap(const wchar_t * szDllFile, HANDLE hTargetProc, LAUN #if !defined(_WIN64) && defined (DUMP_SHELLCODE) auto length = ReCa(ManualMapping_Shell_End) - ReCa(ManualMapping_Shell); DumpShellcode(ReCa(ManualMapping_Shell), length, L"ManualMapping_Shell_WOW64"); + + length = ReCa(VectoredHandlerShell_End) - ReCa(VectoredHandlerShell); + DumpShellcode(ReCa(VectoredHandlerShell), length, L"VectoredHandlerShell_WOW64"); #endif LOG(" Begin ManualMap\n"); MANUAL_MAPPING_DATA data{ 0 }; - data.Flags = Flags; + data.Flags = Flags; + data.OSVersion = GetOSVersion(); + data.OSBuildNumber = GetOSBuildVersion(); size_t len = 0; HRESULT hr = StringCbLengthW(szDllFile, sizeof(data.szPathBuffer), &len); @@ -98,12 +104,26 @@ DWORD MMAP_NATIVE::ManualMap(const wchar_t * szDllFile, HANDLE hTargetProc, LAUN LOG(" Shift offset = %04X\n", shift_offset); } - ULONG_PTR ShellSize = (ULONG_PTR)ManualMapping_Shell_End - (ULONG_PTR)ManualMapping_Shell; - auto AllocationSize = sizeof(MANUAL_MAPPING_DATA) + ShellSize + BASE_ALIGNMENT; + ULONG_PTR ShellSize = ReCa(ManualMapping_Shell_End) - ReCa(ManualMapping_Shell); + ULONG_PTR VEHShellSize = ReCa(VectoredHandlerShell_End) - ReCa(VectoredHandlerShell); + + if (!(Flags & INJ_MM_ENABLE_EXCEPTIONS)) + { + VEHShellSize = 0; + } + + auto AllocationSize = sizeof(MANUAL_MAPPING_DATA) + ShellSize + VEHShellSize + BASE_ALIGNMENT * 2; BYTE * pAllocBase = ReCa(VirtualAllocEx(hTargetProc, nullptr, AllocationSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE)); - BYTE * pArg = pAllocBase; - BYTE * pShell = ReCa(ALIGN_UP(ReCa(pArg) + sizeof(MANUAL_MAPPING_DATA), BASE_ALIGNMENT)); + BYTE * pArg = pAllocBase; + BYTE * pShell = ReCa(ALIGN_UP(ReCa(pArg) + sizeof(MANUAL_MAPPING_DATA), BASE_ALIGNMENT)); + BYTE * pVEHShell = ReCa(ALIGN_UP(ReCa(pShell) + ShellSize, BASE_ALIGNMENT)); + + if (VEHShellSize) + { + data.pVEHShell = pVEHShell; + data.VEHShellSize = MDWD(VEHShellSize); + } if (!pArg) { @@ -116,6 +136,11 @@ DWORD MMAP_NATIVE::ManualMap(const wchar_t * szDllFile, HANDLE hTargetProc, LAUN LOG(" Shellsize = %IX\n Total size = %08X\n pArg = %p\n pShell = %p\n", ShellSize, (DWORD)AllocationSize, pArg, pShell); + if (VEHShellSize) + { + LOG(" pVEHShell = %p\n", pVEHShell); + } + if (!WriteProcessMemory(hTargetProc, pArg, &data, sizeof(MANUAL_MAPPING_DATA), nullptr)) { INIT_ERROR_DATA(error_data, GetLastError()); @@ -142,6 +167,22 @@ DWORD MMAP_NATIVE::ManualMap(const wchar_t * szDllFile, HANDLE hTargetProc, LAUN LOG(" Shell written to memory\n"); + if (VEHShellSize) + { + if (!WriteProcessMemory(hTargetProc, pVEHShell, VectoredHandlerShell, VEHShellSize, nullptr)) + { + INIT_ERROR_DATA(error_data, GetLastError()); + + LOG(" WriteProcessMemory failed: %08X\n", error_data.AdvErrorCode); + + VirtualFreeEx(hTargetProc, pAllocBase, 0, MEM_RELEASE); + + return INJ_ERR_WPM_FAIL; + } + + LOG(" VEHShell written to memory\n"); + } + LOG(" Entering StartRoutine\n"); DWORD remote_ret = 0; @@ -209,6 +250,11 @@ DWORD MMAP_NATIVE::ManualMap(const wchar_t * szDllFile, HANDLE hTargetProc, LAUN return INJ_ERR_SUCCESS; } +__forceinline UINT_PTR bit_rotate_r(UINT_PTR val, int count) +{ + return (val >> count) | (val << (-count)); +} + template __forceinline T * NewObject(MANUAL_MAPPING_FUNCTION_TABLE * f, size_t Count = 1) { @@ -262,6 +308,268 @@ __forceinline bool InitAnsiString(MANUAL_MAPPING_FUNCTION_TABLE * f, ANSI_STRING return true; } +__forceinline void BuildDependencyRecord(MANUAL_MAPPING_FUNCTION_TABLE * f, MM_DEPENDENCY_RECORD ** head, HANDLE DllHandle) +{ + if (!head) + { + return; + } + + //create new list (head) + if (!(*head)) + { + *head = NewObject(f); + + if (!(*head)) + { + return; + } + + (*head)->Next = *head; + (*head)->Prev = *head; + (*head)->DllHandle = DllHandle; + + return; + } + + //create new entry + auto next = NewObject(f); + if (next) + { + (*head)->Prev->Next = next; + next->Prev = (*head)->Prev; + + (*head)->Prev = next; + next->Next = (*head); + + next->DllHandle = DllHandle; + } +} + +__forceinline NTSTATUS LoadModule(MANUAL_MAPPING_DATA * pData, MANUAL_MAPPING_FUNCTION_TABLE * f, char * szModule, HINSTANCE * hModule, MM_DEPENDENCY_RECORD ** head) +{ + //load module using LdrpLoadDll(Internal) + //function protoype is heavily platform dependent + + LDR_DATA_TABLE_ENTRY * entry_out = nullptr; + NTSTATUS ntRet = STATUS_SUCCESS; + + //create ANSI_STRING + auto * ModNameA = NewObject(f); + if (!ModNameA) + { + ntRet = INJ_MM_ERR_HEAP_ALLOC; + + return ntRet; + } + + //move szModule into ANSI_STRING + if (!InitAnsiString(f, ModNameA, szModule)) + { + ntRet = STATUS_HEAP_CORRUPTION; + + DeleteObject(f, ModNameA); + + return ntRet; + } + + //create UNICODE_STRING + auto * ModNameW = NewObject(f); + if (!ModNameW) + { + ntRet = INJ_MM_ERR_HEAP_ALLOC; + + DeleteObject(f, ModNameA->szBuffer); + DeleteObject(f, ModNameA); + + return ntRet; + } + + //allocate buffer for UNICODE_STRING + ModNameW->szBuffer = NewObject(f, MAX_PATH); + ModNameW->MaxLength = sizeof(wchar_t[MAX_PATH]); + + if (!ModNameW->szBuffer) + { + ntRet = INJ_MM_ERR_HEAP_ALLOC; + + DeleteObject(f, ModNameW); + + DeleteObject(f, ModNameA->szBuffer); + DeleteObject(f, ModNameA); + + return ntRet; + } + + //convert dll name from ansi to unicode + ntRet = f->RtlAnsiStringToUnicodeString(ModNameW, ModNameA, FALSE); + if (NT_FAIL(ntRet)) + { + DeleteObject(f, ModNameW->szBuffer); + DeleteObject(f, ModNameW); + + DeleteObject(f, ModNameA->szBuffer); + DeleteObject(f, ModNameA); + + return ntRet; + } + + DeleteObject(f, ModNameA->szBuffer); + DeleteObject(f, ModNameA); + + if (pData->OSVersion >= g_Win10) + { + LDRP_UNICODE_STRING_BUNDLE * pModPathW = NewObject(f); + if (!pModPathW) + { + DeleteObject(f, ModNameW->szBuffer); + DeleteObject(f, ModNameW); + + return STATUS_NO_MEMORY; + } + + pModPathW->String.MaxLength = sizeof(pModPathW->StaticBuffer); + pModPathW->String.szBuffer = pModPathW->StaticBuffer; + + LDRP_LOAD_CONTEXT_FLAGS ctx_flags{ 0 }; + ntRet = f->LdrpPreprocessDllName(ModNameW, pModPathW, nullptr, &ctx_flags); + + if (NT_FAIL(ntRet)) + { + DeleteObject(f, pModPathW); + DeleteObject(f, ModNameW->szBuffer); + DeleteObject(f, ModNameW); + + return ntRet; + } + + auto * ctx = NewObject(f); + if (!ctx) + { + DeleteObject(f, pModPathW); + DeleteObject(f, ModNameW->szBuffer); + DeleteObject(f, ModNameW); + + return STATUS_NO_MEMORY; + } + + if (pData->OSBuildNumber <= g_Win10_1511) + { + ReCa(ctx)->OriginalFullDllName = ModNameW->szBuffer; + } + else + { + ctx->OriginalFullDllName = ModNameW->szBuffer; + } + + ULONG_PTR unknown3 = 0; + + if (pData->OSBuildNumber > g_Win10_21H1) + { + auto _LdrpLoadDllInternal = ReCa(f->LdrpLoadDllInternal); + ntRet = _LdrpLoadDllInternal(&pModPathW->String, ctx, ctx_flags, 4, nullptr, nullptr, ReCa(&entry_out), &unknown3, 0); + } + else + { + ntRet = f->LdrpLoadDllInternal(&pModPathW->String, ctx, ctx_flags, 4, nullptr, nullptr, ReCa(&entry_out), &unknown3); + } + + DeleteObject(f, ctx); + DeleteObject(f, pModPathW); + } + else if (pData->OSVersion == g_Win81) + { + auto * ctx = NewObject(f); + if (ctx) + { + ctx->OriginalFullDllName = ModNameW->szBuffer; + + LDRP_LOAD_CONTEXT_FLAGS ctx_flags{ 0 }; + LDR_DDAG_NODE_WIN81 * ddag_out = nullptr; + + auto _LdrpLoadDll = ReCa(f->LdrpLoadDll); + ntRet = _LdrpLoadDll(ModNameW, ctx, ctx_flags, TRUE, ReCa(&entry_out), &ddag_out); + + DeleteObject(f, ctx); + } + else + { + ntRet = STATUS_NO_MEMORY; + } + } + else if (pData->OSVersion == g_Win8) + { + auto * ctx = NewObject(f); + if (ctx) + { + ctx->OriginalFullDllName = ModNameW->szBuffer; + ctx->unknown2 = TRUE; + + LDRP_LOAD_CONTEXT_FLAGS ctx_flags{ 0 }; + LDR_DDAG_NODE_WIN8 * ddag_out = nullptr; + + auto _LdrpLoadDll = ReCa(f->LdrpLoadDll); + ntRet = _LdrpLoadDll(ModNameW, ctx, ctx_flags, TRUE, ReCa(&entry_out), &ddag_out); + + DeleteObject(f, ctx); + } + else + { + ntRet = STATUS_NO_MEMORY; + } + } + else if (pData->OSVersion == g_Win7) + { + LDRP_LOAD_CONTEXT_FLAGS ctx_flags{ 0 }; + + auto _LdrpLoadDll = ReCa(f->LdrpLoadDll); + ntRet = _LdrpLoadDll(ModNameW, f->LdrpDefaultPath, ctx_flags, TRUE, nullptr, ReCa(&entry_out)); + } + else + { + ntRet = STATUS_NOT_IMPLEMENTED; + } + + DeleteObject(f, ModNameW->szBuffer); + DeleteObject(f, ModNameW); + + if (NT_SUCCESS(ntRet)) + { + if (entry_out) + { + *hModule = ReCa(entry_out->DllBase); + + BuildDependencyRecord(f, head, ReCa(*hModule)); + } + else + { + ntRet = STATUS_DLL_NOT_FOUND; + } + } + + return ntRet; +} + +__forceinline void UnloadAndDeleteDependencyRecord(MANUAL_MAPPING_FUNCTION_TABLE * f, MM_DEPENDENCY_RECORD * head) +{ + if (!head) + { + return; + } + + //unload in reverse order, won't unload everything because dependency loading is fucked since Win 1.0 + auto cur = head->Prev; + auto last = cur; + do + { + f->LdrUnloadDll(cur->DllHandle); + + cur = cur->Prev; + DeleteObject(f, cur->Next); + } + while (cur != last); +} + DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_MAPPING_DATA * pData) { if (!pData) @@ -271,16 +579,23 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M BYTE * pAllocBase = nullptr; BYTE * pBase = nullptr; + BYTE * pVEHShell = nullptr; DWORD Flags = pData->Flags; NTSTATUS ntRet = STATUS_SUCCESS; - HANDLE hProc = MPTR(-1); + HANDLE hProc = NtCurrentProcess(); + //pe headers IMAGE_DOS_HEADER * pDosHeader = nullptr; IMAGE_NT_HEADERS * pNtHeaders = nullptr; IMAGE_OPTIONAL_HEADER * pOptionalHeader = nullptr; IMAGE_FILE_HEADER * pFileHeader = nullptr; + //simple dependency record for unloading + MM_DEPENDENCY_RECORD * imports = nullptr; + MM_DEPENDENCY_RECORD * delay_imports = nullptr; + + //grab LdrpHeap pointer auto * f = &pData->f; f->pLdrpHeap = *f->LdrpHeap; @@ -291,9 +606,9 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M //convert path to nt path UNICODE_STRING DllNtPath{ 0 }; - DllNtPath.Length = pData->DllPath.Length; + DllNtPath.Length = pData->DllPath.Length; DllNtPath.MaxLength = sizeof(wchar_t[MAX_PATH + 4]); - DllNtPath.szBuffer = NewObject(f, DllNtPath.MaxLength / sizeof(wchar_t)); + DllNtPath.szBuffer = NewObject(f, DllNtPath.MaxLength / sizeof(wchar_t)); if (!DllNtPath.szBuffer) { @@ -305,6 +620,7 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M f->memmove(DllNtPath.szBuffer + 4, pData->szPathBuffer, DllNtPath.Length); DllNtPath.Length += sizeof(wchar_t[4]); + //update string buffer addresses UNICODE_STRING DllName = pData->DllName; DllName.szBuffer = pData->szNameBuffer; @@ -332,6 +648,7 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M HANDLE hDllFile = nullptr; + //open dll file ntRet = f->NtOpenFile(&hDllFile, FILE_GENERIC_READ, oa, io_status, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT); DeleteObject(f, oa); @@ -346,32 +663,6 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M return INJ_MM_ERR_NT_OPEN_FILE; } - BYTE * Headers = NewObject(f, 0x1000); - if (!Headers) - { - f->NtClose(hDllFile); - - return INJ_MM_ERR_HEAP_ALLOC; - } - - ntRet = f->NtReadFile(hDllFile, nullptr, nullptr, nullptr, io_status, Headers, 0x1000, nullptr, nullptr); - if (NT_FAIL(ntRet)) - { - pData->ntRet = ntRet; - - DeleteObject(f, Headers); - DeleteObject(f, io_status); - - f->NtClose(hDllFile); - - return INJ_MM_ERR_NT_READ_FILE; - } - - pDosHeader = ReCa(Headers); - pNtHeaders = ReCa(Headers + pDosHeader->e_lfanew); - - DeleteObject(f, Headers); - auto * fsi = NewObject(f); if (!fsi) { @@ -382,6 +673,7 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M return INJ_MM_ERR_HEAP_ALLOC; } + //query basic file information ntRet = f->NtQueryInformationFile(hDllFile, io_status, fsi, sizeof(FILE_STANDARD_INFO), FILE_INFORMATION_CLASS::FileStandardInformation); if (NT_FAIL(ntRet)) { @@ -398,6 +690,7 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M BYTE * pRawData = nullptr; SIZE_T RawSize = fsi->AllocationSize.LowPart; + //allocate memory for the raw dll file ntRet = f->NtAllocateVirtualMemory(hProc, ReCa(&pRawData), 0, &RawSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); if (NT_FAIL(ntRet)) { @@ -424,6 +717,7 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M return INJ_MM_ERR_HEAP_ALLOC; } + //reset file pointer ntRet = f->NtSetInformationFile(hDllFile, io_status, pos, sizeof(FILE_POSITION_INFORMATION), FILE_INFORMATION_CLASS::FilePositionInformation); if (NT_FAIL(ntRet)) { @@ -441,6 +735,7 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M DeleteObject(f, pos); + //read raw dll file into memory ntRet = f->NtReadFile(hDllFile, nullptr, nullptr, nullptr, io_status, pRawData, fsi->AllocationSize.LowPart, nullptr, nullptr); if (NT_FAIL(ntRet)) { @@ -459,17 +754,26 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M DeleteObject(f, fsi); DeleteObject(f, io_status); - pDosHeader = ReCa(pRawData); - pNtHeaders = ReCa(pRawData + pDosHeader->e_lfanew); - pOptionalHeader = &pNtHeaders->OptionalHeader; + //grab pe header pointers (assuming the file is a valid dll) + pDosHeader = ReCa(pRawData); + pNtHeaders = ReCa(pRawData + pDosHeader->e_lfanew); + pOptionalHeader = &pNtHeaders->OptionalHeader; pFileHeader = &pNtHeaders->FileHeader; - SIZE_T ImgSize = (SIZE_T)pOptionalHeader->SizeOfImage; + SIZE_T ImgSize = static_cast(pOptionalHeader->SizeOfImage); + + //update allocation size depending on flags if (Flags & INJ_MM_SHIFT_MODULE_BASE && !(Flags & INJ_MM_SET_PAGE_PROTECTIONS)) { ImgSize += pData->ShiftOffset; } + if (Flags & INJ_MM_ENABLE_EXCEPTIONS) + { + ImgSize += 0x1000; + } + + //allocate memory for the dll ntRet = f->NtAllocateVirtualMemory(hProc, ReCa(&pAllocBase), 0, &ImgSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); if (NT_FAIL(ntRet)) { @@ -482,6 +786,7 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M return INJ_MM_ERR_MEMORY_ALLOCATION_FAILED; } + //update pointers depending on flags if (Flags & INJ_MM_SHIFT_MODULE_BASE && !(Flags & INJ_MM_SET_PAGE_PROTECTIONS)) { pBase = pAllocBase + pData->ShiftOffset; @@ -491,6 +796,32 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M pBase = pAllocBase; } + bool veh_shell_fixed = false; + + if (Flags & INJ_MM_ENABLE_EXCEPTIONS) + { + pVEHShell = pBase + pOptionalHeader->SizeOfImage; + + auto * veh_shell_data = NewObject(f); + + if (veh_shell_data) + { + veh_shell_data->ImgBase = ReCa(pBase); + veh_shell_data->ImgSize = pOptionalHeader->SizeOfImage; + veh_shell_data->OSVersion = pData->OSVersion; + veh_shell_data->_LdrpInvertedFunctionTable = f->LdrpInvertedFunctionTable; + veh_shell_data->_LdrProtectMrdata = f->LdrProtectMrdata; + + veh_shell_fixed = FindAndReplacePtr(pData->pVEHShell, pData->VEHShellSize, VEHDATASIG, ReCa(veh_shell_data)); + } + + if (veh_shell_fixed) + { + //copy VEH shellcode into target location + f->memmove(pVEHShell, pData->pVEHShell, pData->VEHShellSize); + } + } + //copy header and sections f->memmove(pBase, pRawData, pOptionalHeader->SizeOfHeaders); auto * pCurrentSectionHeader = IMAGE_FIRST_SECTION(pNtHeaders); @@ -502,6 +833,7 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M } } + //update pe headers to the new location pDosHeader = ReCa(pBase); pNtHeaders = ReCa(pBase + pDosHeader->e_lfanew); pOptionalHeader = &pNtHeaders->OptionalHeader; @@ -510,10 +842,9 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M RawSize = 0; f->NtFreeVirtualMemory(hProc, ReCa(&pRawData), &RawSize, MEM_RELEASE); - //relocate image - BYTE * LocationDelta = pBase - pOptionalHeader->ImageBase; + //relocate the image if necessary if (LocationDelta) { auto * pRelocDir = ReCa(&pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]); @@ -554,6 +885,7 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M pOptionalHeader->ImageBase += ReCa(LocationDelta); } + //initialize security cookie if (Flags & INJ_MM_INIT_SECURITY_COOKIE && pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].Size) { #ifdef _WIN64 @@ -581,11 +913,11 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M pLoadConfigData->SecurityCookie = new_cookie; } - //tba: track imports for unloading in case something goes wrong + //resolve imports if (Flags & (INJ_MM_RESOLVE_IMPORTS | INJ_MM_RUN_DLL_MAIN)) { - IMAGE_DATA_DIRECTORY * pImportDir = ReCa(&pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]); - IMAGE_IMPORT_DESCRIPTOR * pImportDescr = nullptr; + IMAGE_DATA_DIRECTORY * pImportDir = ReCa(&pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]); + IMAGE_IMPORT_DESCRIPTOR * pImportDescr = nullptr; if (pImportDir->Size) { @@ -596,139 +928,23 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M while (pImportDescr && pImportDescr->Name) { + //grab import name char * szMod = ReCa(pBase + pImportDescr->Name); - - auto * ModNameA = NewObject(f); - if (!ModNameA) - { - ntRet = INJ_MM_ERR_HEAP_ALLOC; - - ErrorBreak = true; - break; - } - - if (!InitAnsiString(f, ModNameA, szMod)) - { - ntRet = STATUS_HEAP_CORRUPTION; - - DeleteObject(f, ModNameA); - - ErrorBreak = true; - break; - } - - auto * ModNameW = NewObject(f); - if (!ModNameW) - { - ntRet = INJ_MM_ERR_HEAP_ALLOC; - - DeleteObject(f, ModNameA->szBuffer); - DeleteObject(f, ModNameA); - - ErrorBreak = true; - break; - } - - ModNameW->szBuffer = NewObject(f, MAX_PATH); - ModNameW->MaxLength = sizeof(wchar_t[MAX_PATH]); - - if (!ModNameW->szBuffer) - { - ntRet = INJ_MM_ERR_HEAP_ALLOC; - - DeleteObject(f, ModNameW); - - DeleteObject(f, ModNameA->szBuffer); - DeleteObject(f, ModNameA); - - ErrorBreak = true; - break; - } - - ntRet = f->RtlAnsiStringToUnicodeString(ModNameW, ModNameA, FALSE); - if (NT_FAIL(ntRet)) - { - DeleteObject(f, ModNameW->szBuffer); - DeleteObject(f, ModNameW); - - DeleteObject(f, ModNameA->szBuffer); - DeleteObject(f, ModNameA); - - ErrorBreak = true; - break; - } - - LDRP_UNICODE_STRING_BUNDLE * pModPathW = NewObject(f); - if (!pModPathW) - { - DeleteObject(f, ModNameW->szBuffer); - DeleteObject(f, ModNameW); - - DeleteObject(f, ModNameA->szBuffer); - DeleteObject(f, ModNameA); - - ErrorBreak = true; - break; - } - - pModPathW->String.MaxLength = sizeof(pModPathW->StaticBuffer); - pModPathW->String.szBuffer = pModPathW->StaticBuffer; - - LDRP_LOAD_CONTEXT_FLAGS ctx_flags{ 0 }; - ntRet = f->LdrpPreprocessDllName(ModNameW, pModPathW, nullptr, &ctx_flags); - - DeleteObject(f, ModNameW->szBuffer); - DeleteObject(f, ModNameW); - - DeleteObject(f, ModNameA->szBuffer); - DeleteObject(f, ModNameA); - - if (NT_FAIL(ntRet)) - { - DeleteObject(f, pModPathW); - - ErrorBreak = true; - break; - } - + + //load import HINSTANCE hDll = NULL; - ntRet = f->LdrGetDllHandleEx(NULL, nullptr, nullptr, &pModPathW->String, ReCa(&hDll)); - - if (NT_FAIL(ntRet)) - { - auto * ctx = NewObject(f); - ctx->OriginalFullDllName = pModPathW->String.szBuffer; - - if (!ctx) - { - DeleteObject(f, pModPathW); - - ErrorBreak = true; - break; - } - - ULONG_PTR unknown = 0; - LDR_DATA_TABLE_ENTRY * entry_out = nullptr; - - ntRet = f->LdrpLoadDllInternal(&pModPathW->String, ctx, ctx_flags, 4, nullptr, nullptr, &entry_out, &unknown); - if (NT_SUCCESS(ntRet)) - { - hDll = ReCa(entry_out->DllBase); - } - - DeleteObject(f, ctx); - } - - DeleteObject(f, pModPathW); + ntRet = LoadModule(pData, f, szMod, &hDll, &imports); if (NT_FAIL(ntRet)) { + //unable to load required library ErrorBreak = true; break; } - IMAGE_THUNK_DATA * pThunk = ReCa(pBase + pImportDescr->OriginalFirstThunk); - IMAGE_THUNK_DATA * pIAT = ReCa(pBase + pImportDescr->FirstThunk); + //grab import data + IMAGE_THUNK_DATA * pThunk = ReCa(pBase + pImportDescr->OriginalFirstThunk); + IMAGE_THUNK_DATA * pIAT = ReCa(pBase + pImportDescr->FirstThunk); if (!pImportDescr->OriginalFirstThunk) { @@ -742,12 +958,15 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M IMAGE_IMPORT_BY_NAME * pImport; if (IMAGE_SNAP_BY_ORDINAL(pThunk->u1.Ordinal)) { + //by ordinal ntRet = f->LdrGetProcedureAddress(ReCa(hDll), nullptr, IMAGE_ORDINAL(pThunk->u1.Ordinal), ReCa(pFuncRef)); } else { + //by name pImport = ReCa(pBase + (pThunk->u1.AddressOfData)); + //convert c string import into ANSI_STRING auto * import = NewObject(f); if (!import) { @@ -759,6 +978,7 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M import->Length = SizeAnsiString(import->szBuffer); import->MaxLength = import->Length + 1 * sizeof(char); + //load imported function address and save to IAT ntRet = f->LdrGetProcedureAddress(ReCa(hDll), import, IMAGE_ORDINAL(pThunk->u1.Ordinal), ReCa(pFuncRef)); DeleteObject(f, import); @@ -766,6 +986,7 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M if (NT_FAIL(ntRet)) { + //unable to resolve function address ErrorBreak = true; break; } @@ -778,6 +999,7 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M ++pImportDescr; + //range check in some cases necessary, if(pImportDescr->Name) might not be sufficient if (pImportDescr >= ReCa(pBase + pImportDir->VirtualAddress + pImportDir->Size)) { break; @@ -787,6 +1009,8 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M if (ErrorBreak) { pData->ntRet = ntRet; + + UnloadAndDeleteDependencyRecord(f, imports); ImgSize = 0; f->NtFreeVirtualMemory(hProc, ReCa(&pAllocBase), &ImgSize, MEM_RELEASE); @@ -796,8 +1020,9 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M } } - - //tba: track imports for unloading in case something goes wrong + //resolve delay imports + //this normally is done at runtime and completely optional + //see regular import loading if (Flags & INJ_MM_RESOLVE_DELAY_IMPORTS) { IMAGE_DATA_DIRECTORY * pDelayImportDir = ReCa(&pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT]); @@ -813,129 +1038,9 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M while (pDelayImportDescr && pDelayImportDescr->DllNameRVA) { char * szMod = ReCa(pBase + pDelayImportDescr->DllNameRVA); - auto * ModNameA = NewObject(f); - if (!ModNameA) - { - ntRet = INJ_MM_ERR_HEAP_ALLOC; - - ErrorBreak = true; - break; - } - - if (!InitAnsiString(f, ModNameA, szMod)) - { - ntRet = STATUS_HEAP_CORRUPTION; - - DeleteObject(f, ModNameA); - - ErrorBreak = true; - break; - } - - auto * ModNameW = NewObject(f); - if (!ModNameW) - { - ntRet = INJ_MM_ERR_HEAP_ALLOC; - - DeleteObject(f, ModNameA->szBuffer); - DeleteObject(f, ModNameA); - - ErrorBreak = true; - break; - } - - ModNameW->szBuffer = NewObject(f, MAX_PATH); - ModNameW->MaxLength = sizeof(wchar_t[MAX_PATH]); - - if (!ModNameW->szBuffer) - { - ntRet = INJ_MM_ERR_HEAP_ALLOC; - - DeleteObject(f, ModNameW); - - DeleteObject(f, ModNameA->szBuffer); - DeleteObject(f, ModNameA); - - ErrorBreak = true; - break; - } - - ntRet = f->RtlAnsiStringToUnicodeString(ModNameW, ModNameA, FALSE); - if (NT_FAIL(ntRet)) - { - DeleteObject(f, ModNameW->szBuffer); - DeleteObject(f, ModNameW); - - DeleteObject(f, ModNameA->szBuffer); - DeleteObject(f, ModNameA); - - ErrorBreak = true; - break; - } - - auto * pModPathW = NewObject(f); - if (!pModPathW) - { - DeleteObject(f, ModNameW->szBuffer); - DeleteObject(f, ModNameW); - - DeleteObject(f, ModNameA->szBuffer); - DeleteObject(f, ModNameA); - - ErrorBreak = true; - break; - } - - pModPathW->String.MaxLength = sizeof(pModPathW->StaticBuffer); - pModPathW->String.szBuffer = pModPathW->StaticBuffer; - - LDRP_LOAD_CONTEXT_FLAGS ctx_flags{ 0 }; - ntRet = f->LdrpPreprocessDllName(ModNameW, pModPathW, nullptr, &ctx_flags); - - DeleteObject(f, ModNameW->szBuffer); - DeleteObject(f, ModNameW); - - DeleteObject(f, ModNameA->szBuffer); - DeleteObject(f, ModNameA); - - if (NT_FAIL(ntRet)) - { - DeleteObject(f, pModPathW); - - ErrorBreak = true; - break; - } - + HINSTANCE hDll = NULL; - ntRet = f->LdrGetDllHandleEx(NULL, nullptr, nullptr, &pModPathW->String, ReCa(&hDll)); - - if (NT_FAIL(ntRet)) - { - auto * ctx = NewObject(f); - ctx->OriginalFullDllName = pModPathW->String.szBuffer; - - if (!ctx) - { - DeleteObject(f, pModPathW); - - ErrorBreak = true; - break; - } - - ULONG_PTR unknown = 0; - LDR_DATA_TABLE_ENTRY * entry_out = nullptr; - - ntRet = f->LdrpLoadDllInternal(&pModPathW->String, ctx, ctx_flags, 4, nullptr, nullptr, &entry_out, &unknown); - - if (NT_SUCCESS(ntRet)) - { - hDll = ReCa(entry_out->DllBase); - } - - DeleteObject(f, ctx); - } - - DeleteObject(f, pModPathW); + ntRet = LoadModule(pData, f, szMod, &hDll, &delay_imports); if (NT_FAIL(ntRet)) { @@ -949,15 +1054,14 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M *pModule = hDll; } - IMAGE_THUNK_DATA * pIAT = ReCa(pBase + pDelayImportDescr->ImportAddressTableRVA); - IMAGE_THUNK_DATA * pNameTable = ReCa(pBase + pDelayImportDescr->ImportNameTableRVA); + IMAGE_THUNK_DATA * pIAT = ReCa(pBase + pDelayImportDescr->ImportAddressTableRVA); + IMAGE_THUNK_DATA * pNameTable = ReCa(pBase + pDelayImportDescr->ImportNameTableRVA); for (; pIAT->u1.Function; ++pIAT, ++pNameTable) { - UINT_PTR pFunc = 0; if (IMAGE_SNAP_BY_ORDINAL(pNameTable->u1.Ordinal)) { - f->LdrGetProcedureAddress(ReCa(hDll), nullptr, IMAGE_ORDINAL(pNameTable->u1.Ordinal), ReCa(&pFunc)); + f->LdrGetProcedureAddress(ReCa(hDll), nullptr, IMAGE_ORDINAL(pNameTable->u1.Ordinal), ReCa(pIAT)); } else { @@ -974,7 +1078,7 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M import->Length = SizeAnsiString(import->szBuffer); import->MaxLength = import->Length + 1 * sizeof(char); - ntRet = f->LdrGetProcedureAddress(ReCa(hDll), import, IMAGE_ORDINAL(pNameTable->u1.Ordinal), ReCa(&pFunc)); + ntRet = f->LdrGetProcedureAddress(ReCa(hDll), import, IMAGE_ORDINAL(pNameTable->u1.Ordinal), ReCa(pIAT)); DeleteObject(f, import); } @@ -998,6 +1102,9 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M { pData->ntRet = ntRet; + UnloadAndDeleteDependencyRecord(f, delay_imports); + UnloadAndDeleteDependencyRecord(f, imports); + ImgSize = 0; f->NtFreeVirtualMemory(hProc, ReCa(&pAllocBase), &ImgSize, MEM_RELEASE); f->NtClose(hDllFile); @@ -1006,6 +1113,7 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M } } + //update page protections if (Flags & INJ_MM_SET_PAGE_PROTECTIONS) { ULONG OldProtection = 0; @@ -1014,6 +1122,7 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M if (NT_SUCCESS(ntRet)) { + //iterate over all the previously mapped sections pCurrentSectionHeader = IMAGE_FIRST_SECTION(pNtHeaders); for (UINT i = 0; i != pFileHeader->NumberOfSections; ++i, ++pCurrentSectionHeader) { @@ -1023,6 +1132,7 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M if (SectionSize) { + //identify protection state for current section ULONG NewProtection = PAGE_NOACCESS; if (characteristics & IMAGE_SCN_MEM_EXECUTE) @@ -1052,6 +1162,7 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M } } + //update page protection ntRet = f->NtProtectVirtualMemory(hProc, &pSectionBase, &SectionSize, NewProtection, &OldProtection); if (NT_FAIL(ntRet)) { @@ -1065,6 +1176,9 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M { pData->ntRet = ntRet; + UnloadAndDeleteDependencyRecord(f, delay_imports); + UnloadAndDeleteDependencyRecord(f, imports); + ImgSize = 0; f->NtFreeVirtualMemory(hProc, ReCa(&pAllocBase), &ImgSize, MEM_RELEASE); f->NtClose(hDllFile); @@ -1075,43 +1189,151 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M if (Flags & INJ_MM_ENABLE_EXCEPTIONS) { - ntRet = f->RtlInsertInvertedFunctionTable(pBase, pOptionalHeader->SizeOfImage); - if (NT_FAIL(ntRet)) + //try RtlInsertInvertedFunctionTable first + if (pData->OSVersion >= g_Win81) { - pData->ntRet = ntRet; - - ImgSize = 0; - f->NtFreeVirtualMemory(hProc, ReCa(&pAllocBase), &ImgSize, MEM_RELEASE); - f->NtClose(hDllFile); - - return INJ_MM_ERR_ENABLING_SEH_FAILED; + f->RtlInsertInvertedFunctionTable(pBase, pOptionalHeader->SizeOfImage); + } + else if (pData->OSVersion == g_Win8) + { + auto _RtlInsertInvertedFunctionTable = ReCa(f->RtlInsertInvertedFunctionTable); + _RtlInsertInvertedFunctionTable(pBase, pOptionalHeader->SizeOfImage); + } + else if (pData->OSVersion == g_Win7) + { + auto _RtlInsertInvertedFunctionTable = ReCa(f->RtlInsertInvertedFunctionTable); + _RtlInsertInvertedFunctionTable(ReCa(f->LdrpInvertedFunctionTable), pBase, pOptionalHeader->SizeOfImage); } - bool found = false; + ntRet = STATUS_DLL_NOT_FOUND; + bool partial = true; + +#ifdef _WIN64 + if (veh_shell_fixed) + { + //register VEH shell to fill handler list + pData->hVEH = f->RtlAddVectoredExceptionHandler(0, ReCa(pVEHShell)); + } +#endif + //check LdrpInvertedFunctionTable if module exists for (ULONG i = 0; i < f->LdrpInvertedFunctionTable->Count; ++i) { - if (f->LdrpInvertedFunctionTable->Entries[i].ImageBase == pBase) + RTL_INVERTED_FUNCTION_TABLE_ENTRY * entry = nullptr; + if (pData->OSVersion >= g_Win8) + { + entry = &f->LdrpInvertedFunctionTable->Entries[i]; + } + else { - found = true; + entry = &ReCa(f->LdrpInvertedFunctionTable)->Entries[i]; + } + + if (entry->ImageBase != pBase) + { + continue; + } + + if (entry->ExceptionDirectorySize) + { + //module exists, entries have been initialized + partial = false; + ntRet = STATUS_SUCCESS; + break; } + + //module exists, entries don't + //create fake entry which will be filled at runtime using a VEH shell + void * pFakeExceptionDir = nullptr; + SIZE_T FakeDirSize = 0x800 * sizeof(void *); + ntRet = f->NtAllocateVirtualMemory(hProc, &pFakeExceptionDir, 0, &FakeDirSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + + if (NT_FAIL(ntRet)) + { + break; + } + + //EncodeSystemPointer + UINT_PTR pRaw = ReCa(pFakeExceptionDir); + auto cookie = *P_KUSER_SHARED_DATA_COOKIE; +#ifdef _WIN64 + UINT_PTR pEncoded = bit_rotate_r(cookie ^ pRaw, cookie & 0x3F); +#else + UINT_PTR pEncoded = bit_rotate_r(cookie ^ pRaw, cookie & 0x1F); +#endif + + if (pData->OSVersion >= g_Win81) + { + ntRet = f->LdrProtectMrdata(FALSE); + } + + if (NT_FAIL(ntRet)) + { + f->NtFreeVirtualMemory(hProc, &pFakeExceptionDir, &FakeDirSize, MEM_RELEASE); + + break; + } + + entry->ExceptionDirectory = ReCa(pEncoded); + + if (pData->OSVersion >= g_Win81) + { + f->LdrProtectMrdata(TRUE); + } + + if (veh_shell_fixed && !pData->hVEH) + { + //register VEH shell to fill handler list + pData->hVEH = f->RtlAddVectoredExceptionHandler(0, ReCa(pVEHShell)); + } + + break; + } + +#ifdef _WIN64 + if (NT_SUCCESS(ntRet) && partial) + { + //on x64 also try documented method + auto size = pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].Size; + if (size) + { + auto * pExceptionHandlers = ReCa(pBase + pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION].VirtualAddress); + auto EntryCount = size / sizeof(RUNTIME_FUNCTION); + + if (!f->RtlAddFunctionTable(pExceptionHandlers, MDWD(EntryCount), ReCa(pBase))) + { + ntRet = STATUS_UNSUCCESSFUL; + } + } + else + { + ntRet = STATUS_UNSUCCESSFUL; + } } +#endif - if (!found) + if (NT_FAIL(ntRet)) { - //Insert seh table manually will be implemented eventually + pData->ntRet = ntRet; + + if (pData->hVEH) + { + f->RtlRemoveVectoredExceptionHandler(pData->hVEH); + } + + UnloadAndDeleteDependencyRecord(f, delay_imports); + UnloadAndDeleteDependencyRecord(f, imports); ImgSize = 0; f->NtFreeVirtualMemory(hProc, ReCa(&pAllocBase), &ImgSize, MEM_RELEASE); f->NtClose(hDllFile); - return INJ_MM_ERR_NOT_IN_LDRP_SEH_TABLE; + return INJ_MM_ERR_ENABLING_SEH_FAILED; } - - //SEH is still fucked by DEP even with correct page protections, might be fixed with LdrpCfgProcessLoadConfig and patching dep callbacks? } + //initialized static TLS and call TLS callbacks if ((Flags & INJ_MM_EXECUTE_TLS) && pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size) { auto * pTLS = ReCa(pBase + pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress); @@ -1119,6 +1341,9 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M auto * pDummyLdr = NewObject(f); if (!pDummyLdr) { + UnloadAndDeleteDependencyRecord(f, delay_imports); + UnloadAndDeleteDependencyRecord(f, imports); + ImgSize = 0; f->NtFreeVirtualMemory(hProc, ReCa(&pAllocBase), &ImgSize, MEM_RELEASE); f->NtClose(hDllFile); @@ -1127,10 +1352,22 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M } //LdrpHandleTlsData either crashes or returns STATUS_SUCCESS -> no point in error checking - //It also only accesses the DllBase member of the ldr entry thus a dummy entry is sufficient + //it also only accesses the DllBase member of the ldr entry thus a dummy ldr entry is sufficient pDummyLdr->DllBase = pBase; - f->LdrpHandleTlsData(pDummyLdr); + + if (pData->OSVersion <= g_Win8) + { + //Win7/Win8 __stdcall + auto _LdrpHandleTlsData = ReCa(f->LdrpHandleTlsData); + _LdrpHandleTlsData(ReCa(pDummyLdr)); + } + else + { + //Win8.1+ __fastcall + f->LdrpHandleTlsData(pDummyLdr); + } + DeleteObject(f, pDummyLdr); auto * pCallback = ReCa(pTLS->AddressOfCallBacks); @@ -1141,6 +1378,7 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M } } + //run DllMain if (Flags & INJ_MM_RUN_DLL_MAIN && pOptionalHeader->AddressOfEntryPoint) { ULONG State = 0; @@ -1149,9 +1387,9 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M if (Flags & INJ_MM_RUN_UNDER_LDR_LOCK) { - ntRet = f->LdrLockLoaderLock(0, &State, &Cookie); + ntRet = f->LdrLockLoaderLock(NULL, &State, &Cookie); - //Don't interrupt only because loader lock wasn't acquired + //don't interrupt only because loader lock wasn't acquired locked = NT_SUCCESS(ntRet); } @@ -1160,12 +1398,14 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M if ((Flags & INJ_MM_RUN_UNDER_LDR_LOCK) && locked) { - f->LdrUnlockLoaderLock(0, Cookie); + f->LdrUnlockLoaderLock(NULL, Cookie); } } + //remove unnecesary data from the PE header if (Flags & INJ_MM_CLEAN_DATA_DIR && !(Flags & INJ_MM_SET_PAGE_PROTECTIONS)) { + //remove strings from the import directory DWORD Size = pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size; if (Size) { @@ -1176,8 +1416,8 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M for (; *szMod++; *szMod = '\0'); pImportDescr->Name = 0; - IMAGE_THUNK_DATA * pThunk = ReCa(pBase + pImportDescr->OriginalFirstThunk); - IMAGE_THUNK_DATA * pIAT = ReCa(pBase + pImportDescr->FirstThunk); + IMAGE_THUNK_DATA * pThunk = ReCa(pBase + pImportDescr->OriginalFirstThunk); + IMAGE_THUNK_DATA * pIAT = ReCa(pBase + pImportDescr->FirstThunk); if (!pImportDescr->OriginalFirstThunk) { @@ -1208,6 +1448,7 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = 0; } + //remove strings from the delay import directory Size = pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].Size; if (Size && !(Flags & INJ_MM_RESOLVE_DELAY_IMPORTS)) { @@ -1249,6 +1490,7 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].Size = 0; } + //remove debug data Size = pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size; if (Size) { @@ -1265,6 +1507,7 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG].Size = 0; } + //remove base relocation information Size = pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size; if (Size) { @@ -1283,6 +1526,7 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = 0; } + //remove TLS callback information Size = pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS].Size; if (Size) { @@ -1310,6 +1554,7 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M SIZE_T header_size = pOptionalHeader->SizeOfHeaders; ULONG old_access = NULL; + //PE header is R/E only if (Flags & INJ_MM_SET_PAGE_PROTECTIONS) { ntRet = f->NtProtectVirtualMemory(hProc, &base, &header_size, PAGE_EXECUTE_READWRITE, &old_access); @@ -1330,6 +1575,8 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M } else if (Flags & INJ_FAKE_HEADER) { + //grab ntdll from the ldr + PEB * pPEB = nullptr; #ifdef _WIN64 @@ -1368,6 +1615,7 @@ DWORD __declspec(code_seg(".mmap_sec$1")) __stdcall ManualMapping_Shell(MANUAL_M f->memmove(pBase, ntdll_ldr->DllBase, min(p_nt_nt->OptionalHeader.SizeOfHeaders, header_size)); } + //update PE header protection back to R/E if (Flags & INJ_MM_SET_PAGE_PROTECTIONS) { ntRet = f->NtProtectVirtualMemory(hProc, &base, &header_size, old_access, &old_access); @@ -1408,28 +1656,42 @@ MANUAL_MAPPING_FUNCTION_TABLE::MANUAL_MAPPING_FUNCTION_TABLE() NT_FUNC_CONSTRUCTOR_INIT(NtProtectVirtualMemory); NT_FUNC_CONSTRUCTOR_INIT(NtFreeVirtualMemory); + NT_FUNC_CONSTRUCTOR_INIT(NtCreateSection); + NT_FUNC_CONSTRUCTOR_INIT(NtMapViewOfSection); + NT_FUNC_CONSTRUCTOR_INIT(memmove); NT_FUNC_CONSTRUCTOR_INIT(RtlZeroMemory); NT_FUNC_CONSTRUCTOR_INIT(RtlAllocateHeap); NT_FUNC_CONSTRUCTOR_INIT(RtlFreeHeap); - NT_FUNC_CONSTRUCTOR_INIT(LdrGetDllHandleEx); + NT_FUNC_CONSTRUCTOR_INIT(LdrpLoadDll); NT_FUNC_CONSTRUCTOR_INIT(LdrpLoadDllInternal); NT_FUNC_CONSTRUCTOR_INIT(LdrGetProcedureAddress); + NT_FUNC_CONSTRUCTOR_INIT(LdrUnloadDll); + NT_FUNC_CONSTRUCTOR_INIT(RtlAnsiStringToUnicodeString); NT_FUNC_CONSTRUCTOR_INIT(LdrpPreprocessDllName); NT_FUNC_CONSTRUCTOR_INIT(RtlInsertInvertedFunctionTable); +#ifdef _WIN64 + NT_FUNC_CONSTRUCTOR_INIT(RtlAddFunctionTable); +#endif NT_FUNC_CONSTRUCTOR_INIT(LdrpHandleTlsData); NT_FUNC_CONSTRUCTOR_INIT(LdrLockLoaderLock); NT_FUNC_CONSTRUCTOR_INIT(LdrUnlockLoaderLock); + NT_FUNC_CONSTRUCTOR_INIT(LdrProtectMrdata); + + NT_FUNC_CONSTRUCTOR_INIT(RtlAddVectoredExceptionHandler); + NT_FUNC_CONSTRUCTOR_INIT(RtlRemoveVectoredExceptionHandler); + NT_FUNC_CONSTRUCTOR_INIT(LdrpModuleBaseAddressIndex); NT_FUNC_CONSTRUCTOR_INIT(LdrpMappingInfoIndex); NT_FUNC_CONSTRUCTOR_INIT(LdrpHeap); NT_FUNC_CONSTRUCTOR_INIT(LdrpInvertedFunctionTable); + NT_FUNC_CONSTRUCTOR_INIT(LdrpDefaultPath); pLdrpHeap = nullptr; } \ No newline at end of file diff --git a/GH Injector Library/Manual Mapping.h b/GH Injector Library/Manual Mapping.h index faab8e1..508e96c 100644 --- a/GH Injector Library/Manual Mapping.h +++ b/GH Injector Library/Manual Mapping.h @@ -1,22 +1,29 @@ #pragma once -#include "Injection.h" +#include "VEH Shell.h" #define RELOC_FLAG86(RelInfo) ((RelInfo >> 0x0C) == IMAGE_REL_BASED_HIGHLOW) #define RELOC_FLAG64(RelInfo) ((RelInfo >> 0x0C) == IMAGE_REL_BASED_DIR64) -#define MIN_SHIFT_OFFSET 0x100 -#define MAX_SHIFT_OFFSET 0x1000 -#define BASE_ALIGNMENT 0x10 - #ifdef _WIN64 #define RELOC_FLAG RELOC_FLAG64 #else #define RELOC_FLAG RELOC_FLAG86 #endif +#define MIN_SHIFT_OFFSET 0x100 +#define MAX_SHIFT_OFFSET 0x1000 + using f_DLL_ENTRY_POINT = BOOL(WINAPI*)(HINSTANCE hDll, DWORD dwReason, void * pReserved); +//list to track imports and unload on failure +typedef struct _MM_DEPENDENCY_RECORD +{ + struct _MM_DEPENDENCY_RECORD * Next; + struct _MM_DEPENDENCY_RECORD * Prev; + HANDLE DllHandle; +} MM_DEPENDENCY_RECORD, * PMM_DEPENDENCY_RECORD; + namespace MMAP_NATIVE { using namespace NATIVE; @@ -41,28 +48,42 @@ namespace MMAP_NATIVE ALIGN NT_FUNC_LOCAL(NtProtectVirtualMemory); ALIGN NT_FUNC_LOCAL(NtFreeVirtualMemory); + ALIGN NT_FUNC_LOCAL(NtCreateSection); + ALIGN NT_FUNC_LOCAL(NtMapViewOfSection); + ALIGN NT_FUNC_LOCAL(memmove); ALIGN NT_FUNC_LOCAL(RtlZeroMemory); ALIGN NT_FUNC_LOCAL(RtlAllocateHeap); ALIGN NT_FUNC_LOCAL(RtlFreeHeap); - ALIGN NT_FUNC_LOCAL(LdrGetDllHandleEx); + ALIGN NT_FUNC_LOCAL(LdrpLoadDll); ALIGN NT_FUNC_LOCAL(LdrpLoadDllInternal); ALIGN NT_FUNC_LOCAL(LdrGetProcedureAddress); + ALIGN NT_FUNC_LOCAL(LdrUnloadDll); + ALIGN NT_FUNC_LOCAL(RtlAnsiStringToUnicodeString); ALIGN NT_FUNC_LOCAL(LdrpPreprocessDllName); ALIGN NT_FUNC_LOCAL(RtlInsertInvertedFunctionTable); +#ifdef _WIN64 + ALIGN NT_FUNC_LOCAL(RtlAddFunctionTable); +#endif ALIGN NT_FUNC_LOCAL(LdrpHandleTlsData); ALIGN NT_FUNC_LOCAL(LdrLockLoaderLock); ALIGN NT_FUNC_LOCAL(LdrUnlockLoaderLock); + ALIGN NT_FUNC_LOCAL(LdrProtectMrdata); + + ALIGN NT_FUNC_LOCAL(RtlAddVectoredExceptionHandler); + ALIGN NT_FUNC_LOCAL(RtlRemoveVectoredExceptionHandler); + ALIGN NT_FUNC_LOCAL(LdrpModuleBaseAddressIndex); ALIGN NT_FUNC_LOCAL(LdrpMappingInfoIndex); ALIGN NT_FUNC_LOCAL(LdrpHeap); ALIGN NT_FUNC_LOCAL(LdrpInvertedFunctionTable); + ALIGN NT_FUNC_LOCAL(LdrpDefaultPath); ALIGN void * pLdrpHeap; @@ -71,11 +92,11 @@ namespace MMAP_NATIVE ALIGN struct MANUAL_MAPPING_DATA { - ALIGN HINSTANCE hRet{ 0 }; - ALIGN DWORD Flags{ 0 }; - ALIGN NTSTATUS ntRet{ 0 }; + ALIGN HINSTANCE hRet = NULL; + ALIGN DWORD Flags = NULL; + ALIGN NTSTATUS ntRet = STATUS_SUCCESS; - ALIGN WORD ShiftOffset{ 0 }; + ALIGN WORD ShiftOffset = 0; ALIGN UNICODE_STRING DllPath{ 0 }; ALIGN wchar_t szPathBuffer[MAX_PATH]{ 0 }; @@ -85,6 +106,13 @@ namespace MMAP_NATIVE ALIGN wchar_t NtPathPrefix[8] = L"\\??\\\0\0\0"; + ALIGN DWORD OSVersion = 0; + ALIGN DWORD OSBuildNumber = 0; + + ALIGN BYTE * pVEHShell = nullptr; + ALIGN DWORD VEHShellSize = 0; + ALIGN HANDLE hVEH = nullptr; + ALIGN MANUAL_MAPPING_FUNCTION_TABLE f; }; @@ -110,15 +138,20 @@ namespace MMAP_WOW64 ALIGN_86 WOW64_FUNCTION_POINTER_LOCAL(NtProtectVirtualMemory); ALIGN_86 WOW64_FUNCTION_POINTER_LOCAL(NtFreeVirtualMemory); + ALIGN_86 WOW64_FUNCTION_POINTER_LOCAL(NtCreateSection); + ALIGN_86 WOW64_FUNCTION_POINTER_LOCAL(NtMapViewOfSection); + ALIGN_86 WOW64_FUNCTION_POINTER_LOCAL(memmove); ALIGN_86 WOW64_FUNCTION_POINTER_LOCAL(RtlZeroMemory); ALIGN_86 WOW64_FUNCTION_POINTER_LOCAL(RtlAllocateHeap); ALIGN_86 WOW64_FUNCTION_POINTER_LOCAL(RtlFreeHeap); - ALIGN_86 WOW64_FUNCTION_POINTER_LOCAL(LdrGetDllHandleEx); + ALIGN_86 WOW64_FUNCTION_POINTER_LOCAL(LdrpLoadDll); ALIGN_86 WOW64_FUNCTION_POINTER_LOCAL(LdrpLoadDllInternal); ALIGN_86 WOW64_FUNCTION_POINTER_LOCAL(LdrGetProcedureAddress); + ALIGN_86 WOW64_FUNCTION_POINTER_LOCAL(LdrUnloadDll); + ALIGN_86 WOW64_FUNCTION_POINTER_LOCAL(RtlAnsiStringToUnicodeString); ALIGN_86 WOW64_FUNCTION_POINTER_LOCAL(LdrpPreprocessDllName); @@ -128,32 +161,45 @@ namespace MMAP_WOW64 ALIGN_86 WOW64_FUNCTION_POINTER_LOCAL(LdrLockLoaderLock); ALIGN_86 WOW64_FUNCTION_POINTER_LOCAL(LdrUnlockLoaderLock); + ALIGN_86 WOW64_FUNCTION_POINTER_LOCAL(LdrProtectMrdata); + + ALIGN_86 WOW64_FUNCTION_POINTER_LOCAL(RtlAddVectoredExceptionHandler); + ALIGN_86 WOW64_FUNCTION_POINTER_LOCAL(RtlRemoveVectoredExceptionHandler); + ALIGN_86 WOW64_FUNCTION_POINTER_LOCAL(LdrpModuleBaseAddressIndex); ALIGN_86 WOW64_FUNCTION_POINTER_LOCAL(LdrpMappingInfoIndex); ALIGN_86 WOW64_FUNCTION_POINTER_LOCAL(LdrpHeap); ALIGN_86 WOW64_FUNCTION_POINTER_LOCAL(LdrpInvertedFunctionTable); + ALIGN_86 WOW64_FUNCTION_POINTER_LOCAL(LdrpDefaultPath); ALIGN_86 DWORD pLdrpHeap; MANUAL_MAPPING_FUNCTION_TABLE_WOW64(); }; - struct MANUAL_MAPPING_DATA_WOW64 + ALIGN_86 struct MANUAL_MAPPING_DATA_WOW64 { - ALIGN_86 DWORD hRet{ 0 }; - ALIGN_86 DWORD Flags{ 0 }; - ALIGN_86 DWORD ntRet{ 0 }; + ALIGN_86 DWORD hRet = NULL; + ALIGN_86 DWORD Flags = NULL; + ALIGN_86 DWORD ntRet = STATUS_SUCCESS; - ALIGN_86 WORD ShiftOffset{ 0 }; + ALIGN_86 WORD ShiftOffset = 0; - ALIGN_86 UNICODE_STRING32 DllPath{ 0 }; + ALIGN_86 UNICODE_STRING_32 DllPath{ 0 }; ALIGN_86 wchar_t szPathBuffer[MAX_PATH]{ 0 }; - ALIGN_86 UNICODE_STRING32 DllName{ 0 }; + ALIGN_86 UNICODE_STRING_32 DllName{ 0 }; ALIGN_86 wchar_t szNameBuffer[MAX_PATH]{ 0 }; ALIGN_86 wchar_t NtPathPrefix[8] = L"\\??\\\0\0\0"; + ALIGN_86 DWORD OSVersion = 0; + ALIGN_86 DWORD OSBuildNumber = 0; + + ALIGN_86 DWORD pVEHShell = 0; + ALIGN_86 DWORD VEHShellSize = 0; + ALIGN_86 DWORD hVEH = 0; + ALIGN_86 MANUAL_MAPPING_FUNCTION_TABLE_WOW64 f; }; diff --git a/GH Injector Library/NT Defs.h b/GH Injector Library/NT Defs.h new file mode 100644 index 0000000..e8e9fee --- /dev/null +++ b/GH Injector Library/NT Defs.h @@ -0,0 +1,773 @@ +#pragma once + +#include "pch.h" + +#pragma region nt (un)defines + +#ifndef NT_FAIL +#define NT_FAIL(status) (status < 0) +#endif + +#ifndef NT_SUCCESS +#define NT_SUCCESS(status) (status >= 0) +#endif + +#ifdef memmove +#undef memmove +#endif + +#ifdef RtlZeroMemory +#undef RtlZeroMemory +#endif + +#define THREAD_CREATE_FLAGS_CREATE_SUSPENDED 0x00000001 +#define THREAD_CREATE_FLAGS_SKIP_THREAD_ATTACH 0x00000002 //broken?! +#define THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER 0x00000004 + +#define OBJ_CASE_INSENSITIVE 0x00000040 + +#define STATUS_SUCCESS 0x00000000 +#define STATUS_UNSUCCESSFUL 0xC0000001 +#define STATUS_NOT_IMPLEMENTED 0xC0000002 +#define STATUS_INFO_LENGTH_MISMATCH 0xC0000004 + +#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020 + +#define InitializeObjectAttributes(p, n, a, r, s) \ +{ \ + (p)->Length = sizeof(OBJECT_ATTRIBUTES); \ + (p)->RootDirectory = r; \ + (p)->Attributes = a; \ + (p)->ObjectName = n; \ + (p)->SecurityDescriptor = s; \ + (p)->SecurityQualityOfService = NULL; \ +} + +typedef LONG KPRIORITY; + +#define KUSER_SHARED_DATA (DWORD)0x7FFE0000 +#define P_KUSER_SHARED_DATA_COOKIE ReCa(KUSER_SHARED_DATA + 0x0330) + +#define NtCurrentProcess() ( (HANDLE)(LONG_PTR) -1 ) + +#pragma endregion + +#pragma region enums + +typedef enum class _PROCESSINFOCLASS +{ + ProcessBasicInformation = 0, + ProcessSessionInformation = 24, + ProcessWow64Information = 26, + ProcessProtectionInformation = 61 +} PROCESSINFOCLASS; + +typedef enum class _SYSTEM_INFORMATION_CLASS +{ + SystemProcessInformation = 5, + SystemHandleInformation = 16 +} SYSTEM_INFORMATION_CLASS; + +typedef enum class _THREADINFOCLASS +{ + ThreadBasicInformation = 0, + ThreadQuerySetWin32StartAddress = 9 +} THREADINFOCLASS; + +typedef enum class _THREAD_STATE +{ + Running = 0x02, + Waiting = 0x05 +} THREAD_STATE; + +typedef enum class _KWAIT_REASON +{ + WrQueue = 0x0F +} KWAIT_REASON; + +typedef enum class _OBEJECT_TYPE_NUMBER +{ + Process = 0x07 +} OBJECT_TYPE_NUMBER; + +typedef enum _FILE_INFORMATION_CLASS +{ + FileStandardInformation = 5, + FilePositionInformation = 14 +} FILE_INFORMATION_CLASS, * PFILE_INFORMATION_CLASS; + +typedef enum _LDR_DDAG_STATE : int +{ + LdrModulesMerged = -5, + LdrModulesInitError = -4, + LdrModulesSnapError = -3, + LdrModulesUnloaded = -2, + LdrModulesUnloading = -1, + LdrModulesPlaceHolder = 0, + LdrModulesMapping = 1, + LdrModulesMapped = 2, + LdrModulesWaitingForDependencies = 3, + LdrModulesSnapping = 4, + LdrModulesSnapped = 5, + LdrModulesCondensed = 6, + LdrModulesReadyToInit = 7, + LdrModulesInitializing = 8, + LdrModulesReadyToRun = 9 +} LDR_DDAG_STATE, * PLDR_DDAG_STATE; + +typedef enum _LDR_DLL_LOAD_REASON : int +{ + LoadReasonUnknown = -1, + LoadReasonStaticDependency = 0, + LoadReasonStaticForwarderDependency = 1, + LoadReasonDynamicForwarderDependency = 2, + LoadReasonDelayloadDependency = 3, + LoadReasonDynamicLoad = 4, + LoadReasonAsImageLoad = 5, + LoadReasonAsDataLoad = 6, + LoadReasonEnclavePrimary = 7, + LoadReasonEnclaveDependency = 8 +} LDR_DLL_LOAD_REASON, * PLDR_DLL_LOAD_REASON; + +typedef enum _SECTION_INHERIT +{ + ViewShare = 1, + ViewUnmap = 2 +} SECTION_INHERIT, * PSECTION_INHERIT; + +typedef enum _LDR_HOT_PATCH_STATE +{ + LdrHotPatchBaseImage = 0, + LdrHotPatchNotApplied = 1, + LdrHotPatchAppliedReverse = 2, + LdrHotPatchAppliedForward = 3, + LdrHotPatchFailedToPatch = 4, + LdrHotPatchStateMax = 5 +} LDR_HOT_PATCH_STATE, *PLDR_HOT_PATCH_STATE; + +#pragma endregion + +struct PEB; + +typedef struct _ANSI_STRING +{ + USHORT Length; + USHORT MaxLength; + char * szBuffer; +} ANSI_STRING, * PANSI_STRING; + +typedef struct _UNICODE_STRING +{ + WORD Length; + WORD MaxLength; + wchar_t * szBuffer; +} UNICODE_STRING, * PUNICODE_STRING; + +typedef struct _RTL_BALANCED_NODE +{ + union + { + struct _RTL_BALANCED_NODE * Children[2]; + struct + { + struct _RTL_BALANCED_NODE * Left; + struct _RTL_BALANCED_NODE * Right; + }; + }; + + union + { + UCHAR Red : 1; + UCHAR Balance : 2; + ULONG_PTR ParentValue; + }; +} RTL_BALANCED_NODE, * PRTL_BALANCED_NODE; + +typedef struct _RTL_RB_TREE +{ + RTL_BALANCED_NODE * Root; + RTL_BALANCED_NODE * Min; +} RTL_RB_TREE, * PRTL_RB_TREE; + +typedef struct _CLIENT_ID +{ + HANDLE UniqueProcess; + HANDLE UniqueThread; +} CLIENT_ID, * PCLIENT_ID; + +typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO +{ + WORD UniqueProcessId; + WORD CreateBackTraceIndex; + BYTE ObjectTypeIndex; + BYTE HandleAttributes; + WORD HandleValue; + void * Object; + ULONG GrantedAccess; +} SYSTEM_HANDLE_TABLE_ENTRY_INFO, * PSYSTEM_HANDLE_TABLE_ENTRY_INFO; + +typedef struct _SYSTEM_HANDLE_INFORMATION +{ + ULONG NumberOfHandles; + SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[1]; +} SYSTEM_HANDLE_INFORMATION, * PSYSTEM_HANDLE_INFORMATION; + +typedef struct _THREAD_BASIC_INFORMATION +{ + NTSTATUS ExitStatus; + PVOID TebBaseAddress; + CLIENT_ID ClientId; + KAFFINITY AffinityMask; + KPRIORITY Priority; + KPRIORITY BasePriority; +} THREAD_BASIC_INFORMATION, * PTHREAD_BASIC_INFORMATION; + +typedef struct _PROCESS_BASIC_INFORMATION +{ + NTSTATUS ExitStatus; + PEB * pPEB; + ULONG_PTR AffinityMask; + LONG BasePriority; + HANDLE UniqueProcessId; + HANDLE InheritedFromUniqueProcessId; +} PROCESS_BASIC_INFORMATION, * PPROCESS_BASIC_INFORMATION; + +typedef struct _PROCESS_SESSION_INFORMATION +{ + ULONG SessionId; +} PROCESS_SESSION_INFORMATION, * PPROCESS_SESSION_INFORMATION; + +typedef struct _SYSTEM_THREAD_INFORMATION +{ + LARGE_INTEGER KernelTime; + LARGE_INTEGER UserTime; + LARGE_INTEGER CreateTime; + ULONG WaitTime; + PVOID StartAddress; + CLIENT_ID ClientId; + KPRIORITY Priority; + LONG BasePriority; + ULONG ContextSwitches; + THREAD_STATE ThreadState; + KWAIT_REASON WaitReason; +} SYSTEM_THREAD_INFORMATION, * PSYSTEM_THREAD_INFORMATION; + +typedef struct _SYSTEM_PROCESS_INFORMATION +{ + ULONG NextEntryOffset; + ULONG NumberOfThreads; + LARGE_INTEGER WorkingSetPrivateSize; + ULONG HardFaultCount; + ULONG NumberOfThreadsHighWatermark; + ULONGLONG CycleTime; + LARGE_INTEGER CreateTime; + LARGE_INTEGER UserTime; + LARGE_INTEGER KernelTime; + UNICODE_STRING ImageName; + KPRIORITY BasePriority; + HANDLE UniqueProcessId; + HANDLE InheritedFromUniqueProcessId; + ULONG HandleCount; + ULONG SessionId; + ULONG_PTR UniqueProcessKey; + SIZE_T PeakVirtualSize; + SIZE_T VirtualSize; + ULONG PageFaultCount; + SIZE_T PeakWorkingSetSize; + SIZE_T WorkingSetSize; + SIZE_T QuotaPeakPagedPoolUsage; + SIZE_T QuotaPagedPoolUsage; + SIZE_T QuotaPeakNonPagedPoolUsage; + SIZE_T QuotaNonPagedPoolUsage; + SIZE_T PagefileUsage; + SIZE_T PeakPagefileUsage; + SIZE_T PrivatePageCount; + LARGE_INTEGER ReadOperationCount; + LARGE_INTEGER WriteOperationCount; + LARGE_INTEGER OtherOperationCount; + LARGE_INTEGER ReadTransferCount; + LARGE_INTEGER WriteTransferCount; + LARGE_INTEGER OtherTransferCount; + SYSTEM_THREAD_INFORMATION Threads[1]; +} SYSTEM_PROCESS_INFORMATION, * PSYSTEM_PROCESS_INFORMATION; + +typedef struct _FILE_STANDARD_INFORMATION +{ + LARGE_INTEGER AllocationSize; + LARGE_INTEGER EndOfFile; + ULONG NumberOfLinks; + BOOLEAN DeletePending; + BOOLEAN Directory; +} FILE_STANDARD_INFORMATION, * PFILE_STANDARD_INFORMATION; + +typedef struct _FILE_POSITION_INFORMATION +{ + LARGE_INTEGER CurrentByteOffset; +} FILE_POSITION_INFORMATION, * PFILE_POSITION_INFORMATION; + +typedef struct _OBJECT_ATTRIBUTES +{ + ULONG Length; + HANDLE RootDirectory; + UNICODE_STRING * ObjectName; + ULONG Attributes; + PVOID SecurityDescriptor; + PVOID SecurityQualityOfService; +} OBJECT_ATTRIBUTES, * POBJECT_ATTRIBUTES; + +typedef struct _IO_STATUS_BLOCK +{ + union + { + NTSTATUS Status; + PVOID Pointer; + } DUMMYUNIONNAME; + + ULONG_PTR Information; +} IO_STATUS_BLOCK, * PIO_STATUS_BLOCK; + +typedef struct _PEB_LDR_DATA +{ + ULONG Length; + BYTE Initialized; + HANDLE SsHandle; + LIST_ENTRY InLoadOrderModuleListHead; + LIST_ENTRY InMemoryOrderModuleListHead; + LIST_ENTRY InInitializationOrderModuleListHead; + PVOID EntryInProgress; + BYTE ShutdownInProgress; + HANDLE ShutdownThreadId; +} PEB_LDR_DATA, * PPEB_LDR_DATA; + +struct PEB +{ + BOOLEAN InheritedAddressSpace; + BOOLEAN ReadImageFileExecOptions; + BOOLEAN BeingDebugged; + + union + { + UCHAR BitField; + struct + { + UCHAR ImageUsedLargePages : 1; + UCHAR IsProtectedProcess : 1; + UCHAR IsImageDynamicallyRelocated : 1; + UCHAR SkipPatchingUser32Forwarders : 1; + UCHAR IsPackagedProcess : 1; + UCHAR IsAppContainer : 1; + UCHAR IsProtectedProcessLight : 1; + UCHAR IsLongPathAwareProcess : 1; + }; + }; + + HANDLE Mutant; + + PVOID ImageBaseAddress; + + PEB_LDR_DATA * Ldr; + + PVOID * ProcessParameters; + PVOID SubSystemData; + HANDLE ProcessHeap; + RTL_CRITICAL_SECTION * FastPebLock; + PVOID AtlThunkSListPtr; + PVOID IFEOKey; + + union + { + ULONG CrossProcessFlags; + struct + { + ULONG ProcessInJob : 1; + ULONG ProcessInitializing : 1; + ULONG ProcessUsingVEH : 1; + ULONG ProcessUsingVCH : 1; + ULONG ProcessUsingFTH : 1; + ULONG ProcessPreviouslyThrottled : 1; + ULONG ProcessCurrentlyThrottled : 1; + ULONG ProcessImagesHotPatched : 1; + ULONG ReservedBits0 : 24; + }; + }; + +#ifdef _WIN64 + UCHAR Padding1[4]; +#endif + + union + { + PVOID KernelCallbackTable; + PVOID UserSharedInfoPtr; + }; + + ULONG SystemReserved; + ULONG AtlThunkSListPtr32; + PVOID ApiSetMap; + ULONG TlsExpansionCounter; + +#ifdef _WIN64 + UCHAR Padding2[4]; +#endif + + PVOID TlsBitmap; + ULONG TlsBitmapBits[2]; + PVOID ReadOnlySharedMemoryBase; + + union + { + PVOID HotpatchInformation; // till Win8 + PVOID SparePvoid0; // Win8.1 -> Win10 (1607) + PVOID SharedData; // Win10 (1703) + + }; + + PVOID * ReadOnlyStaticServerData; + PVOID AnsiCodePageData; + PVOID OemCodePageData; + PVOID UnicodeCaseTableData; + ULONG NumberOfProcessors; + ULONG NtGlobalFlag; + LARGE_INTEGER CriticalSectionTimeout; + ULONG_PTR HeapSegmentReserve; + ULONG_PTR HeapSegmentCommit; + ULONG_PTR HeapDeCommitTotalFreeThreshold; + ULONG_PTR HeapDeCommitFreeBlockThreshold; + ULONG NumberOfHeaps; + ULONG MaximumNumberOfHeaps; + PVOID * ProcessHeaps; + PVOID GdiSharedHandleTable; + PVOID ProcessStarterHelper; + ULONG GdiDCAttributeList; + +#ifdef _WIN64 + UCHAR Padding3[4]; +#endif + + RTL_CRITICAL_SECTION * LoaderLock; + ULONG OSMajorVersion; + ULONG OSMinorVersion; + + USHORT OSBuildNumber; + USHORT OSCSDVersion; +}; + +typedef struct _LDR_SERVICE_TAG_RECORD +{ + struct _LDR_SERVICE_TAG_RECORD * Next; + ULONG ServiceTag; +} LDR_SERVICE_TAG_RECORD, * PLDR_SERVICE_TAG_RECORD; + +typedef struct _LDRP_CSLIST +{ + struct _SINGLE_LIST_ENTRY * Tail; +} LDRP_CSLIST, * PLDRP_CSLIST; + +typedef struct _LDRP_UNICODE_STRING_BUNDLE +{ + UNICODE_STRING String; + WCHAR StaticBuffer[128]; +} LDRP_UNICODE_STRING_BUNDLE, * PLDRP_UNICODE_STRING_BUNDLE; + +typedef struct _RTL_INVERTED_FUNCTION_TABLE_ENTRY +{ + IMAGE_RUNTIME_FUNCTION_ENTRY * ExceptionDirectory; + PVOID ImageBase; + ULONG ImageSize; + ULONG ExceptionDirectorySize; +} RTL_INVERTED_FUNCTION_TABLE_ENTRY, * PRTL_INVERTED_FUNCTION_TABLE_ENTRY; + +typedef struct _RTL_INVERTED_FUNCTION_TABLE +{ + ULONG Count; + ULONG MaxCount; + ULONG Epoch; + UCHAR Overflow; + RTL_INVERTED_FUNCTION_TABLE_ENTRY Entries[ANYSIZE_ARRAY]; +} RTL_INVERTED_FUNCTION_TABLE, * PRTL_INVERTED_FUNCTION_TABLE; + +typedef union _LDR_SEARCH_PATH +{ + BOOLEAN NoPath : 1; + wchar_t * szSearchPath; +} LDR_SEARCH_PATH, * PLDR_SEARCH_PATH; + +//1507 - 1511 +typedef struct _LDRP_PATH_SEARCH_CONTEXT_1507 +{ + wchar_t * DllSearchPathOut; + void * Unknown_0[2]; + wchar_t * OriginalFullDllName; + void * unknown_1[7]; + ULONG64 unknown_2[4]; +} LDRP_PATH_SEARCH_CONTEXT_1507, * PLDRP_PATH_SEARCH_CONTEXT_1507; //x86 size <= 0x50, x64 size <= 0x80 + +//1607+ +typedef struct _LDRP_PATH_SEARCH_CONTEXT +{ + wchar_t * DllSearchPathOut; + void * Unknown_0[3]; + wchar_t * OriginalFullDllName; + void * unknown_1[7]; + ULONG64 unknown_2[4]; +} LDRP_PATH_SEARCH_CONTEXT, * PLDRP_PATH_SEARCH_CONTEXT; //x86 size <= 0x50, x64 size <= 0x80 + +typedef union _LDRP_LOAD_CONTEXT_FLAGS +{ + ULONG32 Flags; + struct + { + ULONG32 Redirected : 1; + ULONG32 Static : 1; + ULONG32 BaseNameOnly : 1; + ULONG32 HasFullPath : 1; + ULONG32 KnownDll : 1; + ULONG32 SystemImage : 1; + ULONG32 ExecutableImage : 1; + ULONG32 AppContainerImage : 1; + ULONG32 CallInit : 1; + ULONG32 UserAllocated : 1; + ULONG32 SearchOnlyFirstPathSegment : 1; + ULONG32 RedirectedByAPISet : 1; + }; +} LDRP_LOAD_CONTEXT_FLAGS, * PLDRP_LOAD_CONTEXT_FLAGS; + +#ifdef _WIN64 + +typedef ALIGN_86 struct _UNICODE_STRING_32 +{ + WORD Length; + WORD MaxLength; + DWORD szBuffer; +} UNICODE_STRING_32, * PUNICODE_STRING_32; + +typedef ALIGN_86 struct _RTL_BALANCED_NODE_32 +{ + union + { + DWORD Children[2]; + struct + { + DWORD Left; + DWORD Right; + }; + }; + + union + { + UCHAR Red : 1; + UCHAR Balance : 2; + DWORD ParentValue; + }; +} RTL_BALANCED_NODE_32, * PRTL_BALANCED_NODE_32; + +typedef ALIGN_86 struct _SINGLE_LIST_ENTRY_32 +{ + DWORD Next; // -> SINGLE_LIST_ENTRY_32 +} SINGLE_LIST_ENTRY_32, * PSINGLE_LIST_ENTRY_32; + +typedef ALIGN_86 struct _LDR_SERVICE_TAG_RECORD_32 +{ + DWORD Next; // -> LDR_SERVICE_TAG_RECORD_32 + ULONG ServiceTag; +} LDR_SERVICE_TAG_RECORD_32, * PLDR_SERVICE_TAG_RECORD_32; + +typedef ALIGN_86 struct _LDRP_CSLIST_32 +{ + DWORD Tail; // -> SINGLE_LIST_ENTRY_32 +} LDRP_CSLIST_32, * PLDRP_CSLIST_32; + +typedef ALIGN_86 struct _RTL_CRITICAL_SECTION_32 +{ + DWORD DebugInfo; // -> RTL_CRITICAL_SECTION_DEBUG_32 + LONG LockCount; + LONG RecursionCount; + DWORD OwningThread; + DWORD LockSemaphore; + DWORD SpinCount; +} RTL_CRITICAL_SECTION_32, * PRTL_CRITICAL_SECTION_32; + +typedef ALIGN_86 struct _RTL_CRITICAL_SECTION_DEBUG_32 +{ + WORD Type; + WORD CreatorBackTraceIndex; + DWORD CriticalSection; // -> RTL_CRITICAL_SECTION_32 + LIST_ENTRY32 ProcessLocksList; + DWORD EntryCount; + DWORD ContentionCount; + DWORD Flags; + WORD CreatorBackTraceIndexHigh; + WORD SpareWORD; +} RTL_CRITICAL_SECTION_DEBUG_32, * PRTL_CRITICAL_SECTION_DEBUG_32, _RTL_RESOURCE_DEBUG_32, RTL_RESOURCE_DEBUG_32, * PRTL_RESOURCE_DEBUG_32; + +typedef ALIGN_86 struct _PEB_LDR_DATA_32 +{ + ULONG Length; + BYTE Initialized; + DWORD SsHandle; + LIST_ENTRY32 InLoadOrderModuleListHead; + LIST_ENTRY32 InMemoryOrderModuleListHead; + LIST_ENTRY32 InInitializationOrderModuleListHead; + DWORD EntryInProgress; + BYTE ShutdownInProgress; + DWORD ShutdownThreadId; +} PEB_LDR_DATA_32, * PPEB_LDR_DATA_32; + +typedef struct _PEB_32 +{ + BOOLEAN InheritedAddressSpace; + BOOLEAN ReadImageFileExecOptions; + BOOLEAN BeingDebugged; + + union + { + UCHAR BitField; + struct + { + UCHAR ImageUsedLargePages : 1; + UCHAR IsProtectedProcess : 1; + UCHAR IsImageDynamicallyRelocated : 1; + UCHAR SkipPatchingUser32Forwarders : 1; + UCHAR IsPackagedProcess : 1; + UCHAR IsAppContainer : 1; + UCHAR IsProtectedProcessLight : 1; + UCHAR IsLongPathAwareProcess : 1; + }; + }; + + DWORD Mutant; + + DWORD ImageBaseAddress; + DWORD Ldr; // -> PEB_LDR_DATA_32 + + DWORD ProcessParameters; + DWORD SubSystemData; + DWORD ProcessHeap; + DWORD FastPebLock; // -> RTL_CRITICAL_SECTION_32 + DWORD AtlThunkSListPtr; + DWORD IFEOKey; + + union + { + ULONG CrossProcessFlags; + struct + { + ULONG ProcessInJob : 1; + ULONG ProcessInitializing : 1; + ULONG ProcessUsingVEH : 1; + ULONG ProcessUsingVCH : 1; + ULONG ProcessUsingFTH : 1; + ULONG ProcessPreviouslyThrottled : 1; + ULONG ProcessCurrentlyThrottled : 1; + ULONG ProcessImagesHotPatched : 1; + ULONG ReservedBits0 : 24; + }; + }; + + union + { + DWORD KernelCallbackTable; + DWORD UserSharedInfoPtr; + }; + + ULONG SystemReserved; + ULONG AtlThunkSListPtr32; + DWORD ApiSetMap; + ULONG TlsExpansionCounter; + + DWORD TlsBitmap; + ULONG TlsBitmapBits[2]; + DWORD ReadOnlySharedMemoryBase; + + union + { + DWORD HotpatchInformation; // till Win8 + DWORD SparePvoid0; // Win8.1 -> Win10 (1607) + DWORD SharedData; // Win10 (1703) + + }; + + DWORD ReadOnlyStaticServerData; + DWORD AnsiCodePageData; + DWORD OemCodePageData; + DWORD UnicodeCaseTableData; + ULONG NumberOfProcessors; + ULONG NtGlobalFlag; + LARGE_INTEGER CriticalSectionTimeout; + DWORD HeapSegmentReserve; + DWORD HeapSegmentCommit; + DWORD HeapDeCommitTotalFreeThreshold; + DWORD HeapDeCommitFreeBlockThreshold; + ULONG NumberOfHeaps; + ULONG MaximumNumberOfHeaps; + DWORD ProcessHeaps; + DWORD GdiSharedHandleTable; + DWORD ProcessStarterHelper; + ULONG GdiDCAttributeList; + + DWORD LoaderLock; // -> RTL_CRITICAL_SECTION_32 + ULONG OSMajorVersion; + ULONG OSMinorVersion; + USHORT OSBuildNumber; + USHORT OSCSDVersion; +} PEB_32, * PPEB_32; + +typedef ALIGN_86 struct _LDRP_UNICODE_STRING_BUNDLE_32 +{ + UNICODE_STRING_32 String; + WCHAR StaticBuffer[128]; +} LDRP_UNICODE_STRING_BUNDLE_32, * PLDRP_UNICODE_STRING_BUNDLE_32; + +typedef ALIGN_86 struct _LDRP_PATH_SEARCH_CONTEXT_32 //dummy structure, needs to be at least 0x50 bytes in size, members don't matter +{ + DWORD DllSearchPathOut; // wchar_t * + DWORD unknown_0[3]; + DWORD OriginalFullDllName; // wchar_t * + DWORD unknown_1[15]; +} LDRP_PATH_SEARCH_CONTEXT_32, * PLDRP_PATH_SEARCH_CONTEXT_32; + +typedef ALIGN_86 struct _RTL_INVERTED_FUNCTION_TABLE_ENTRY_32 +{ + DWORD ExceptionDirectory; // -> IMAGE_RUNTIME_FUNCTION_ENTRY + DWORD ImageBase; + ULONG ImageSize; + ULONG ExceptionDirectorySize; +} RTL_INVERTED_FUNCTION_TABLE_ENTRY_32, * PRTL_INVERTED_FUNCTION_TABLE_ENTRY_32; + +typedef ALIGN_86 struct _RTL_INVERTED_FUNCTION_TABLE_32 +{ + ULONG Count; + ULONG MaxCount; + ULONG Epoch; + UCHAR Overflow; + RTL_INVERTED_FUNCTION_TABLE_ENTRY_32 Entries[ANYSIZE_ARRAY]; +} RTL_INVERTED_FUNCTION_TABLE_32, * PRTL_INVERTED_FUNCTION_TABLE_32; + +typedef ALIGN_86 union _LDRP_PATH_SEARCH_OPTIONS_32 +{ + ULONG32 Flags; + + struct + { + ULONG32 Unknown; + }; +} LDRP_PATH_SEARCH_OPTIONS_32, * PLDRP_PATH_SEARCH_OPTIONS_32; + +typedef ALIGN_86 union _LDRP_LOAD_CONTEXT_FLAGS_32 +{ + ULONG32 Flags; + struct + { + ULONG32 Redirected : 1; + ULONG32 BaseNameOnly : 1; + ULONG32 HasFullPath : 1; + ULONG32 KnownDll : 1; + ULONG32 SystemImage : 1; + ULONG32 ExecutableImage : 1; + ULONG32 AppContainerImage : 1; + ULONG32 CallInit : 1; + ULONG32 UserAllocated : 1; + ULONG32 SearchOnlyFirstPathSegment : 1; + ULONG32 RedirectedByAPISet : 1; + }; +} LDRP_LOAD_CONTEXT_FLAGS_32, * PLDRP_LOAD_CONTEXT_FLAGS_32; + +#endif \ No newline at end of file diff --git a/GH Injector Library/NT Funcs.h b/GH Injector Library/NT Funcs.h new file mode 100644 index 0000000..ec96e5c --- /dev/null +++ b/GH Injector Library/NT Funcs.h @@ -0,0 +1,417 @@ +#pragma once + +//I honestly can't give proper credit here as most of the stuff is stolen from somewhere ages ago +//Sources I definitely stole from: +//https://www.geoffchappell.com +//https://github.com/DarthTon +//https://github.com/reactos +//Bill Gates + +#include "Win7.h" +#include "Win8.h" +#include "Win81.h" +#include "Win10.h" +#include "Win11.h" + +#define DEF_STRUCT_DEFAULT(name, suffix) \ +using name = name##suffix; \ +using P##name = P##name##suffix; \ +using _##name = _##name##suffix; + +#define DEF_STRUCT_DEFAULT_32(name, suffix) \ +using name##_32 = name##suffix##_32; \ +using P##name##_32 = P##name##suffix##_32; \ +using _##name##_32 = _##name##suffix##_32; + +#ifndef _WIN32_WINNT + #error Not supported +#else + #if(_WIN32_WINNT == _WIN32_WINNT_WIN7) + DEF_STRUCT_DEFAULT(LDR_DATA_TABLE_ENTRY, _WIN7) + DEF_STRUCT_DEFAULT(LDR_DDAG_NODE, _WIN7) + + #ifdef _WIN64 + DEF_STRUCT_DEFAULT_32(LDR_DATA_TABLE_ENTRY, _WIN7) + DEF_STRUCT_DEFAULT_32(LDR_DDAG_NODE, _WIN7) + #endif + #elif (_WIN32_WINNT == _WIN32_WINNT_WIN8) + DEF_STRUCT_DEFAULT(LDR_DATA_TABLE_ENTRY, _WIN8) + DEF_STRUCT_DEFAULT(LDR_DDAG_NODE, _WIN8) + + #ifdef _WIN64 + DEF_STRUCT_DEFAULT_32(LDR_DATA_TABLE_ENTRY, _WIN8) + DEF_STRUCT_DEFAULT_32(LDR_DDAG_NODE, _WIN8) + #endif + #elif (_WIN32_WINNT == _WIN32_WINNT_WINBLUE) + DEF_STRUCT_DEFAULT(LDR_DATA_TABLE_ENTRY, _WIN81) + DEF_STRUCT_DEFAULT(LDR_DDAG_NODE, _WIN81) + + #ifdef _WIN64 + DEF_STRUCT_DEFAULT_32(LDR_DATA_TABLE_ENTRY, _WIN81) + DEF_STRUCT_DEFAULT_32(LDR_DDAG_NODE, _WIN81) + #endif + #elif (_WIN32_WINNT == _WIN32_WINNT_WIN10) + #if(WDK_NTDDI_VERSION == 0x0A00000B) + DEF_STRUCT_DEFAULT(LDR_DATA_TABLE_ENTRY, _WIN11) + DEF_STRUCT_DEFAULT(LDR_DDAG_NODE, _WIN11) + + #ifdef _WIN64 + DEF_STRUCT_DEFAULT_32(LDR_DATA_TABLE_ENTRY, _WIN11) + DEF_STRUCT_DEFAULT_32(LDR_DDAG_NODE, _WIN11) + #endif + #else + DEF_STRUCT_DEFAULT(LDR_DATA_TABLE_ENTRY, _WIN10) + DEF_STRUCT_DEFAULT(LDR_DDAG_NODE, _WIN10) + + #ifdef _WIN64 + DEF_STRUCT_DEFAULT_32(LDR_DATA_TABLE_ENTRY, _WIN10) + DEF_STRUCT_DEFAULT_32(LDR_DDAG_NODE, _WIN10) + #endif + #endif + #else + #error Not supported + #endif +#endif + +#pragma region function prototypes + +using f_NtCreateThreadEx = NTSTATUS (__stdcall *) +( + HANDLE * pHandle, + ACCESS_MASK DesiredAccess, + void * pAttr, + HANDLE hTargetProc, + void * pFunc, + void * pArg, + ULONG Flags, + SIZE_T ZeroBits, + SIZE_T StackSize, + SIZE_T MaxStackSize, + void * pAttrListOut +); + +using f_LdrLoadDll = NTSTATUS (__stdcall *) +( + LDR_SEARCH_PATH ldrSearchPath, + ULONG * pFlags, + UNICODE_STRING * pModuleFileName, + HANDLE * pOut +); + +using f_LdrUnloadDll = NTSTATUS (__stdcall *) +( + HANDLE DllHandle +); + +//1507-1803 +using f_LdrpLoadDll_1507 = NTSTATUS (__fastcall *) +( + UNICODE_STRING * dll_path, + LDRP_PATH_SEARCH_CONTEXT * search_path, + LDRP_LOAD_CONTEXT_FLAGS Flags, + BOOLEAN bUnknown, //set to TRUE + LDR_DATA_TABLE_ENTRY ** ldr_out +); + +//1809+ +using f_LdrpLoadDll = NTSTATUS (__fastcall *) +( + UNICODE_STRING * dll_path, + LDRP_PATH_SEARCH_CONTEXT * search_path, + LDRP_LOAD_CONTEXT_FLAGS Flags, + LDR_DATA_TABLE_ENTRY ** ldr_out +); + +using f_LdrpLoadDllInternal = NTSTATUS (__fastcall *) +( + UNICODE_STRING * dll_path, + LDRP_PATH_SEARCH_CONTEXT * search_path, + LDRP_LOAD_CONTEXT_FLAGS Flags, + ULONG32 Unknown0, //set to 4 + LDR_DATA_TABLE_ENTRY * Unknown1, //set to nullptr + LDR_DATA_TABLE_ENTRY * Unknown2, //set to nullptr + LDR_DATA_TABLE_ENTRY ** ldr_out, + ULONG_PTR * Unknown3 //set to pointer to nullptr +); + +using f_LdrpLoadDllInternal_21H2 = NTSTATUS (__fastcall *) +( + UNICODE_STRING * dll_path, + LDRP_PATH_SEARCH_CONTEXT * search_path, + LDRP_LOAD_CONTEXT_FLAGS Flags, + ULONG32 Unknown0, //set to 4 + LDR_DATA_TABLE_ENTRY_WIN11 * Unknown1, //set to nullptr + LDR_DATA_TABLE_ENTRY_WIN11 * Unknown2, //set to nullptr + LDR_DATA_TABLE_ENTRY_WIN11 ** ldr_out, + ULONG_PTR * Unknown3, //set to pointer to nullptr + ULONG Unknown4 //set to 0 +); + +using f_LdrGetDllHandleEx = NTSTATUS (__stdcall *) +( + ULONG Flags, + PWSTR OptDllPath, + PULONG OptDllCharacteristics, + UNICODE_STRING * DllName, + PVOID * DllHandle +); + +using f_LdrGetProcedureAddress = NTSTATUS (__stdcall *) +( + PVOID BaseAddress, + ANSI_STRING * Name, + ULONG Ordinal, + PVOID * ProcedureAddress +); + +using f_NtQueryInformationProcess = NTSTATUS (__stdcall *) +( + HANDLE hTargetProc, + PROCESSINFOCLASS PIC, + void * pBuffer, + ULONG BufferSize, + ULONG * SizeOut +); + +using f_NtQuerySystemInformation = NTSTATUS (__stdcall *) +( + SYSTEM_INFORMATION_CLASS SIC, + void * pBuffer, + ULONG BufferSize, + ULONG * SizeOut +); + +using f_NtQueryInformationThread = NTSTATUS (__stdcall *) +( + HANDLE hThread, + THREADINFOCLASS TIC, + void * pBuffer, + ULONG BufferSize, + ULONG * SizeOut +); + +using f_RtlQueueApcWow64Thread = NTSTATUS (__stdcall *) +( + HANDLE hThread, + void * pRoutine, + void * pArg1, + void * pArg2, + void * pArg3 +); + +using f_LdrpPreprocessDllName = NTSTATUS (__fastcall *) +( + UNICODE_STRING * DllName, + LDRP_UNICODE_STRING_BUNDLE * OutputDllName, + LDR_DATA_TABLE_ENTRY * pOptParentEntry, + LDRP_LOAD_CONTEXT_FLAGS * LoadContextFlags +); + +using f_RtlInsertInvertedFunctionTable = BOOL (__fastcall *) +( + void * ImageBase, + DWORD SizeOfImage +); + +#ifdef _WIN64 +using f_RtlAddFunctionTable = BOOL (__stdcall *) +( + RUNTIME_FUNCTION * FunctionTable, + DWORD EntryCount, + DWORD64 BaseAddress +); +#endif + +using f_LdrpHandleTlsData = NTSTATUS (__fastcall *) +( + LDR_DATA_TABLE_ENTRY * pEntry +); + +using f_LdrLockLoaderLock = NTSTATUS (__stdcall *) +( + ULONG Flags, + ULONG * State, + ULONG_PTR * Cookie +); + +using f_LdrUnlockLoaderLock = NTSTATUS (__stdcall *) +( + ULONG Flags, + ULONG_PTR Cookie +); + +using f_memmove = VOID (__cdecl *) +( + PVOID UNALIGNED Destination, + LPCVOID UNALIGNED Source, + SIZE_T Length +); + +using f_RtlZeroMemory = VOID (__stdcall *) +( + PVOID UNALIGNED Destination, + SIZE_T Length +); + +using f_RtlAllocateHeap = PVOID (__stdcall *) +( + PVOID HeapHandle, + ULONG Flags, + SIZE_T Size +); + +using f_RtlFreeHeap = BOOLEAN (__stdcall *) +( + PVOID HeapHandle, + ULONG Flags, + PVOID BaseAddress +); + +using f_RtlAnsiStringToUnicodeString = NTSTATUS (__stdcall *) +( + UNICODE_STRING * DestinationString, + ANSI_STRING * SourceString, + BOOLEAN AllocateDestinationString +); + +using f_RtlRbInsertNodeEx = VOID (__stdcall *) +( + RTL_RB_TREE * Tree, + RTL_BALANCED_NODE * Parent, + BOOLEAN Right, + RTL_BALANCED_NODE * Node +); + +using f_RtlRbRemoveNode = VOID (__stdcall *) +( + RTL_RB_TREE * pTree, + RTL_BALANCED_NODE * pNode +); + +using f_NtOpenFile = NTSTATUS (__stdcall *) +( + HANDLE * hFileOut, + ACCESS_MASK DesiredAccess, + OBJECT_ATTRIBUTES * pAtrributes, + IO_STATUS_BLOCK * pIoStatusBlock, + ULONG ShareAccess, + ULONG OpenOptions +); + +using f_NtReadFile = NTSTATUS (__stdcall *) +( + HANDLE FileHandle, + HANDLE hOptEvent, + PVOID pOptApc, + PVOID pOptApcContext, + IO_STATUS_BLOCK * IoStatusBlock, + PVOID Buffer, + ULONG Length, + LARGE_INTEGER * pOptByteOffset, + ULONG * pOptKey +); + +using f_NtSetInformationFile = NTSTATUS (__stdcall *) +( + HANDLE FileHandle, + IO_STATUS_BLOCK * IoStatusBlock, + PVOID FileInformation, + ULONG Length, + FILE_INFORMATION_CLASS FileInformationClass +); + +using f_NtQueryInformationFile = NTSTATUS (__stdcall *) +( + HANDLE FileHandle, + IO_STATUS_BLOCK * pIoStatusBlock, + PVOID FileInformation, + ULONG Length, + FILE_INFORMATION_CLASS FileInformationClass +); + +using f_NtClose = NTSTATUS (__stdcall *) +( + HANDLE Handle +); + +using f_NtAllocateVirtualMemory = NTSTATUS (__stdcall *) +( + HANDLE ProcessHandle, + PVOID * BaseAddress, + ULONG_PTR ZeroBits, + SIZE_T * RegionSize, + ULONG AllocationType, + ULONG Protect +); + +using f_NtFreeVirtualMemory = NTSTATUS (__stdcall *) +( + HANDLE ProcessHandle, + PVOID * BaseAddress, + SIZE_T * RegionSize, + ULONG FreeType +); + +using f_NtProtectVirtualMemory = NTSTATUS (__stdcall *) +( + HANDLE ProcessHandle, + PVOID * BaseAddress, + SIZE_T * Size, + ULONG NewAccess, + ULONG * OldAccess +); + +using f_NtCreateSection = NTSTATUS (__stdcall *) +( + HANDLE * SectionHandle, + ACCESS_MASK DesiredAccess, + OBJECT_ATTRIBUTES * ObjectAttributes, + LARGE_INTEGER * MaximumSize, + ULONG SectionPageProtection, + ULONG AllocationAttributes, + HANDLE FileHandle +); + +using f_NtMapViewOfSection = NTSTATUS (__stdcall *) +( + HANDLE SectionHandle, + HANDLE ProcessHandle, + PVOID * BaseAddress, + ULONG_PTR ZeroBits, + SIZE_T CommitSize, + LARGE_INTEGER * SectionOffset, + SIZE_T * ViewSize, + SECTION_INHERIT InheritDisposition, + ULONG AllocationType, + ULONG Win32Protect +); + +using f_LdrProtectMrdata = NTSTATUS (__stdcall *) +( + BOOL bProtected +); + +using f_RtlAddVectoredExceptionHandler = PVOID (__stdcall *) +( + ULONG FirstHandler, + PVECTORED_EXCEPTION_HANDLER VectoredHandler +); + +using f_RtlRemoveVectoredExceptionHandler = ULONG (__stdcall *) +( + PVOID Handle +); + +using f_LdrpModuleBaseAddressIndex = RTL_RB_TREE *; +using f_LdrpMappingInfoIndex = RTL_RB_TREE *; +using f_LdrpHeap = PVOID *; +using f_LdrpInvertedFunctionTable = RTL_INVERTED_FUNCTION_TABLE *; +using f_LdrpDefaultPath = UNICODE_STRING *; + +#pragma endregion + +inline HINSTANCE g_hNTDLL; + +#ifdef _WIN64 +inline HINSTANCE g_hNTDLL_WOW64; +#endif \ No newline at end of file diff --git a/GH Injector Library/NT Stuff.h b/GH Injector Library/NT Stuff.h deleted file mode 100644 index 8fbedeb..0000000 --- a/GH Injector Library/NT Stuff.h +++ /dev/null @@ -1,904 +0,0 @@ -#pragma once - -//I honestly can't give proper credit here as most of the stuff is stolen from somewhere ages ago -//Sources I definitely stole from: -//https://www.geoffchappell.com -//https://github.com/DarthTon -//https://github.com/reactos -//Bill Gates - -#include "pch.h" - -#pragma region nt (un)defines - -#ifndef NT_FAIL - #define NT_FAIL(status) (status < 0) -#endif - -#ifndef NT_SUCCESS - #define NT_SUCCESS(status) (status >= 0) -#endif - -#ifdef memmove -#undef memmove -#endif - -#ifdef RtlZeroMemory -#undef RtlZeroMemory -#endif - -#define THREAD_CREATE_FLAGS_CREATE_SUSPENDED 0x00000001 -#define THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER 0x00000004 - -#define OBJ_CASE_INSENSITIVE 0x00000040 - -#define STATUS_SUCCESS 0x00000000 -#define STATUS_INFO_LENGTH_MISMATCH 0xC0000004 - -#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020 - -typedef LONG KPRIORITY; - -#pragma endregion - -#pragma region enums - -typedef enum class _PROCESSINFOCLASS -{ - ProcessBasicInformation = 0, - ProcessSessionInformation = 24, - ProcessWow64Information = 26, - ProcessProtectionInformation = 61 -} PROCESSINFOCLASS; - -typedef enum class _SYSTEM_INFORMATION_CLASS -{ - SystemProcessInformation = 5, - SystemHandleInformation = 16 -} SYSTEM_INFORMATION_CLASS; - -typedef enum class _THREADINFOCLASS -{ - ThreadBasicInformation = 0, - ThreadQuerySetWin32StartAddress = 9 -} THREADINFOCLASS; - -typedef enum class _THREAD_STATE -{ - Running = 0x02, - Waiting = 0x05 -} THREAD_STATE; - -typedef enum class _KWAIT_REASON -{ - WrQueue = 0x0F -} KWAIT_REASON; - -typedef enum class _OBEJECT_TYPE_NUMBER -{ - Process = 0x07 -} OBJECT_TYPE_NUMBER; - -enum class LDR_DDAG_STATE -{ - LdrModulesReadyToRun = 9 -}; - -typedef enum _FILE_INFORMATION_CLASS -{ - FileStandardInformation = 5, - FilePositionInformation = 14 -} FILE_INFORMATION_CLASS, * PFILE_INFORMATION_CLASS; - -#pragma endregion - -#pragma region structs - -typedef struct _ANSI_STRING -{ - USHORT Length; - USHORT MaxLength; - char * szBuffer; -} ANSI_STRING, * PANSI_STRING; - -typedef struct _UNICODE_STRING -{ - WORD Length; - WORD MaxLength; - wchar_t * szBuffer; -} UNICODE_STRING, * PUNICODE_STRING; - -typedef struct _LDRP_UNICODE_STRING_BUNDLE -{ - UNICODE_STRING String; - WCHAR StaticBuffer[128]; -} LDRP_UNICODE_STRING_BUNDLE, * PLDRP_UNICODE_STRING_BUNDLE; - -typedef struct _RTL_BALANCED_NODE -{ - union - { - struct _RTL_BALANCED_NODE * Children[2]; - struct - { - struct _RTL_BALANCED_NODE * Left; - struct _RTL_BALANCED_NODE * Right; - }; - }; - - union - { - UCHAR Red : 1; - UCHAR Balance : 2; - ULONG_PTR ParentValue; - }; -} RTL_BALANCED_NODE, * PRTL_BALANCED_NODE; - -typedef struct _RTL_RB_TREE -{ - RTL_BALANCED_NODE * Root; - RTL_BALANCED_NODE * Min; -} RTL_RB_TREE, * PRTL_RB_TREE; - -typedef struct _LDR_SERVICE_TAG_RECORD -{ - struct _LDR_SERVICE_TAG_RECORD * Next; - ULONG ServiceTag; -} LDR_SERVICE_TAG_RECORD, * PLDR_SERVICE_TAG_RECORD; - -typedef struct _LDRP_CSLIST -{ - struct _SINGLE_LIST_ENTRY * Tail; -} LDRP_CSLIST, * PLDRP_CSLIST; - -typedef struct _LDR_DDAG_NODE -{ - LIST_ENTRY Modules; - PLDR_SERVICE_TAG_RECORD ServiceTagList; - ULONG LoadCount; - ULONG LoadWhileUnloadingCount; - ULONG LowestLink; - PLDRP_CSLIST Dependencies; - PLDRP_CSLIST IncomingDependencies; - LDR_DDAG_STATE State; - SINGLE_LIST_ENTRY CondenseLink; - ULONG PreorderNumber; -} LDR_DDAG_NODE, * PLDR_DDAG_NODE; - -typedef struct _LDR_DATA_TABLE_ENTRY -{ - LIST_ENTRY InLoadOrderLinks; - LIST_ENTRY InMemoryOrderLinks; - union - { - LIST_ENTRY InInitializationOrderLinks; - LIST_ENTRY InProgressLinks; - }; - - PVOID DllBase; - PVOID EntryPoint; - ULONG SizeOfImage; - - UNICODE_STRING FullDllName; - UNICODE_STRING BaseDllName; - - ULONG Flags; - WORD ObsoleteLoadCount; - WORD TlsIndex; - - LIST_ENTRY HashLinks; - - ULONG TimedateStamp; - PVOID EntryPointActivationContext; - PVOID Lock; - - LDR_DDAG_NODE * DdagNode; - - LIST_ENTRY NodeModuleLink; - PVOID LoadContext; - PVOID ParentDllBase; - PVOID SwitchBackContext; - - RTL_BALANCED_NODE BaseAddressIndexNode; - RTL_BALANCED_NODE MappingInfoIndexNode; - - ULONG_PTR OriginalBase; - LARGE_INTEGER LoadTime; - ULONG BaseNameHashValue; - ULONG LoadReason; - - ULONG ImplicitPathOptions; - ULONG ReferenceCount; - ULONG DependentLoadFlags; - UCHAR SigningLevel; -} LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY; - -typedef struct _PEB_LDR_DATA -{ - ULONG Length; - BYTE Initialized; - HANDLE SsHandle; - LIST_ENTRY InLoadOrderModuleListHead; - LIST_ENTRY InMemoryOrderModuleListHead; - LIST_ENTRY InInitializationOrderModuleListHead; - void * EntryInProgress; - BYTE ShutdownInProgress; - HANDLE ShutdownThreadId; -} PEB_LDR_DATA, * PPEB_LDR_DATA; - -struct PEB -{ - BOOLEAN InheritedAddressSpace; - BOOLEAN ReadImageFileExecOptions; - BOOLEAN BeingDebugged; - - union - { - UCHAR BitField; - struct - { - UCHAR ImageUsedLargePages : 1; - UCHAR IsProtectedProcess : 1; - UCHAR IsImageDynamicallyRelocated : 1; - UCHAR SkipPatchingUser32Forwarders : 1; - UCHAR IsPackagedProcess : 1; - UCHAR IsAppContainer : 1; - UCHAR IsProtectedProcessLight : 1; - UCHAR IsLongPathAwareProcess : 1; - }; - }; - - HANDLE Mutant; - - PVOID ImageBaseAddress; - PEB_LDR_DATA * Ldr; - - PVOID * ProcessParameters; - PVOID SubSystemData; - HANDLE ProcessHeap; - RTL_CRITICAL_SECTION * FastPebLock; - PVOID AtlThunkSListPtr; - PVOID IFEOKey; - - union - { - ULONG CrossProcessFlags; - struct - { - ULONG ProcessInJob : 1; - ULONG ProcessInitializing : 1; - ULONG ProcessUsingVEH : 1; - ULONG ProcessUsingVCH : 1; - ULONG ProcessUsingFTH : 1; - ULONG ProcessPreviouslyThrottled : 1; - ULONG ProcessCurrentlyThrottled : 1; - ULONG ProcessImagesHotPatched : 1; - ULONG ReservedBits0 : 24; - }; - }; - - union - { - PVOID KernelCallbackTable; - PVOID UserSharedInfoPtr; - }; -}; - -typedef struct _RTL_INVERTED_FUNCTION_TABLE_ENTRY -{ - IMAGE_RUNTIME_FUNCTION_ENTRY * ExceptionDirectory; - PVOID ImageBase; - ULONG ImageSize; - ULONG ExceptionDirectorySize; -} RTL_INVERTED_FUNCTION_TABLE_ENTRY, * PRTL_INVERTED_FUNCTION_TABLE_ENTRY; - -//based on darthtons stuff -//https://github.com/DarthTon/Blackbone/blob/231f1747161cce6944589c4a748c4d0a71340fbd/src/BlackBone/Include/Win8Specific.h#L57 -typedef struct _RTL_INVERTED_FUNCTION_TABLE -{ - ULONG Count; - ULONG MaxCount; - ULONG Epoch; - UCHAR Overflow; - RTL_INVERTED_FUNCTION_TABLE_ENTRY Entries[ANYSIZE_ARRAY]; -} RTL_INVERTED_FUNCTION_TABLE, * PRTL_INVERTED_FUNCTION_TABLE; - -typedef struct _CLIENT_ID -{ - HANDLE UniqueProcess; - HANDLE UniqueThread; -} CLIENT_ID, *PCLIENT_ID; - -typedef struct _PROCESS_BASIC_INFORMATION -{ - NTSTATUS ExitStatus; - PEB * pPEB; - ULONG_PTR AffinityMask; - LONG BasePriority; - HANDLE UniqueProcessId; - HANDLE InheritedFromUniqueProcessId; -} PROCESS_BASIC_INFORMATION, * PPROCESS_BASIC_INFORMATION; - -typedef struct _PROCESS_SESSION_INFORMATION -{ - ULONG SessionId; -} PROCESS_SESSION_INFORMATION, * PPROCESS_SESSION_INFORMATION; - -typedef struct _THREAD_BASIC_INFORMATION -{ - NTSTATUS ExitStatus; - PVOID TebBaseAddress; - CLIENT_ID ClientId; - KAFFINITY AffinityMask; - KPRIORITY Priority; - KPRIORITY BasePriority; -} THREAD_BASIC_INFORMATION, * PTHREAD_BASIC_INFORMATION; - -typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO -{ - WORD UniqueProcessId; - WORD CreateBackTraceIndex; - BYTE ObjectTypeIndex; - BYTE HandleAttributes; - WORD HandleValue; - void * Object; - ULONG GrantedAccess; -} SYSTEM_HANDLE_TABLE_ENTRY_INFO, * PSYSTEM_HANDLE_TABLE_ENTRY_INFO; - -typedef struct _SYSTEM_HANDLE_INFORMATION -{ - ULONG NumberOfHandles; - SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[1]; -} SYSTEM_HANDLE_INFORMATION, * PSYSTEM_HANDLE_INFORMATION; - -typedef struct _SYSTEM_THREAD_INFORMATION -{ - LARGE_INTEGER KernelTime; - LARGE_INTEGER UserTime; - LARGE_INTEGER CreateTime; - ULONG WaitTime; - PVOID StartAddress; - CLIENT_ID ClientId; - KPRIORITY Priority; - LONG BasePriority; - ULONG ContextSwitches; - THREAD_STATE ThreadState; - KWAIT_REASON WaitReason; -} SYSTEM_THREAD_INFORMATION, * PSYSTEM_THREAD_INFORMATION; - -typedef struct _SYSTEM_PROCESS_INFORMATION -{ - ULONG NextEntryOffset; - ULONG NumberOfThreads; - LARGE_INTEGER WorkingSetPrivateSize; - ULONG HardFaultCount; - ULONG NumberOfThreadsHighWatermark; - ULONGLONG CycleTime; - LARGE_INTEGER CreateTime; - LARGE_INTEGER UserTime; - LARGE_INTEGER KernelTime; - UNICODE_STRING ImageName; - KPRIORITY BasePriority; - HANDLE UniqueProcessId; - HANDLE InheritedFromUniqueProcessId; - ULONG HandleCount; - ULONG SessionId; - ULONG_PTR UniqueProcessKey; - SIZE_T PeakVirtualSize; - SIZE_T VirtualSize; - ULONG PageFaultCount; - SIZE_T PeakWorkingSetSize; - SIZE_T WorkingSetSize; - SIZE_T QuotaPeakPagedPoolUsage; - SIZE_T QuotaPagedPoolUsage; - SIZE_T QuotaPeakNonPagedPoolUsage; - SIZE_T QuotaNonPagedPoolUsage; - SIZE_T PagefileUsage; - SIZE_T PeakPagefileUsage; - SIZE_T PrivatePageCount; - LARGE_INTEGER ReadOperationCount; - LARGE_INTEGER WriteOperationCount; - LARGE_INTEGER OtherOperationCount; - LARGE_INTEGER ReadTransferCount; - LARGE_INTEGER WriteTransferCount; - LARGE_INTEGER OtherTransferCount; - SYSTEM_THREAD_INFORMATION Threads[1]; -} SYSTEM_PROCESS_INFORMATION, * PSYSTEM_PROCESS_INFORMATION; - -typedef struct _FILE_STANDARD_INFORMATION -{ - LARGE_INTEGER AllocationSize; - LARGE_INTEGER EndOfFile; - ULONG NumberOfLinks; - BOOLEAN DeletePending; - BOOLEAN Directory; -} FILE_STANDARD_INFORMATION, * PFILE_STANDARD_INFORMATION; - -typedef struct _FILE_POSITION_INFORMATION -{ - LARGE_INTEGER CurrentByteOffset; -} FILE_POSITION_INFORMATION, * PFILE_POSITION_INFORMATION; - -typedef union _LDRP_PATH_SEARCH_OPTIONS -{ - ULONG32 Flags; - - struct - { - ULONG32 Unknown; - }; -} LDRP_PATH_SEARCH_OPTIONS, * PLDRP_PATH_SEARCH_OPTIONS; - -typedef struct _LDRP_PATH_SEARCH_CONTEXT -{ - wchar_t * DllSearchPathOut; - void * unknown_0[3]; - wchar_t * OriginalFullDllName; -} LDRP_PATH_SEARCH_CONTEXT, * PLDRP_PATH_SEARCH_CONTEXT; - -typedef union _LDRP_LOAD_CONTEXT_FLAGS -{ - ULONG32 Flags; - struct - { - ULONG32 Redirected : 1; - ULONG32 BaseNameOnly : 1; - ULONG32 HasFullPath : 1; - ULONG32 KnownDll : 1; - ULONG32 SystemImage : 1; - ULONG32 ExecutableImage : 1; - ULONG32 AppContainerImage : 1; - ULONG32 CallInit : 1; - ULONG32 UserAllocated : 1; - ULONG32 SearchOnlyFirstPathSegment : 1; - ULONG32 RedirectedByAPISet : 1; - }; -} LDRP_LOAD_CONTEXT_FLAGS, * PLDRP_LOAD_CONTEXT_FLAGS; - -typedef struct _OBJECT_ATTRIBUTES -{ - ULONG Length; - HANDLE RootDirectory; - UNICODE_STRING * ObjectName; - ULONG Attributes; - PVOID SecurityDescriptor; - PVOID SecurityQualityOfService; -} OBJECT_ATTRIBUTES, * POBJECT_ATTRIBUTES; - -#define InitializeObjectAttributes(p, n, a, r, s) \ -{ \ - (p)->Length = sizeof(OBJECT_ATTRIBUTES); \ - (p)->RootDirectory = r; \ - (p)->Attributes = a; \ - (p)->ObjectName = n; \ - (p)->SecurityDescriptor = s; \ - (p)->SecurityQualityOfService = NULL; \ -} - -typedef struct _IO_STATUS_BLOCK -{ - union - { - NTSTATUS Status; - PVOID Pointer; - } DUMMYUNIONNAME; - - ULONG_PTR Information; -} IO_STATUS_BLOCK, * PIO_STATUS_BLOCK; - -#ifdef _WIN64 - -typedef ALIGN_86 struct _UNICODE_STRING32 -{ - WORD Length; - WORD MaxLength; - DWORD szBuffer; -} UNICODE_STRING32, * PUNICODE_STRING32; - -typedef ALIGN_86 struct _RTL_BALANCED_NODE32 -{ - union - { - DWORD Children[2]; - struct - { - DWORD Left; - DWORD Right; - }; - }; - - union - { - UCHAR Red : 1; - UCHAR Balance : 2; - DWORD ParentValue; - }; -} RTL_BALANCED_NODE32, * PRTL_BALANCED_NODE32; - -typedef ALIGN_86 struct _LARGE_INTEGER32 -{ - DWORD LowPart; - DWORD HighPart; -} LARGE_INTEGER32, * PLARGE_INTEGER32; - -typedef ALIGN_86 struct _LDR_DATA_TABLE_ENTRY32 -{ - LIST_ENTRY32 InLoadOrderLinks; - LIST_ENTRY32 InMemoryOrderLinks; - LIST_ENTRY32 InInitializationOrderLinks; - DWORD DllBase; - DWORD EntryPoint; - ULONG SizeOfImage; - UNICODE_STRING32 FullDllName; - UNICODE_STRING32 BaseDllName; - ULONG Flags; - WORD LoadCount; - WORD TlsIndex; - LIST_ENTRY32 HashLinks; - ULONG TimedateStamp; - DWORD EntryPointActivationContext; - DWORD Lock; - DWORD DdagNode; - LIST_ENTRY32 NodeModuleLink; - DWORD LoadContext; - DWORD ParentDllBase; - DWORD SwitchBackContext; - RTL_BALANCED_NODE32 BaseAddressIndexNode; - RTL_BALANCED_NODE32 MappingInfoIndexNode; - DWORD OriginalBase; - DWORD Buffer; - LARGE_INTEGER32 LoadTime; - ULONG BaseNameHashValue; - ULONG LoadReason; - ULONG ImplicitPathOptions; - ULONG ReferenceCount; - ULONG DependentLoadFlags; - UCHAR SigningLevel; -} LDR_DATA_TABLE_ENTRY32, * PLDR_DATA_TABLE_ENTRY32; - -typedef ALIGN_86 struct _PEB_LDR_DATA32 -{ - ULONG Length; - BYTE Initialized; - DWORD SsHandle; - LIST_ENTRY32 InLoadOrderModuleListHead; - LIST_ENTRY32 InMemoryOrderModuleListHead; - LIST_ENTRY32 InInitializationOrderModuleListHead; - DWORD EntryInProgress; - BYTE ShutdownInProgress; - DWORD ShutdownThreadId; -} PEB_LDR_DATA32, * PPEB_LDR_DATA32; - -typedef ALIGN_86 struct _PEB32 -{ - BOOLEAN InheritedAddressSpace; - BOOLEAN ReadImageFileExecOptions; - BOOLEAN BeingDebugged; - - union - { - UCHAR BitField; - struct - { - UCHAR ImageUsedLargePages : 1; - UCHAR IsProtectedProcess : 1; - UCHAR IsImageDynamicallyRelocated : 1; - UCHAR SkipPatchingUser32Forwarders : 1; - UCHAR IsPackagedProcess : 1; - UCHAR IsAppContainer : 1; - UCHAR IsProtectedProcessLight : 1; - UCHAR IsLongPathAwareProcess : 1; - }; - }; - - DWORD Mutant; - - DWORD ImageBaseAddress; - DWORD Ldr; - - DWORD ProcessParameters; - DWORD SubSystemData; - DWORD ProcessHeap; - DWORD FastPebLock; - DWORD AtlThunkSListPtr; - DWORD IFEOKey; - - union - { - ULONG CrossProcessFlags; - struct - { - ULONG ProcessInJob : 1; - ULONG ProcessInitializing : 1; - ULONG ProcessUsingVEH : 1; - ULONG ProcessUsingVCH : 1; - ULONG ProcessUsingFTH : 1; - ULONG ProcessPreviouslyThrottled : 1; - ULONG ProcessCurrentlyThrottled : 1; - ULONG ProcessImagesHotPatched : 1; - ULONG ReservedBits0 : 24; - }; - }; - - union - { - DWORD KernelCallbackTable; - DWORD UserSharedInfoPtr; - }; -} PEB32, * PPEB32; - -typedef ALIGN_86 struct _LDRP_UNICODE_STRING_BUNDLE32 -{ - UNICODE_STRING32 String; - WCHAR StaticBuffer[128]; -} LDRP_UNICODE_STRING_BUNDLE32, * PLDRP_UNICODE_STRING_BUNDLE32; - -typedef ALIGN_86 struct _LDRP_PATH_SEARCH_CONTEXT32 -{ - DWORD DllSearchPathOut; - DWORD unknown_0[3]; - DWORD OriginalFullDllName; -} LDRP_PATH_SEARCH_CONTEXT32, * PLDRP_PATH_SEARCH_CONTEXT32; -#endif - -#pragma endregion - -#pragma region function prototypes - -using f_NtCreateThreadEx = NTSTATUS (__stdcall *) -( - HANDLE * pHandle, - ACCESS_MASK DesiredAccess, - void * pAttr, - HANDLE hTargetProc, - void * pFunc, - void * pArg, - ULONG Flags, - SIZE_T ZeroBits, - SIZE_T StackSize, - SIZE_T MaxStackSize, - void * pAttrListOut -); - -using f_LdrLoadDll = NTSTATUS (__stdcall *) -( - wchar_t * szOptPath, - ULONG ulFlags, - UNICODE_STRING * pModuleFileName, - HANDLE * pOut -); - -using f_LdrUnloadDll = NTSTATUS (__stdcall *) -( - HANDLE DllHandle -); - -using f_LdrpLoadDll = NTSTATUS (__fastcall *) -( - UNICODE_STRING * dll_path, - LDRP_PATH_SEARCH_CONTEXT * search_path, - LDRP_LOAD_CONTEXT_FLAGS Flags, - LDR_DATA_TABLE_ENTRY ** ldr_out -); - -using f_LdrpLoadDllInternal = NTSTATUS (__fastcall *) -( - UNICODE_STRING * dll_path, - LDRP_PATH_SEARCH_CONTEXT * search_path, - LDRP_LOAD_CONTEXT_FLAGS Flags, - ULONG32 Unknown0, //set to 4 - LDR_DATA_TABLE_ENTRY * Unknown1, //set to nullptr - LDR_DATA_TABLE_ENTRY * Unknown2, //set to nullptr - LDR_DATA_TABLE_ENTRY ** ldr_out, - ULONG_PTR * Unknown3 //set to pointer to nullptr -); - -using f_LdrGetDllHandleEx = NTSTATUS (__stdcall *) -( - ULONG Flags, - PWSTR OptDllPath, - PULONG OptDllCharacteristics, - UNICODE_STRING * DllName, - PVOID * DllHandle -); - -using f_LdrGetProcedureAddress = NTSTATUS (__stdcall *) -( - PVOID BaseAddress, - ANSI_STRING * Name, - ULONG Ordinal, - PVOID * ProcedureAddress -); - -using f_NtQueryInformationProcess = NTSTATUS (__stdcall *) -( - HANDLE hTargetProc, - PROCESSINFOCLASS PIC, - void * pBuffer, - ULONG BufferSize, - ULONG * SizeOut -); - -using f_NtQuerySystemInformation = NTSTATUS (__stdcall *) -( - SYSTEM_INFORMATION_CLASS SIC, - void * pBuffer, - ULONG BufferSize, - ULONG * SizeOut -); - -using f_NtQueryInformationThread = NTSTATUS (__stdcall *) -( - HANDLE hThread, - THREADINFOCLASS TIC, - void * pBuffer, - ULONG BufferSize, - ULONG * SizeOut -); - -using f_RtlQueueApcWow64Thread = NTSTATUS (__stdcall *) -( - HANDLE hThread, - void * pRoutine, - void * pArg1, - void * pArg2, - void * pArg3 -); - -using f_LdrpPreprocessDllName = NTSTATUS (__fastcall *) -( - UNICODE_STRING * DllName, - LDRP_UNICODE_STRING_BUNDLE * OutputDllName, - LDR_DATA_TABLE_ENTRY * pOptParentEntry, - LDRP_LOAD_CONTEXT_FLAGS * LoadContextFlags -); - -using f_RtlInsertInvertedFunctionTable = BOOL (__fastcall *) -( - void * hDll, - DWORD SizeOfImage -); - -using f_LdrpHandleTlsData = NTSTATUS (__fastcall *) -( - LDR_DATA_TABLE_ENTRY * pEntry -); - -using f_LdrLockLoaderLock = NTSTATUS(__stdcall *) -( - ULONG Flags, - ULONG * State, - ULONG_PTR * Cookie -); - -using f_LdrUnlockLoaderLock = NTSTATUS(__stdcall *) -( - ULONG Flags, - ULONG_PTR Cookie -); - -using f_memmove = VOID (__cdecl *) -( - PVOID UNALIGNED Destination, - LPCVOID UNALIGNED Source, - SIZE_T Length -); - -using f_RtlZeroMemory = VOID (__stdcall *) -( - PVOID UNALIGNED Destination, - SIZE_T Length -); - -using f_RtlAllocateHeap = PVOID (__stdcall *) -( - PVOID HeapHandle, - ULONG Flags, - SIZE_T Size -); - -using f_RtlFreeHeap = BOOLEAN (__stdcall *) -( - PVOID HeapHandle, - ULONG Flags, - PVOID BaseAddress -); - -using f_RtlAnsiStringToUnicodeString = NTSTATUS (__stdcall *) -( - UNICODE_STRING * DestinationString, - ANSI_STRING * SourceString, - BOOLEAN AllocateDestinationString -); - -using f_RtlRbRemoveNode = VOID (__stdcall *) -( - RTL_RB_TREE * pTree, - RTL_BALANCED_NODE * pNode -); - -using f_NtOpenFile = NTSTATUS (__stdcall *) -( - HANDLE * hFileOut, - ACCESS_MASK DesiredAccess, - OBJECT_ATTRIBUTES * pAtrributes, - IO_STATUS_BLOCK * pIoStatusBlock, - ULONG ShareAccess, - ULONG OpenOptions -); - -using f_NtReadFile = NTSTATUS (__stdcall *) -( - HANDLE FileHandle, - HANDLE hOptEvent, - PVOID pOptApc, - PVOID pOptApcContext, - IO_STATUS_BLOCK * IoStatusBlock, - PVOID Buffer, - ULONG Length, - LARGE_INTEGER * pOptByteOffset, - ULONG * pOptKey -); - -using f_NtSetInformationFile = NTSTATUS (__stdcall *) -( - HANDLE FileHandle, - IO_STATUS_BLOCK * IoStatusBlock, - PVOID FileInformation, - ULONG Length, - FILE_INFORMATION_CLASS FileInformationClass -); - -using f_NtQueryInformationFile = NTSTATUS(__stdcall *) -( - HANDLE FileHandle, - IO_STATUS_BLOCK * pIoStatusBlock, - PVOID FileInformation, - ULONG Length, - FILE_INFORMATION_CLASS FileInformationClass -); - -using f_NtClose = NTSTATUS (__stdcall *) -( - HANDLE Handle -); - -using f_NtAllocateVirtualMemory = NTSTATUS (__stdcall *) -( - HANDLE ProcessHandle, - PVOID * BaseAddress, - ULONG_PTR ZeroBits, - SIZE_T * RegionSize, - ULONG AllocationType, - ULONG Protect -); - -using f_NtFreeVirtualMemory = NTSTATUS (__stdcall *) -( - HANDLE ProcessHandle, - PVOID * BaseAddress, - SIZE_T * RegionSize, - ULONG FreeType -); - -using f_NtProtectVirtualMemory = NTSTATUS (__stdcall *) -( - HANDLE ProcessHandle, - PVOID * BaseAddress, - SIZE_T * Size, - ULONG NewAccess, - ULONG * OldAccess -); - -using f_LdrpModuleBaseAddressIndex = RTL_RB_TREE *; -using f_LdrpMappingInfoIndex = RTL_RB_TREE *; -using f_LdrpHeap = PVOID *; -using f_LdrpInvertedFunctionTable = RTL_INVERTED_FUNCTION_TABLE *; - -#pragma endregion - -inline HINSTANCE g_hNTDLL; - -#ifdef _WIN64 -inline HINSTANCE g_hNTDLL_WOW64; -#endif \ No newline at end of file diff --git a/GH Injector Library/NtCreateThreadEx.cpp b/GH Injector Library/NtCreateThreadEx.cpp index 273f2b4..ad7517c 100644 --- a/GH Injector Library/NtCreateThreadEx.cpp +++ b/GH Injector Library/NtCreateThreadEx.cpp @@ -135,7 +135,7 @@ DWORD SR_NtCreateThreadEx(HANDLE hTargetProc, f_Routine pRoutine, void * pArg, b } LOG(" Creating thread with\n pRoutine = %p\n pArg = %p\n", pRemoteFunc, pMem); - + NTSTATUS ntRet = NATIVE::NtCreateThreadEx(&hThread, THREAD_ALL_ACCESS, nullptr, hTargetProc, CloakThread ? pEntrypoint : pRemoteFunc, pMem, CloakThread ? Flags : NULL, 0, 0, 0, nullptr); if (NT_FAIL(ntRet) || !hThread) { diff --git a/GH Injector Library/Process Info.cpp b/GH Injector Library/Process Info.cpp index 7f3ecfe..adb7974 100644 --- a/GH Injector Library/Process Info.cpp +++ b/GH Injector Library/Process Info.cpp @@ -2,7 +2,81 @@ #include "Process Info.h" -#define NEXT_SYSTEM_PROCESS_ENTRY(pCurrent) ReCa(ReCa(pCurrent) + pCurrent->NextEntryOffset) +#define NEXT_SYSTEM_PROCESS_ENTRY(pCurrent) ReCa(ReCa(pCurrent) + pCurrent->NextEntryOffset) + +ProcessInfo::ProcessInfo() +{ + HINSTANCE hNTDLL = GetModuleHandle(TEXT("ntdll.dll")); + if (!hNTDLL) + { + return; + } + + LOG("Creating ProcessInfo\n"); + + m_pNtQueryInformationProcess = ReCa (GetProcAddress(hNTDLL, "NtQueryInformationProcess")); + m_pNtQuerySystemInformation = ReCa (GetProcAddress(hNTDLL, "NtQuerySystemInformation")); + m_pNtQueryInformationThread = ReCa (GetProcAddress(hNTDLL, "NtQueryInformationThread")); + + if (!m_pNtQueryInformationProcess || !m_pNtQuerySystemInformation || !m_pNtQueryInformationThread) + { + return; + } + + m_BufferSize = 0x10000; + m_pFirstProcess = nullptr; + + ULONG nt_ret_offset = 0; + +#ifdef _WIN64 + if (GetOSBuildVersion() <= g_Win10_1507) + { + nt_ret_offset = NT_RET_OFFSET_64_WIN7; + } + else + { + nt_ret_offset = NT_RET_OFFSET_64_WIN10_1511; + } +#else + if (GetOSVersion() == g_Win7) + { + nt_ret_offset = NT_RET_OFFSET_86_WIN7; + } + else + { + nt_ret_offset = NT_RET_OFFSET_86_WIN8; + } +#endif + + m_WaitFunctionReturnAddress[0] = ReCa(GetProcAddress(hNTDLL, "NtDelayExecution" )) + nt_ret_offset; + m_WaitFunctionReturnAddress[1] = ReCa(GetProcAddress(hNTDLL, "NtWaitForSingleObject" )) + nt_ret_offset; + m_WaitFunctionReturnAddress[2] = ReCa(GetProcAddress(hNTDLL, "NtWaitForMultipleObjects" )) + nt_ret_offset; + m_WaitFunctionReturnAddress[3] = ReCa(GetProcAddress(hNTDLL, "NtSignalAndWaitForSingleObject" )) + nt_ret_offset; + + if (GetOSBuildVersion() >= g_Win10_1607) + { + m_hWin32U = LoadLibrary(TEXT("win32u.dll")); + if (m_hWin32U) + { + m_WaitFunctionReturnAddress[4] = ReCa(GetProcAddress(m_hWin32U, "NtUserMsgWaitForMultipleObjectsEx")) + nt_ret_offset; + } + } + + LOG("ProcessInfo initialized\n"); +} + +ProcessInfo::~ProcessInfo() +{ + if (m_hWin32U) + { + FreeLibrary(m_hWin32U); + } + + if (m_pFirstProcess) + { + delete[] m_pFirstProcess; + } +} PEB * ProcessInfo::GetPEB_Native() { @@ -58,7 +132,7 @@ LDR_DATA_TABLE_ENTRY * ProcessInfo::GetLdrEntry_Native(HINSTANCE hMod) if (CurrentEntry.DllBase == hMod) { - return ReCa(pCurrentEntry); + return ReCa(pCurrentEntry); } else if (pCurrentEntry == pLastEntry) { @@ -71,52 +145,6 @@ LDR_DATA_TABLE_ENTRY * ProcessInfo::GetLdrEntry_Native(HINSTANCE hMod) return nullptr; } -ProcessInfo::ProcessInfo() -{ - HINSTANCE hNTDLL = GetModuleHandle(TEXT("ntdll.dll")); - if (!hNTDLL) - { - return; - } - - m_pNtQueryInformationProcess = ReCa (GetProcAddress(hNTDLL, "NtQueryInformationProcess")); - m_pNtQuerySystemInformation = ReCa (GetProcAddress(hNTDLL, "NtQuerySystemInformation")); - m_pNtQueryInformationThread = ReCa (GetProcAddress(hNTDLL, "NtQueryInformationThread")); - - if (!m_pNtQueryInformationProcess || !m_pNtQuerySystemInformation || !m_pNtQueryInformationThread) - { - return; - } - - m_BufferSize = 0x10000; - m_pFirstProcess = nullptr; - - m_WaitFunctionReturnAddress[0] = ReCa(GetProcAddress(hNTDLL, "NtDelayExecution" )) + NT_RET_OFFSET; - m_WaitFunctionReturnAddress[1] = ReCa(GetProcAddress(hNTDLL, "NtWaitForSingleObject" )) + NT_RET_OFFSET; - m_WaitFunctionReturnAddress[2] = ReCa(GetProcAddress(hNTDLL, "NtWaitForMultipleObjects" )) + NT_RET_OFFSET; - m_WaitFunctionReturnAddress[3] = ReCa(GetProcAddress(hNTDLL, "NtSignalAndWaitForSingleObject" )) + NT_RET_OFFSET; - m_WaitFunctionReturnAddress[4] = ReCa(GetProcAddress(hNTDLL, "NtRemoveIoCompletionEx" )) + NT_RET_OFFSET; - - m_hWin32U = LoadLibrary(TEXT("win32u.dll")); - if (m_hWin32U) - { - m_WaitFunctionReturnAddress[5] = ReCa(GetProcAddress(m_hWin32U, "NtUserMsgWaitForMultipleObjectsEx")) + NT_RET_OFFSET; - } -} - -ProcessInfo::~ProcessInfo() -{ - if (m_hWin32U) - { - FreeLibrary(m_hWin32U); - } - - if (m_pFirstProcess) - { - delete[] m_pFirstProcess; - } -} - bool ProcessInfo::SetProcess(HANDLE hTargetProc) { DWORD dwHandleInfo = 0; @@ -135,11 +163,15 @@ bool ProcessInfo::SetProcess(HANDLE hTargetProc) m_hCurrentProcess = hTargetProc; +#ifdef _WIN64 + m_IsWow64 = IsNative() ? false : true; +#endif + ULONG_PTR PID = GetProcessId(m_hCurrentProcess); while (NEXT_SYSTEM_PROCESS_ENTRY(m_pCurrentProcess) != m_pCurrentProcess) { - if (m_pCurrentProcess->UniqueProcessId == ReCa(PID)) + if (m_pCurrentProcess->UniqueProcessId == ReCa(PID)) { break; } @@ -147,7 +179,7 @@ bool ProcessInfo::SetProcess(HANDLE hTargetProc) m_pCurrentProcess = NEXT_SYSTEM_PROCESS_ENTRY(m_pCurrentProcess); } - if (m_pCurrentProcess->UniqueProcessId != ReCa(PID)) + if (m_pCurrentProcess->UniqueProcessId != ReCa(PID)) { m_pCurrentProcess = m_pFirstProcess; return false; @@ -170,7 +202,7 @@ bool ProcessInfo::SetThread(DWORD TID) for (UINT i = 0; i != m_pCurrentProcess->NumberOfThreads; ++i) { - if (m_pCurrentProcess->Threads[i].ClientId.UniqueThread == ReCa(ULONG_PTR(TID))) + if (m_pCurrentProcess->Threads[i].ClientId.UniqueThread == ReCa(ULONG_PTR(TID))) { m_CurrentThreadIndex = i; m_pCurrentThread = &m_pCurrentProcess->Threads[i]; @@ -222,7 +254,7 @@ bool ProcessInfo::RefreshInformation() { if (!m_pFirstProcess) { - m_pFirstProcess = ReCa(new BYTE[m_BufferSize]); + m_pFirstProcess = ReCa(new BYTE[m_BufferSize]); if (!m_pFirstProcess) { return false; @@ -244,7 +276,7 @@ bool ProcessInfo::RefreshInformation() delete[] m_pFirstProcess; m_BufferSize = size_out + 0x1000; - m_pFirstProcess = ReCa(new BYTE[m_BufferSize]); + m_pFirstProcess = ReCa(new BYTE[m_BufferSize]); if (!m_pFirstProcess) { return false; @@ -447,6 +479,15 @@ bool ProcessInfo::IsThreadInAlertableState() return false; } +#ifdef _WIN64 + + if (m_IsWow64) + { + return IsThreadInAlertableState_WOW64(); + } + +#endif + HANDLE hThread = OpenThread(THREAD_GET_CONTEXT, FALSE, MDWD(m_pCurrentThread->ClientId.UniqueThread)); if (!hThread) { @@ -472,38 +513,37 @@ bool ProcessInfo::IsThreadInAlertableState() return false; } - if (ctx.Rip == m_WaitFunctionReturnAddress[0]) - { - return (ctx.Rcx == TRUE); - } - else if (ctx.Rip == m_WaitFunctionReturnAddress[1]) + if (ctx.Rip == m_WaitFunctionReturnAddress[0]) //NtDelayExecution { - return (ctx.Rdx == TRUE); - } - else if (ctx.Rip == m_WaitFunctionReturnAddress[2]) + if (GetOSVersion() == g_Win7) + { + return (ctx.Rdi == TRUE); + } + else if (GetOSBuildVersion() <= g_Win10_1709) + { + return (ctx.Rbx == TRUE); + } + else + { + return (ctx.Rcx == TRUE); + } + } + else if (ctx.Rip == m_WaitFunctionReturnAddress[1]) //NtWaitForSingleObject { - return (ctx.Rsi == TRUE); - } - else if (ctx.Rip == m_WaitFunctionReturnAddress[3]) + return (ctx.Rbx == TRUE); + } + else if (ctx.Rip == m_WaitFunctionReturnAddress[2] || ctx.Rip == m_WaitFunctionReturnAddress[3]) //NtWaitForMultipleObjects & NtSignalAndWaitForSingleObject { return (ctx.Rsi == TRUE); - } - else if (ctx.Rip == m_WaitFunctionReturnAddress[4]) - { - BOOLEAN Alertable = FALSE; - if (ReadProcessMemory(m_hCurrentProcess, ReCa(ctx.Rsp + 0x30), &Alertable, sizeof(Alertable), nullptr)) - { - return (Alertable == TRUE); - } } - else if (ctx.Rip == m_WaitFunctionReturnAddress[5]) + else if (ctx.Rip == m_WaitFunctionReturnAddress[4]) //NtUserMsgWaitForMultipleObjectsEx { DWORD Flags = FALSE; - if (ReadProcessMemory(m_hCurrentProcess, ReCa(ctx.Rsp + 0x28), &Flags, sizeof(Flags), nullptr)) + if (ReadProcessMemory(m_hCurrentProcess, ReCa(ctx.Rsp + 0x28), &Flags, sizeof(Flags), nullptr)) { return ((Flags & MWMO_ALERTABLE) != 0); } - } + } #else @@ -512,33 +552,57 @@ bool ProcessInfo::IsThreadInAlertableState() return false; } - DWORD stack_buffer[7] = { 0 }; - if (!ReadProcessMemory(m_hCurrentProcess, ReCa(ctx.Esp), stack_buffer, sizeof(stack_buffer), nullptr)) + DWORD stack_buffer[6] = { 0 }; + if (!ReadProcessMemory(m_hCurrentProcess, ReCa(ctx.Esp), stack_buffer, sizeof(stack_buffer), nullptr)) { return false; } - if (ctx.Eip == m_WaitFunctionReturnAddress[0]) + if (ctx.Eip == m_WaitFunctionReturnAddress[0]) //NtDelayExecution { - return (stack_buffer[1] == TRUE); - } - else if (ctx.Eip == m_WaitFunctionReturnAddress[1]) - { - return (stack_buffer[2] == TRUE); + if (GetOSVersion() == g_Win7) + { + return (stack_buffer[2] == TRUE); + } + else + { + return (stack_buffer[1] == TRUE); + } } - else if (ctx.Eip == m_WaitFunctionReturnAddress[2]) + else if (ctx.Eip == m_WaitFunctionReturnAddress[1]) //NtWaitForSingleObject { - return (stack_buffer[4] == TRUE); + if (GetOSVersion() == g_Win7) + { + return (stack_buffer[3] == TRUE); + } + else + { + return (stack_buffer[2] == TRUE); + } } - else if (ctx.Eip == m_WaitFunctionReturnAddress[3]) + else if (ctx.Eip == m_WaitFunctionReturnAddress[2]) //NtWaitForMultipleObjects { - return (stack_buffer[3] == TRUE); + if (GetOSVersion() == g_Win7) + { + return (stack_buffer[5] == TRUE); + } + else + { + return (stack_buffer[4] == TRUE); + } } - else if (ctx.Eip == m_WaitFunctionReturnAddress[4]) + else if (ctx.Eip == m_WaitFunctionReturnAddress[3]) //NtSignalAndWaitForSingleObject { - return ((stack_buffer[6] & 0xFF) == TRUE); + if (GetOSVersion() == g_Win7) + { + return (stack_buffer[4] == TRUE); + } + else + { + return (stack_buffer[3] == TRUE); + } } - else if (ctx.Eip == m_WaitFunctionReturnAddress[5]) + else if (ctx.Eip == m_WaitFunctionReturnAddress[4]) //NtUserMsgWaitForMultipleObjectsEx { return ((stack_buffer[5] & MWMO_ALERTABLE) != 0); } @@ -550,6 +614,13 @@ bool ProcessInfo::IsThreadInAlertableState() bool ProcessInfo::IsThreadWorkerThread() { + if (GetOSVersion() < g_Win10) + { + //TEB_SAMETEB_FLAGS::LoaderWorker is Win10+ only + + return false; + } + if (!m_pCurrentThread) { return false; @@ -570,9 +641,9 @@ bool ProcessInfo::IsThreadWorkerThread() CloseHandle(hThread); USHORT TebInfo = NULL; - if (ReadProcessMemory(m_hCurrentProcess, ReCa(tbi.TebBaseAddress) + TEB_SAMETEBFLAGS, &TebInfo, sizeof(TebInfo), nullptr)) + if (ReadProcessMemory(m_hCurrentProcess, ReCa(tbi.TebBaseAddress) + TEB_SAMETEBFLAGS, &TebInfo, sizeof(TebInfo), nullptr)) { - return ((TebInfo & 0x2000) != 0); + return ((TebInfo & TEB_SAMETEB_FLAGS_LoaderWorker) != 0); } return false; @@ -590,7 +661,7 @@ const SYSTEM_THREAD_INFORMATION * ProcessInfo::GetThreadInfo() #ifdef _WIN64 -PEB32 * ProcessInfo::GetPEB_WOW64() +PEB_32 * ProcessInfo::GetPEB_WOW64() { if (!m_pFirstProcess) { @@ -606,52 +677,52 @@ PEB32 * ProcessInfo::GetPEB_WOW64() return nullptr; } - return ReCa(pPEB); + return ReCa(pPEB); } -LDR_DATA_TABLE_ENTRY32 * ProcessInfo::GetLdrEntry_WOW64(HINSTANCE hMod) +LDR_DATA_TABLE_ENTRY_32 * ProcessInfo::GetLdrEntry_WOW64(HINSTANCE hMod) { if (!m_pFirstProcess) { return nullptr; } - PEB32 * ppeb = GetPEB_WOW64(); + PEB_32 * ppeb = GetPEB_WOW64(); if (!ppeb) { return nullptr; } - PEB32 peb{ 0 }; - if (!ReadProcessMemory(m_hCurrentProcess, ppeb, &peb, sizeof(PEB32), nullptr)) + PEB_32 peb{ 0 }; + if (!ReadProcessMemory(m_hCurrentProcess, ppeb, &peb, sizeof(PEB_32), nullptr)) { return nullptr; } - PEB_LDR_DATA32 ldrdata{ 0 }; - if (!ReadProcessMemory(m_hCurrentProcess, MPTR(peb.Ldr), &ldrdata, sizeof(PEB_LDR_DATA32), nullptr)) + PEB_LDR_DATA_32 ldrdata{ 0 }; + if (!ReadProcessMemory(m_hCurrentProcess, MPTR(peb.Ldr), &ldrdata, sizeof(PEB_LDR_DATA_32), nullptr)) { return nullptr; } - LIST_ENTRY32 * pCurrentEntry = ReCa((ULONG_PTR)ldrdata.InLoadOrderModuleListHead.Flink); - LIST_ENTRY32 * pLastEntry = ReCa((ULONG_PTR)ldrdata.InLoadOrderModuleListHead.Blink); + LIST_ENTRY32 * pCurrentEntry = ReCa((ULONG_PTR)ldrdata.InLoadOrderModuleListHead.Flink); + LIST_ENTRY32 * pLastEntry = ReCa((ULONG_PTR)ldrdata.InLoadOrderModuleListHead.Blink); while (true) { - LDR_DATA_TABLE_ENTRY32 CurrentEntry{ 0 }; - ReadProcessMemory(m_hCurrentProcess, pCurrentEntry, &CurrentEntry, sizeof(LDR_DATA_TABLE_ENTRY32), nullptr); + LDR_DATA_TABLE_ENTRY_32 CurrentEntry{ 0 }; + ReadProcessMemory(m_hCurrentProcess, pCurrentEntry, &CurrentEntry, sizeof(LDR_DATA_TABLE_ENTRY_32), nullptr); if (CurrentEntry.DllBase == MDWD(hMod)) { - return ReCa(pCurrentEntry); + return ReCa(pCurrentEntry); } else if (pCurrentEntry == pLastEntry) { break; } - pCurrentEntry = ReCa((ULONG_PTR)CurrentEntry.InLoadOrderLinks.Flink); + pCurrentEntry = ReCa((ULONG_PTR)CurrentEntry.InLoadOrderLinks.Flink); } return nullptr; @@ -674,26 +745,37 @@ bool ProcessInfo::IsThreadInAlertableState_WOW64() DWORD Address = 0; + ULONG nt_ret_offset = 0; + + if (GetOSVersion() > g_Win7) + { + nt_ret_offset = NT_RET_OFFSET_86_WIN8; + } + else + { + nt_ret_offset = NT_RET_OFFSET_86_WIN7; + } + GetProcAddressEx_WOW64(m_hCurrentProcess, hNTDLL, "NtDelayExecution", Address); - m_WaitFunctionReturnAddress_WOW64[0] = Address + NT_RET_OFFSET_86; + m_WaitFunctionReturnAddress_WOW64[0] = Address + nt_ret_offset; GetProcAddressEx_WOW64(m_hCurrentProcess, hNTDLL, "NtWaitForSingleObject", Address); - m_WaitFunctionReturnAddress_WOW64[1] = Address + NT_RET_OFFSET_86; + m_WaitFunctionReturnAddress_WOW64[1] = Address + nt_ret_offset; GetProcAddressEx_WOW64(m_hCurrentProcess, hNTDLL, "NtWaitForMultipleObjects", Address); - m_WaitFunctionReturnAddress_WOW64[2] = Address + NT_RET_OFFSET_86; + m_WaitFunctionReturnAddress_WOW64[2] = Address + nt_ret_offset; GetProcAddressEx_WOW64(m_hCurrentProcess, hNTDLL, "NtSignalAndWaitForSingleObject", Address); - m_WaitFunctionReturnAddress_WOW64[3] = Address + NT_RET_OFFSET_86; + m_WaitFunctionReturnAddress_WOW64[3] = Address + nt_ret_offset; - GetProcAddressEx_WOW64(m_hCurrentProcess, hNTDLL, "NtRemoveIoCompletionEx", Address); - m_WaitFunctionReturnAddress_WOW64[4] = Address + NT_RET_OFFSET_86; - - HINSTANCE hWIN32U = GetModuleHandleExW_WOW64(m_hCurrentProcess, L"win32u.dll"); - if (hWIN32U) + if (GetOSBuildVersion() >= g_Win10_1607) { - GetProcAddressEx_WOW64(m_hCurrentProcess, hWIN32U, "NtUserMsgWaitForMultipleObjectsEx", Address); - m_WaitFunctionReturnAddress_WOW64[5] = Address + NT_RET_OFFSET_86; + HINSTANCE hWIN32U = GetModuleHandleExW_WOW64(m_hCurrentProcess, L"win32u.dll"); + if (hWIN32U) + { + GetProcAddressEx_WOW64(m_hCurrentProcess, hWIN32U, "NtUserMsgWaitForMultipleObjectsEx", Address); + m_WaitFunctionReturnAddress_WOW64[4] = Address + nt_ret_offset; + } } } @@ -715,33 +797,57 @@ bool ProcessInfo::IsThreadInAlertableState_WOW64() CloseHandle(hThread); - DWORD stack_buffer[7] = { 0 }; + DWORD stack_buffer[6] = { 0 }; if (!ReadProcessMemory(m_hCurrentProcess, MPTR(ctx.Esp), stack_buffer, sizeof(stack_buffer), nullptr)) { return false; } - if (ctx.Eip == m_WaitFunctionReturnAddress_WOW64[0]) + if (ctx.Eip == m_WaitFunctionReturnAddress_WOW64[0]) //NtDelayExecution { - return (stack_buffer[1] == TRUE); - } - else if (ctx.Eip == m_WaitFunctionReturnAddress_WOW64[1]) - { - return (stack_buffer[2] == TRUE); + if (GetOSVersion() == g_Win7) + { + return (stack_buffer[2] == TRUE); + } + else + { + return (stack_buffer[1] == TRUE); + } } - else if (ctx.Eip == m_WaitFunctionReturnAddress_WOW64[2]) + else if (ctx.Eip == m_WaitFunctionReturnAddress_WOW64[1]) //NtWaitForSingleObject { - return (stack_buffer[4] == TRUE); + if (GetOSVersion() == g_Win7) + { + return (stack_buffer[3] == TRUE); + } + else + { + return (stack_buffer[2] == TRUE); + } } - else if (ctx.Eip == m_WaitFunctionReturnAddress_WOW64[3]) + else if (ctx.Eip == m_WaitFunctionReturnAddress_WOW64[2]) //NtWaitForMultipleObjects { - return (stack_buffer[3] == TRUE); + if (GetOSVersion() == g_Win7) + { + return (stack_buffer[5] == TRUE); + } + else + { + return (stack_buffer[4] == TRUE); + } } - else if (ctx.Eip == m_WaitFunctionReturnAddress_WOW64[4]) + else if (ctx.Eip == m_WaitFunctionReturnAddress_WOW64[3]) //NtSignalAndWaitForSingleObject { - return ((stack_buffer[6] & 0xFF) == TRUE); + if (GetOSVersion() == g_Win7) + { + return (stack_buffer[4] == TRUE); + } + else + { + return (stack_buffer[3] == TRUE); + } } - else if (ctx.Eip == m_WaitFunctionReturnAddress_WOW64[5]) + else if (ctx.Eip == m_WaitFunctionReturnAddress_WOW64[4]) //NtUserMsgWaitForMultipleObjectsEx { return ((stack_buffer[5] & MWMO_ALERTABLE) != 0); } diff --git a/GH Injector Library/Process Info.h b/GH Injector Library/Process Info.h index adf9256..bf88287 100644 --- a/GH Injector Library/Process Info.h +++ b/GH Injector Library/Process Info.h @@ -8,17 +8,20 @@ //Honestly, too lazy to document -#define NT_RET_OFFSET_64 0x14 -#define NT_RET_OFFSET_86 0x0C +#define NT_RET_OFFSET_64_WIN7 0x0A //Win7 - Win10 1507 +#define NT_RET_OFFSET_64_WIN10_1511 0x14 //Win10 1511+ + +#define NT_RET_OFFSET_86_WIN7 0x15 //Win7 only +#define NT_RET_OFFSET_86_WIN8 0x0C //Win8+ #define TEB_SAMETEBFLAGS_64 0x17EE #define TEB_SAMETEBFLAGS_86 0xFCA +#define TEB_SAMETEB_FLAGS_LoaderWorker 0x2000 + #ifdef _WIN64 -#define NT_RET_OFFSET NT_RET_OFFSET_64 #define TEB_SAMETEBFLAGS TEB_SAMETEBFLAGS_64 #else -#define NT_RET_OFFSET NT_RET_OFFSET_86 #define TEB_SAMETEBFLAGS TEB_SAMETEBFLAGS_86 #endif @@ -41,12 +44,13 @@ class ProcessInfo PEB * GetPEB_Native(); LDR_DATA_TABLE_ENTRY * GetLdrEntry_Native(HINSTANCE hMod); - UINT_PTR m_WaitFunctionReturnAddress[6] = { 0 }; + UINT_PTR m_WaitFunctionReturnAddress[5] = { 0 }; - HINSTANCE m_hWin32U; + HINSTANCE m_hWin32U = NULL; #ifdef _WIN64 - DWORD m_WaitFunctionReturnAddress_WOW64[6] = { 0 }; + DWORD m_WaitFunctionReturnAddress_WOW64[5] = { 0 }; + bool m_IsWow64 = false; #endif public: @@ -87,8 +91,8 @@ class ProcessInfo #ifdef _WIN64 - PEB32 * GetPEB_WOW64(); - LDR_DATA_TABLE_ENTRY32 * GetLdrEntry_WOW64(HINSTANCE hMod); + PEB_32 * GetPEB_WOW64(); + LDR_DATA_TABLE_ENTRY_32 * GetLdrEntry_WOW64(HINSTANCE hMod); bool IsThreadInAlertableState_WOW64(); diff --git a/GH Injector Library/Symbol Parser.cpp b/GH Injector Library/Symbol Parser.cpp index 6f7c416..cfbd501 100644 --- a/GH Injector Library/Symbol Parser.cpp +++ b/GH Injector Library/Symbol Parser.cpp @@ -395,7 +395,7 @@ DWORD SYMBOL_PARSER::Initialize(const std::wstring szModulePath, const std::wstr guid_filtered += w_GUID[i]; } } - + std::wstring url = L"https://msdl.microsoft.com/download/symbols/"; url += szPdbFileName; url += '/'; @@ -412,6 +412,17 @@ DWORD SYMBOL_PARSER::Initialize(const std::wstring szModulePath, const std::wstr while (InternetCheckConnectionW(L"https://msdl.microsoft.com", FLAG_ICC_FORCE_CONNECTION, NULL) == FALSE) { + if (GetLastError() == ERROR_INTERNET_CANNOT_CONNECT) + { + VirtualFree(pLocalImageBase, 0, MEM_RELEASE); + + delete[] pRawData; + + LOG(" Symbol Parser: cannot connect to Microsoft Symbol Server\n"); + + return SYMBOL_ERR_CANNOT_CONNECT; + } + Sleep(25); if (m_bInterruptEvent) diff --git a/GH Injector Library/Symbol Parser.h b/GH Injector Library/Symbol Parser.h index 5972319..ab3c2bd 100644 --- a/GH Injector Library/Symbol Parser.h +++ b/GH Injector Library/Symbol Parser.h @@ -63,7 +63,7 @@ struct PDBHeader7 struct RootStream7 { int num_streams; - int stream_sizes[1]; //num_streams + int stream_sizes[ANYSIZE_ARRAY]; //num_streams }; struct GUID_StreamData diff --git a/GH Injector Library/Tools.cpp b/GH Injector Library/Tools.cpp index 0c18718..ee6d9ef 100644 --- a/GH Injector Library/Tools.cpp +++ b/GH Injector Library/Tools.cpp @@ -2,14 +2,9 @@ #include "Tools.h" -static FLOAT g_vNTDLL = 0.0; -static const FLOAT g_Win7 = 6.1f; -static const FLOAT g_Win8 = 6.2f; -static const FLOAT g_Win81 = 6.3f; -static const FLOAT g_Win10 = 10.0f; - std::wstring InjectionModeToString(INJECTION_MODE mode); std::wstring LaunchMethodToString(LAUNCH_METHOD method); +std::wstring BuildNumberToVersionString(int OSBuildNumber); bool FileExists(const wchar_t * szFile) { @@ -167,26 +162,33 @@ void ErrorLog(ERROR_INFO * info) wchar_t szTime[30]{ 0 }; wcsftime(szTime, 30, L"%d-%m-%Y %H:%M:%S", &time_info); - wchar_t szWinProductName [100]{ 0 }; - wchar_t szWinReleaseId [100]{ 0 }; - wchar_t szWinCurrentBuild [100]{ 0 }; + const wchar_t * szWinProductName = nullptr; + auto szWinReleaseId = BuildNumberToVersionString(GetOSBuildVersion()); + wchar_t szWinCurrentBuild[10]{ 0 }; - HKEY hKey = nullptr; - LSTATUS reg_status = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", NULL, KEY_READ, &hKey); - if (reg_status == ERROR_SUCCESS) - { - DWORD Type = REG_SZ; + StringCchPrintfW(szWinCurrentBuild, sizeof(szWinCurrentBuild) / sizeof(wchar_t), L"%d", GetOSBuildVersion()); - DWORD SizeOut = sizeof(szWinProductName); - RegQueryValueExW(hKey, L"ProductName", nullptr, &Type, ReCa(szWinProductName), &SizeOut); + switch (GetOSVersion()) + { + case g_Win7: + szWinProductName = L"Windows 7"; + break; + + case g_Win8: + szWinProductName = L"Windows 8"; + break; - SizeOut = sizeof(szWinReleaseId); - RegQueryValueExW(hKey, L"ReleaseId", nullptr, &Type, ReCa(szWinReleaseId), &SizeOut); + case g_Win81: + szWinProductName = L"Windows 8.1"; + break; - SizeOut = sizeof(szWinCurrentBuild); - RegQueryValueExW(hKey, L"CurrentBuild", nullptr, &Type, ReCa(szWinCurrentBuild), &SizeOut); + default: + szWinProductName = L"Windows 10"; + } - RegCloseKey(hKey); + if (GetOSVersion() == g_Win10 && GetOSBuildVersion() == g_Win11_21H2) + { + szWinProductName = L"Windows 11"; } wchar_t szFlags [9]{ 0 }; @@ -208,7 +210,16 @@ void ErrorLog(ERROR_INFO * info) error_log << szTime << std::endl; error_log << L"Version : " << L"GH Injector V" << GH_INJ_VERSION << std::endl; - error_log << L"OS : " << szWinProductName << L" " << szWinReleaseId << L" (Build " << szWinCurrentBuild << L")" << std::endl; + + if (szWinReleaseId.length() > 1) + { + error_log << L"OS : " << szWinProductName << L" " << szWinReleaseId.c_str() << L" (Build " << szWinCurrentBuild << L")" << std::endl; + } + else + { + error_log << L"OS : " << szWinProductName << L" (Build " << szWinCurrentBuild << L")" << std::endl; + } + error_log << L"File : " << (info->szDllFileName ? info->szDllFileName : L"(nullptr)") << std::endl; error_log << L"Target : " << (info->szTargetProcessExeFileName[0] ? info->szTargetProcessExeFileName : L"(undetermined)") << std::endl; error_log << L"Target PID : " << info->TargetProcessId << std::endl; @@ -277,6 +288,58 @@ std::wstring LaunchMethodToString(LAUNCH_METHOD method) return std::wstring(L"bruh moment"); } +std::wstring BuildNumberToVersionString(int OSBuildNumber) +{ + switch (OSBuildNumber) + { + case g_Win7_SP1: + case g_Win8_SP1: + return std::wstring(L"SP1"); + + case g_Win10_1507: + return std::wstring(L"1507"); + + case g_Win10_1511: + return std::wstring(L"1511"); + + case g_Win10_1607: + return std::wstring(L"1607"); + + case g_Win10_1703: + return std::wstring(L"1703"); + + case g_Win10_1709: + return std::wstring(L"1709"); + + case g_Win10_1803: + return std::wstring(L"1803"); + + case g_Win10_1809: + return std::wstring(L"1809"); + + case g_Win10_1903: + return std::wstring(L"1903"); + + case g_Win10_1909: + return std::wstring(L"1909"); + + case g_Win10_2004: + return std::wstring(L"2004"); + + case g_Win10_20H2: + return std::wstring(L"20H2"); + + case g_Win10_21H1: + return std::wstring(L"21H1"); + + case g_Win11_21H2: + return std::wstring(L"21H2"); + + default: + return std::wstring(L""); + } +} + #if !defined(_WIN64) && defined(DUMP_SHELLCODE) void DumpShellcode(BYTE * start, int length, const wchar_t * szShellname) @@ -397,77 +460,4 @@ void __stdcall InterruptDownload() while (import_handler_ret.wait_for(std::chrono::milliseconds(100)) != std::future_status::ready); LOG("Import handler thread exited successfully\n"); -} - -bool IsWin7OrGreater() -{ - return (g_vNTDLL >= g_Win7); -} - -bool IsWin8OrGreater() -{ - return (g_vNTDLL >= g_Win8); -} - -bool IsWin10OrGreater() -{ - return (g_vNTDLL >= g_Win10); -} - -float GetNTDLLVersion() -{ - if (g_vNTDLL != 0.0f) - { - return g_vNTDLL; - } - - DWORD unused = 0; - auto fv_size = GetFileVersionInfoSize(TEXT("ntdll.dll"), &unused); - if (!fv_size) - { - return 0.0f; - } - - BYTE * v_buffer = new BYTE[fv_size]; - if (!v_buffer) - { - return 0.0f; - } - - if (!GetFileVersionInfo(TEXT("ntdll.dll"), 0, fv_size, v_buffer)) - { - delete[] v_buffer; - - return 0.0f; - } - - UINT size_out = 0; - VS_FIXEDFILEINFO * p_info = nullptr; - if (!VerQueryValue(v_buffer, TEXT("\\"), ReCa(&p_info), &size_out)) - { - delete[] v_buffer; - - return 0.0f; - } - - if (!p_info || p_info->dwSignature != VS_FFI_SIGNATURE) - { - delete[] v_buffer; - - return 0.0f; - } - - float v_hi = (float)((p_info->dwFileVersionMS >> 0x10) & 0xffff); - float v_lo = (float)((p_info->dwFileVersionMS >> 0x00) & 0xffff); - - delete[] v_buffer; - - while (v_lo > 1.0f) - { - v_lo /= 10.0f; - } - - g_vNTDLL = v_hi + v_lo; - - return g_vNTDLL; } \ No newline at end of file diff --git a/GH Injector Library/Tools.h b/GH Injector Library/Tools.h index 0c83c25..f17bc42 100644 --- a/GH Injector Library/Tools.h +++ b/GH Injector Library/Tools.h @@ -28,21 +28,8 @@ #define GH_INJ_VERSION GH_INJ_VERSIONA #endif -//Command line codes for "GH Injector SM - XX.exe" - -#define ID_SWHEX "0" //use for SetWindowsHookEx -#define ID_WOW64 "1" //use for wow64 addresses -#define ID_KC "2" //use for KernelCallbackTable - -//Global variable to store the base address of the current image of the injector. Initialized in DllMain. -inline HINSTANCE g_hInjMod = NULL; - -//Global variables to store the root directory of the module -inline std::string g_RootPathA; -inline std::wstring g_RootPathW; - //Global macro round up addresses and offsets -#define ALIGN_UP(X, A) (X + (A - 1)) & (~(A - 1)) +#define ALIGN_UP(X, A) ((ULONG_PTR)X + (A - 1)) & (~(A - 1)) struct ERROR_INFO //A structure used to pass information to the error log function. @@ -173,28 +160,4 @@ void __stdcall InterruptDownload(); //Arguments: // none // -//Returnvalue (void) - -bool IsWin7OrGreater(); -bool IsWin8OrGreater(); -bool IsWin10OrGreater(); -//These functions are used to determine the currently running version of windows. GetNTDLLVersion needs to be successfully called before these work. -// -//Arguements: -// none -// -//Returnvalue (bool): -/// true: Running OS is equal or newer than specified in the function name. -/// false: Running OS is older than specified in the function name. - -float GetNTDLLVersion(); -//This function is used to determine the version of the ntdll. -//Based on this: -//https://stackoverflow.com/a/940743 by user crashmstr -// -//Arguments: -// none -// -//Returnvalue (float): -/// On success: The version of the ntdll to 1 decimal place. -/// On failure: 0.0f. \ No newline at end of file +//Returnvalue (void) \ No newline at end of file diff --git a/GH Injector Library/VEH Shell.cpp b/GH Injector Library/VEH Shell.cpp new file mode 100644 index 0000000..68a490b --- /dev/null +++ b/GH Injector Library/VEH Shell.cpp @@ -0,0 +1,158 @@ +#pragma once +#include "pch.h" + +#include "VEH Shell.h" + +__forceinline UINT_PTR bit_rotate_l(UINT_PTR val, int count) +{ + return (val << count) | (val >> (-count)); +} + +#pragma optimize( "", off ) //even with volatile this doesn't work, disabling optimizations seems to be the only way + +// This code is 100% stolen from DarthTon: +// https://github.com/DarthTon/Blackbone/blob/master/src/BlackBone/ManualMap/MExcept.cpp + +#ifdef _WIN64 + +LONG __declspec(code_seg(".mmap_sec$3")) CALLBACK VectoredHandlerShell(EXCEPTION_POINTERS * ExceptionInfo) +{ + volatile auto * pData = ReCa(VEHDATASIG_64); + + if (ExceptionInfo->ExceptionRecord->ExceptionCode == EH_EXCEPTION_NUMBER) + { + if (ExceptionInfo->ExceptionRecord->ExceptionInformation[2] >= pData->ImgBase && ExceptionInfo->ExceptionRecord->ExceptionInformation[2] < pData->ImgBase + pData->ImgSize) + { + if (ExceptionInfo->ExceptionRecord->ExceptionInformation[0] == EH_PURE_MAGIC_NUMBER1 && ExceptionInfo->ExceptionRecord->ExceptionInformation[3] == 0) + { + ExceptionInfo->ExceptionRecord->ExceptionInformation[0] = (ULONG_PTR)EH_MAGIC_NUMBER1; + + ExceptionInfo->ExceptionRecord->ExceptionInformation[3] = pData->ImgBase; + } + } + } + + return EXCEPTION_CONTINUE_SEARCH; +} + +#else + +LONG __declspec(code_seg(".mmap_sec$3")) CALLBACK VectoredHandlerShell(EXCEPTION_POINTERS * ExceptionInfo) +{ + UNREFERENCED_PARAMETER(ExceptionInfo); + + volatile auto * pData = ReCa(VEHDATASIG_32); + EXCEPTION_REGISTRATION_RECORD * pERR = nullptr; + + pERR = ReCa(__readfsdword(0x00)); + + if (!pERR) + { + return EXCEPTION_CONTINUE_SEARCH; + } + + RTL_INVERTED_FUNCTION_TABLE_ENTRY * Entries = nullptr; + bool UseWin7Table = (pData->OSVersion == g_Win7); + + if (UseWin7Table) + { + Entries = &(ReCa(pData->_LdrpInvertedFunctionTable))->Entries[0]; + } + else + { + Entries = &pData->_LdrpInvertedFunctionTable->Entries[0]; + } + + auto ntRet = STATUS_SUCCESS; + if (pData->OSVersion >= g_Win81) + { + ntRet = pData->_LdrProtectMrdata(FALSE); + + if (NT_FAIL(ntRet)) + { + return EXCEPTION_CONTINUE_SEARCH; + } + } + + auto cookie = *P_KUSER_SHARED_DATA_COOKIE; + + for (; pERR && pERR != ReCa(0xFFFFFFFF) && pERR->Next != ReCa(0xFFFFFFFF); pERR = pERR->Next) + { + for (ULONG idx = 0; idx < pData->_LdrpInvertedFunctionTable->Count; ++idx) + { + if (!UseWin7Table && idx == 0) + { + continue; + } + + if (Entries[idx].ImageBase != ReCa(pData->ImgBase)) + { + continue; + } + + if (ReCa(pERR->Handler) < pData->ImgBase || ReCa(pERR->Handler) >= pData->ImgBase + pData->ImgSize) + { + continue; + } + + bool NewHandler = false; + + //DecodeSystemPointer + DWORD ptr_enc = ReCa(Entries[idx].ExceptionDirectory); + ptr_enc = bit_rotate_l(ptr_enc, cookie & 0x1F); + ptr_enc ^= cookie; + + DWORD * pStart = ReCa(ptr_enc); + + for (auto * pRVA = pStart; pRVA != nullptr && pRVA < pStart + 0x100; ++pRVA) + { + if (*pRVA == 0) + { + *pRVA = ReCa(pERR->Handler) - ReCa(Entries[idx].ImageBase); + + Entries[idx].ExceptionDirectorySize++; + NewHandler = true; + + break; + } + else if (ReCa(pERR->Handler) == ReCa(Entries[idx].ImageBase) + *pRVA) + { + break; + } + } + + if (NewHandler) + { + for (ULONG i = 0; i < Entries[idx].ExceptionDirectorySize; ++i) + { + for (ULONG j = Entries[idx].ExceptionDirectorySize - 1; j > i; --j) + { + if (pStart[j - 1] > pStart[j]) + { + //high efficient xor-swap to outperform DarthTon's code 5Head + pStart[j - 1] ^= pStart[j]; + pStart[j] ^= pStart[j - 1]; + pStart[j - 1] ^= pStart[j]; + } + } + } + } + } + } + + if (pData->OSVersion >= g_Win81) + { + pData->_LdrProtectMrdata(TRUE); + } + + return EXCEPTION_CONTINUE_SEARCH; +} + +#endif + +LONG __declspec(code_seg(".mmap_sec$4")) VectoredHandlerShell_End() +{ + return 2; +} + +#pragma optimize( "", on) \ No newline at end of file diff --git a/GH Injector Library/VEH Shell.h b/GH Injector Library/VEH Shell.h new file mode 100644 index 0000000..573ce0f --- /dev/null +++ b/GH Injector Library/VEH Shell.h @@ -0,0 +1,54 @@ +#pragma once + +#include "Injection.h" + +#define BASE_ALIGNMENT 0x10 + +#define EH_MAGIC_NUMBER1 0x19930520 +#define EH_PURE_MAGIC_NUMBER1 0x01994000 +#define EH_EXCEPTION_NUMBER ('msc' | 0xE0000000) + +#define VEHDATASIG_32 0xFACEB00C +#define VEHDATASIG_64 0xB16B00B500B16A33 + +#ifdef _WIN64 +#define VEHDATASIG VEHDATASIG_64 +#else +#define VEHDATASIG VEHDATASIG_32 +#endif + + + +ALIGN struct VEH_SHELL_DATA +{ + ULONG_PTR ImgBase; + DWORD ImgSize; + DWORD OSVersion; + + f_LdrpInvertedFunctionTable _LdrpInvertedFunctionTable; + f_LdrProtectMrdata _LdrProtectMrdata; +}; + +LONG __declspec(code_seg(".mmap_sec$3")) CALLBACK VectoredHandlerShell(EXCEPTION_POINTERS * EP); +LONG __declspec(code_seg(".mmap_sec$4")) VectoredHandlerShell_End(); + +__forceinline bool FindAndReplacePtr(BYTE * start, DWORD size, UINT_PTR stub, UINT_PTR value) +{ + if (!start) + { + return false; + } + + auto end = start + size - sizeof(UINT_PTR); + for (; start <= end; ++start) + { + if (*ReCa(start) == stub) + { + *ReCa(start) = value; + + return true; + } + } + + return false; +} \ No newline at end of file diff --git a/GH Injector Library/WOW64 Shells.h b/GH Injector Library/WOW64 Shells.h index 990b717..f78cf86 100644 --- a/GH Injector Library/WOW64 Shells.h +++ b/GH Injector Library/WOW64 Shells.h @@ -4,25 +4,35 @@ inline unsigned char InjectionShell_WOW64[] = { - 0x55, 0x8B, 0xEC, 0x83, 0xEC, 0x08, 0x56, 0x8B, 0x75, 0x08, 0x85, 0xF6, 0x75, 0x0A, 0x8D, 0x46, 0x01, 0x5E, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x8B, 0x46, 0x0C, 0x8D, 0x4E, 0x18, 0x89, 0x4E, 0x14, 0x57, 0x85, 0xC0, 0x75, 0x2F, 0x8B, 0x86, 0x3C, 0x03, 0x00, 0x00, 0x6A, 0x00, 0x6A, 0x00, 0x51, 0xFF, 0xD0, 0x89, 0x06, 0x85, 0xC0, 0x0F, 0x85, 0x01, 0x01, 0x00, 0x00, 0x8B, 0x86, 0x50, 0x03, 0x00, 0x00, 0xFF, 0xD0, 0x89, 0x46, 0x04, 0xB8, 0x28, 0x00, 0x00, 0x00, 0x5F, 0x5E, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x83, 0xF8, 0x01, 0x75, 0x19, 0x8B, 0x8E, 0x40, 0x03, 0x00, 0x00, 0x8D, 0x46, 0x10, 0x56, 0x50, 0x6A, 0x00, 0x6A, 0x00, 0xFF, 0xD1, 0x89, 0x46, 0x04, 0xE9, 0xCB, 0x00, 0x00, 0x00, 0x83, 0xF8, 0x02, 0x74, 0x12, 0x83, 0xF8, 0x03, 0x74, 0x0D, 0x5F, 0xB8, 0x0E, 0x00, 0x00, 0x00, 0x5E, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0xB8, 0x00, 0x01, 0x00, 0x00, 0xC7, 0x45, 0x08, 0x00, 0x00, 0x00, 0x00, 0x66, 0x89, 0x86, 0x22, 0x02, 0x00, 0x00, 0x8D, 0x4D, 0x08, 0x8D, 0x86, 0x28, 0x02, 0x00, 0x00, 0x51, 0x89, 0x86, 0x24, 0x02, 0x00, 0x00, 0x8D, 0x4E, 0x10, 0x8B, 0x86, 0x4C, 0x03, 0x00, 0x00, 0x8D, 0x96, 0x20, 0x02, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xD0, 0x83, 0x7E, 0x0C, 0x02, 0x8D, 0x96, 0x28, 0x03, 0x00, 0x00, 0x89, 0x46, 0x04, 0x8B, 0x86, 0x24, 0x02, 0x00, 0x00, 0x89, 0x86, 0x38, 0x03, 0x00, 0x00, 0xC7, 0x45, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xAE, 0xE8, 0x75, 0x17, 0x8B, 0x86, 0x44, 0x03, 0x00, 0x00, 0x8D, 0x4D, 0xFC, 0x51, 0xFF, 0x75, 0x08, 0x8D, 0x8E, 0x20, 0x02, 0x00, 0x00, 0xFF, 0xD0, 0xEB, 0x26, 0x8B, 0x86, 0x48, 0x03, 0x00, 0x00, 0x8D, 0x4D, 0xF8, 0x51, 0x8D, 0x4D, 0xFC, 0xC7, 0x45, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x51, 0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x04, 0xFF, 0x75, 0x08, 0x8D, 0x8E, 0x20, 0x02, 0x00, 0x00, 0xFF, 0xD0, 0x89, 0x46, 0x04, 0x8B, 0x45, 0xFC, 0x85, 0xC0, 0x75, 0x0D, 0x5F, 0xB8, 0x3A, 0x00, 0x00, 0x00, 0x5E, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x8B, 0x40, 0x18, 0x89, 0x06, 0x8B, 0x46, 0x08, 0xA8, 0x07, 0x75, 0x0A, 0x5F, 0x33, 0xC0, 0x5E, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x64, 0x8B, 0x3D, 0x30, 0x00, 0x00, 0x00, 0x85, 0xFF, 0x75, 0x0B, 0x8D, 0x47, 0x2C, 0x5F, 0x5E, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x8B, 0x4F, 0x0C, 0x85, 0xC9, 0x0F, 0x84, 0x86, 0x01, 0x00, 0x00, 0x83, 0x79, 0x0C, 0x00, 0x0F, 0x84, 0x7C, 0x01, 0x00, 0x00, 0xA8, 0x03, 0x0F, 0x84, 0x92, 0x00, 0x00, 0x00, 0x8B, 0x0E, 0x8B, 0x41, 0x3C, 0x8B, 0x44, 0x08, 0x54, 0x89, 0x4D, 0xFC, 0x8D, 0x4D, 0xF8, 0x51, 0x6A, 0x40, 0x8D, 0x4D, 0x08, 0x89, 0x45, 0x08, 0x8B, 0x86, 0x60, 0x03, 0x00, 0x00, 0x51, 0x8D, 0x4D, 0xFC, 0xC7, 0x45, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x51, 0x6A, 0xFF, 0xFF, 0xD0, 0x89, 0x46, 0x04, 0x8B, 0x46, 0x08, 0xA8, 0x01, 0x74, 0x10, 0xFF, 0x75, 0x08, 0x8B, 0x86, 0x58, 0x03, 0x00, 0x00, 0xFF, 0x75, 0xFC, 0xFF, 0xD0, 0xEB, 0x28, 0xA8, 0x02, 0x74, 0x24, 0x8B, 0x47, 0x0C, 0x8B, 0x40, 0x0C, 0x8B, 0x00, 0x85, 0xC0, 0x0F, 0x84, 0x18, 0x01, 0x00, 0x00, 0xFF, 0x75, 0x08, 0xFF, 0x70, 0x18, 0x8B, 0x86, 0x54, 0x03, 0x00, 0x00, 0xFF, 0x75, 0xFC, 0xFF, 0xD0, 0x83, 0xC4, 0x0C, 0x8D, 0x4D, - 0xF8, 0x51, 0x0F, 0xAE, 0xE8, 0xFF, 0x75, 0xF8, 0x8B, 0x86, 0x60, 0x03, 0x00, 0x00, 0x8D, 0x4D, 0x08, 0x51, 0x8D, 0x4D, 0xFC, 0x51, 0x6A, 0xFF, 0xFF, 0xD0, 0x89, 0x46, 0x04, 0x8B, 0x46, 0x08, 0x53, 0xA8, 0x04, 0x0F, 0x84, 0xCE, 0x00, 0x00, 0x00, 0x8B, 0x47, 0x0C, 0x83, 0xC0, 0x0C, 0x8B, 0x18, 0x3B, 0xD8, 0x74, 0x14, 0x8B, 0x16, 0x0F, 0x1F, 0x44, 0x00, 0x00, 0x8B, 0x0B, 0x39, 0x53, 0x18, 0x74, 0x14, 0x8B, 0xD9, 0x3B, 0xD8, 0x75, 0xF3, 0x5B, 0x5F, 0xB8, 0x13, 0x00, 0x00, 0x00, 0x5E, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x8B, 0x43, 0x04, 0x89, 0x41, 0x04, 0x8B, 0x4B, 0x04, 0x8B, 0x03, 0x89, 0x01, 0x8B, 0x4B, 0x10, 0x8B, 0x43, 0x14, 0x89, 0x41, 0x04, 0x8B, 0x4B, 0x14, 0x8B, 0x43, 0x10, 0x89, 0x01, 0x8B, 0x4B, 0x08, 0x8B, 0x43, 0x0C, 0x89, 0x41, 0x04, 0x8B, 0x4B, 0x0C, 0x8B, 0x43, 0x08, 0x89, 0x01, 0x8B, 0x4B, 0x3C, 0x8B, 0x43, 0x40, 0x89, 0x41, 0x04, 0x8B, 0x4B, 0x40, 0x8B, 0x43, 0x3C, 0x89, 0x01, 0x8D, 0x43, 0x68, 0x50, 0xFF, 0xB6, 0x64, 0x03, 0x00, 0x00, 0x8B, 0x86, 0x5C, 0x03, 0x00, 0x00, 0xFF, 0xD0, 0x8D, 0x43, 0x74, 0x50, 0xFF, 0xB6, 0x68, 0x03, 0x00, 0x00, 0x8B, 0x86, 0x5C, 0x03, 0x00, 0x00, 0xFF, 0xD0, 0x0F, 0xB7, 0x43, 0x2E, 0x50, 0xFF, 0x73, 0x30, 0x8B, 0x86, 0x58, 0x03, 0x00, 0x00, 0xFF, 0xD0, 0x0F, 0xB7, 0x43, 0x26, 0x50, 0xFF, 0x73, 0x28, 0x8B, 0x86, 0x58, 0x03, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x86, 0x58, 0x03, 0x00, 0x00, 0x8B, 0x7B, 0x50, 0x68, 0xA8, 0x00, 0x00, 0x00, 0x53, 0xFF, 0xD0, 0x8B, 0x86, 0x58, 0x03, 0x00, 0x00, 0x6A, 0x2C, 0x57, 0xFF, 0xD0, 0x5B, 0x5F, 0x33, 0xC0, 0x5E, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x5F, 0xB8, 0x2D, 0x00, 0x00, 0x00, 0x5E, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC + 0x55, 0x8B, 0xEC, 0x83, 0xEC, 0x28, 0x53, 0x56, 0x8B, 0x75, 0x08, 0x57, 0x85, 0xF6, 0x75, 0x0C, 0x8D, 0x46, 0x01, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x8B, 0x4E, 0x0C, 0x8D, 0x56, 0x18, 0x89, 0x56, 0x14, 0x85, 0xC9, 0x75, 0x2E, 0x8B, 0x86, 0x88, 0x03, 0x00, 0x00, 0x51, 0x51, 0x52, 0xFF, 0xD0, 0x89, 0x06, 0x85, 0xC0, 0x0F, 0x85, 0xC7, 0x00, 0x00, 0x00, 0x8B, 0x86, 0x9C, 0x03, 0x00, 0x00, 0xFF, 0xD0, 0x89, 0x46, 0x04, 0xB8, 0x28, 0x00, 0x00, 0x00, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x8B, 0x86, 0x78, 0x03, 0x00, 0x00, 0x83, 0xF9, 0x01, 0x75, 0x3C, 0xC7, 0x45, 0xF4, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x45, 0x08, 0x00, 0x00, 0x00, 0x00, 0x83, 0xF8, 0x3D, 0x75, 0x0B, 0x8B, 0x86, 0xC4, 0x03, 0x00, 0x00, 0x8B, 0x40, 0x04, 0xEB, 0x07, 0x80, 0x4D, 0x08, 0x01, 0x8B, 0x45, 0x08, 0x8B, 0x96, 0x8C, 0x03, 0x00, 0x00, 0x8D, 0x4E, 0x10, 0x56, 0x51, 0x8D, 0x4D, 0xF4, 0x51, 0x50, 0xFF, 0xD2, 0x89, 0x46, 0x04, 0xEB, 0x67, 0x83, 0xF8, 0x64, 0x0F, 0x82, 0x01, 0x01, 0x00, 0x00, 0x8D, 0xBE, 0x28, 0x03, 0x00, 0x00, 0x33, 0xC0, 0x89, 0x57, 0x10, 0x83, 0x7E, 0x0C, 0x02, 0xC7, 0x45, 0x08, 0x00, 0x00, 0x00, 0x00, 0x89, 0x45, 0xF8, 0x75, 0x67, 0x8B, 0x8E, 0x7C, 0x03, 0x00, 0x00, 0x8B, 0x9E, 0x90, 0x03, 0x00, 0x00, 0x81, 0xF9, 0xEE, 0x42, 0x00, 0x00, 0x77, 0x45, 0x81, 0xF9, 0x5A, 0x29, 0x00, 0x00, 0x77, 0x06, 0x89, 0x57, 0x0C, 0x89, 0x47, 0x10, 0x8D, 0x4D, 0x08, 0x8B, 0xD7, 0x51, 0x6A, 0x01, 0x50, 0x8D, 0x4E, 0x10, 0xFF, 0xD3, 0x89, 0x46, 0x04, 0x8B, 0x45, 0x08, 0x85, 0xC0, 0x0F, 0x84, 0x87, 0x01, 0x00, 0x00, 0x8B, 0x40, 0x18, 0x89, 0x06, 0x8B, 0x46, 0x08, 0xA8, 0x07, 0x0F, 0x85, 0x85, 0x01, 0x00, 0x00, 0x33, 0xC0, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x8D, 0x4D, 0x08, 0x8B, 0xD7, 0x51, 0x50, 0x8D, 0x4E, 0x10, 0xFF, 0xD3, 0xEB, 0xC9, 0x8D, 0x4D, 0xF8, 0x8D, 0x86, 0x28, 0x02, 0x00, 0x00, 0x51, 0x89, 0x86, 0x24, 0x02, 0x00, 0x00, 0x8D, 0x4E, 0x10, 0x8B, 0x86, 0x98, 0x03, 0x00, 0x00, 0x8D, 0x96, 0x20, 0x02, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xD0, 0x81, 0xBE, 0x7C, 0x03, 0x00, 0x00, 0x63, 0x4A, 0x00, 0x00, 0x8D, 0x4D, 0xF4, 0x89, 0x46, 0x04, 0x8B, 0xD7, 0xC7, 0x45, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x94, 0x03, 0x00, 0x00, 0x76, 0x1D, 0x6A, 0x00, 0x51, 0x8D, 0x4D, 0x08, 0x51, 0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x04, 0xFF, 0x75, 0xF8, 0x8D, 0x8E, 0x20, 0x02, 0x00, 0x00, 0xFF, 0xD0, 0xE9, 0x65, 0xFF, 0xFF, 0xFF, 0x51, 0x8D, 0x4D, 0x08, 0x51, 0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x04, 0xFF, 0x75, 0xF8, 0x8D, 0x8E, 0x20, 0x02, 0x00, 0x00, 0xFF, 0xD0, 0xE9, 0x4A, 0xFF, 0xFF, 0xFF, 0x83, 0xF8, 0x3F, 0x75, 0x47, 0x83, 0xF9, 0x02, 0x0F, 0x85, 0x02, 0x04, 0x00, 0x00, 0x8B, 0x86, 0x90, 0x03, 0x00, 0x00, 0x8D, 0x4D, 0xF4, 0x51, 0x8D, 0x4D, 0x08, 0xC7, 0x45, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x51, 0x0F, 0x57, 0xC0, 0xC7, 0x45, 0x08, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x11, 0x45, 0xE0, 0x6A, 0x01, 0x89, 0x55, 0xEC, 0x8D, 0x4E, 0x10, 0x6A, 0x00, 0x8D, 0x55, 0xE0, 0xC7, 0x45, 0xF4, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xD0, 0xE9, 0xFE, 0xFE, 0xFF, 0xFF, + 0x83, 0xF8, 0x3E, 0x75, 0x4B, 0x83, 0xF9, 0x02, 0x0F, 0x85, 0xB6, 0x03, 0x00, 0x00, 0x8B, 0x8E, 0x90, 0x03, 0x00, 0x00, 0x8D, 0x45, 0xF4, 0x50, 0x8D, 0x45, 0x08, 0xC7, 0x45, 0x08, 0x00, 0x00, 0x00, 0x00, 0x50, 0x6A, 0x01, 0x6A, 0x00, 0x8D, 0x45, 0xDC, 0xC7, 0x45, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x50, 0x0F, 0x57, 0xC0, 0x8D, 0x46, 0x10, 0x0F, 0x11, 0x45, 0xDC, 0x50, 0x66, 0x0F, 0xD6, 0x45, 0xEC, 0x89, 0x55, 0xE0, 0xC6, 0x45, 0xE4, 0x01, 0xFF, 0xD1, 0xE9, 0xAE, 0xFE, 0xFF, 0xFF, 0x83, 0xF8, 0x3D, 0x0F, 0x85, 0x6B, 0x03, 0x00, 0x00, 0x83, 0xF9, 0x02, 0x0F, 0x85, 0x62, 0x03, 0x00, 0x00, 0x8B, 0x8E, 0x90, 0x03, 0x00, 0x00, 0x8D, 0x45, 0x08, 0x50, 0x6A, 0x00, 0x6A, 0x01, 0x6A, 0x00, 0xFF, 0xB6, 0xC4, 0x03, 0x00, 0x00, 0x8D, 0x46, 0x10, 0xC7, 0x45, 0x08, 0x00, 0x00, 0x00, 0x00, 0x50, 0xFF, 0xD1, 0x89, 0x46, 0x04, 0x8B, 0x45, 0x08, 0x85, 0xC0, 0x0F, 0x85, 0x79, 0xFE, 0xFF, 0xFF, 0xB8, 0x3A, 0x00, 0x00, 0x00, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x64, 0x8B, 0x3D, 0x30, 0x00, 0x00, 0x00, 0x85, 0xFF, 0x75, 0x0C, 0x8D, 0x47, 0x2C, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x8B, 0x4F, 0x0C, 0x85, 0xC9, 0x0F, 0x84, 0xF3, 0x02, 0x00, 0x00, 0x83, 0x79, 0x0C, 0x00, 0x0F, 0x84, 0xE9, 0x02, 0x00, 0x00, 0xA8, 0x03, 0x0F, 0x84, 0x92, 0x00, 0x00, 0x00, 0x8B, 0x0E, 0x8B, 0x41, 0x3C, 0x8B, 0x44, 0x08, 0x54, 0x89, 0x4D, 0xF8, 0x8D, 0x4D, 0xF4, 0x51, 0x6A, 0x40, 0x8D, 0x4D, 0x08, 0x89, 0x45, 0x08, 0x8B, 0x86, 0xAC, 0x03, 0x00, 0x00, 0x51, 0x8D, 0x4D, 0xF8, 0xC7, 0x45, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x51, 0x6A, 0xFF, 0xFF, 0xD0, 0x89, 0x46, 0x04, 0x8B, 0x46, 0x08, 0xA8, 0x01, 0x74, 0x10, 0xFF, 0x75, 0x08, 0x8B, 0x86, 0xA4, 0x03, 0x00, 0x00, 0xFF, 0x75, 0xF8, 0xFF, 0xD0, 0xEB, 0x28, 0xA8, 0x02, 0x74, 0x24, 0x8B, 0x47, 0x0C, 0x8B, 0x40, 0x0C, 0x8B, 0x00, 0x85, 0xC0, 0x0F, 0x84, 0x85, 0x02, 0x00, 0x00, 0xFF, 0x75, 0x08, 0xFF, 0x70, 0x18, 0x8B, 0x86, 0xA0, 0x03, 0x00, 0x00, 0xFF, 0x75, 0xF8, 0xFF, 0xD0, 0x83, 0xC4, 0x0C, 0x8D, 0x4D, 0xF4, 0x51, 0x0F, 0xAE, 0xE8, 0xFF, 0x75, 0xF4, 0x8B, 0x86, 0xAC, 0x03, 0x00, 0x00, 0x8D, 0x4D, 0x08, 0x51, 0x8D, 0x4D, 0xF8, 0x51, 0x6A, 0xFF, 0xFF, 0xD0, 0x89, 0x46, 0x04, 0x8B, 0x46, 0x08, 0xA8, 0x04, 0x0F, 0x84, 0xAD, 0xFD, 0xFF, 0xFF, 0x8B, 0x47, 0x0C, 0x8B, 0x78, 0x0C, 0x83, 0xC0, 0x0C, 0x3B, 0xF8, 0x74, 0x0F, 0x8B, 0x0E, 0x8B, 0x57, 0x18, 0x3B, 0xD1, 0x74, 0x14, 0x8B, 0x3F, 0x3B, 0xF8, 0x75, 0xF3, 0xB8, 0x13, 0x00, 0x00, 0x00, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x8B, 0x8E, 0x80, 0x03, 0x00, 0x00, 0x8B, 0x9E, 0x84, 0x03, 0x00, 0x00, 0x83, 0xC1, 0x0F, 0x03, 0xD9, 0x83, 0xE3, 0xF0, 0x89, 0x13, 0x8B, 0x47, 0x20, 0x89, 0x43, 0x04, 0x8B, 0x86, 0x78, 0x03, 0x00, 0x00, 0x89, 0x43, 0x08, 0x8B, 0x86, 0xB8, 0x03, 0x00, 0x00, 0x89, 0x43, 0x0C, 0x8B, 0x86, 0xB4, 0x03, 0x00, 0x00, 0x89, 0x43, 0x10, 0x8B, 0x8E, 0x80, 0x03, 0x00, 0x00, 0x85, 0xC9, 0x74, 0x33, 0x8B, 0x86, 0x84, 0x03, 0x00, 0x00, 0x83, 0xC0, 0xFC, 0x03, 0xC1, 0x3B, 0xC8, 0x77, 0x24, 0x0F, 0x1F, 0x00, 0x81, 0x39, 0x0C, 0xB0, 0xCE, 0xFA, 0x74, 0x07, + 0x41, 0x3B, 0xC8, 0x76, 0xF3, 0xEB, 0x12, 0x89, 0x19, 0xFF, 0xB6, 0x80, 0x03, 0x00, 0x00, 0x8B, 0x86, 0xB0, 0x03, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xD0, 0x8B, 0x07, 0x85, 0xC0, 0x74, 0x11, 0x8B, 0x4F, 0x04, 0x85, 0xC9, 0x74, 0x0A, 0x89, 0x48, 0x04, 0x8B, 0x4F, 0x04, 0x8B, 0x07, 0x89, 0x01, 0x8B, 0x47, 0x10, 0x85, 0xC0, 0x74, 0x12, 0x8B, 0x4F, 0x14, 0x85, 0xC9, 0x74, 0x0B, 0x89, 0x48, 0x04, 0x8B, 0x4F, 0x14, 0x8B, 0x47, 0x10, 0x89, 0x01, 0x8B, 0x47, 0x08, 0x85, 0xC0, 0x74, 0x12, 0x8B, 0x4F, 0x0C, 0x85, 0xC9, 0x74, 0x0B, 0x89, 0x48, 0x04, 0x8B, 0x4F, 0x0C, 0x8B, 0x47, 0x08, 0x89, 0x01, 0x8B, 0x47, 0x3C, 0x85, 0xC0, 0x74, 0x12, 0x8B, 0x4F, 0x40, 0x85, 0xC9, 0x74, 0x0B, 0x89, 0x48, 0x04, 0x8B, 0x4F, 0x40, 0x8B, 0x47, 0x3C, 0x89, 0x01, 0x33, 0xC0, 0xC7, 0x45, 0x08, 0x2C, 0x00, 0x00, 0x00, 0x83, 0xBE, 0x78, 0x03, 0x00, 0x00, 0x3D, 0xBB, 0xB8, 0x00, 0x00, 0x00, 0x89, 0x45, 0xF4, 0x75, 0x55, 0x8B, 0x47, 0x50, 0x85, 0xC0, 0x74, 0x12, 0x8B, 0x4F, 0x54, 0x85, 0xC9, 0x74, 0x0B, 0x89, 0x48, 0x04, 0x8B, 0x4F, 0x54, 0x8B, 0x47, 0x50, 0x89, 0x01, 0x8B, 0x47, 0x58, 0x85, 0xC0, 0x74, 0x12, 0x8B, 0x4F, 0x5C, 0x85, 0xC9, 0x74, 0x0B, 0x89, 0x48, 0x04, 0x8B, 0x4F, 0x5C, 0x8B, 0x47, 0x58, 0x89, 0x01, 0x8B, 0x47, 0x60, 0x85, 0xC0, 0x74, 0x12, 0x8B, 0x4F, 0x64, 0x85, 0xC9, 0x74, 0x0B, 0x89, 0x48, 0x04, 0x8B, 0x4F, 0x64, 0x8B, 0x47, 0x60, 0x89, 0x01, 0xBB, 0x78, 0x00, 0x00, 0x00, 0xE9, 0x8C, 0x00, 0x00, 0x00, 0x8D, 0x47, 0x68, 0x50, 0xFF, 0xB6, 0xBC, 0x03, 0x00, 0x00, 0x8B, 0x86, 0xA8, 0x03, 0x00, 0x00, 0xFF, 0xD0, 0x8D, 0x47, 0x74, 0x50, 0xFF, 0xB6, 0xC0, 0x03, 0x00, 0x00, 0x8B, 0x86, 0xA8, 0x03, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x86, 0x78, 0x03, 0x00, 0x00, 0x83, 0xF8, 0x3E, 0x75, 0x0C, 0x8D, 0x58, 0x5A, 0xC7, 0x45, 0x08, 0x30, 0x00, 0x00, 0x00, 0xEB, 0x4B, 0x83, 0xF8, 0x3F, 0x75, 0x0C, 0x8D, 0x58, 0x61, 0xC7, 0x45, 0x08, 0x30, 0x00, 0x00, 0x00, 0xEB, 0x3A, 0x83, 0xF8, 0x64, 0x72, 0x35, 0x8B, 0x86, 0x7C, 0x03, 0x00, 0x00, 0x3D, 0x5A, 0x29, 0x00, 0x00, 0x77, 0x07, 0xBB, 0xA0, 0x00, 0x00, 0x00, 0xEB, 0x21, 0x3D, 0x39, 0x38, 0x00, 0x00, 0x77, 0x07, 0xBB, 0xA4, 0x00, 0x00, 0x00, 0xEB, 0x13, 0xC7, 0x45, 0x08, 0x2C, 0x00, 0x00, 0x00, 0x3D, 0x63, 0x4A, 0x00, 0x00, 0x77, 0x05, 0xBB, 0xA8, 0x00, 0x00, 0x00, 0x8B, 0x47, 0x50, 0x89, 0x45, 0xF4, 0x0F, 0xB7, 0x47, 0x2E, 0x50, 0xFF, 0x77, 0x30, 0x8B, 0x86, 0xA4, 0x03, 0x00, 0x00, 0xFF, 0xD0, 0x0F, 0xB7, 0x47, 0x26, 0x50, 0xFF, 0x77, 0x28, 0x8B, 0x86, 0xA4, 0x03, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x86, 0xA4, 0x03, 0x00, 0x00, 0x53, 0x57, 0xFF, 0xD0, 0x8B, 0x45, 0xF4, 0x85, 0xC0, 0x0F, 0x84, 0x7D, 0xFB, 0xFF, 0xFF, 0xFF, 0x75, 0x08, 0x50, 0x8B, 0x86, 0xA4, 0x03, 0x00, 0x00, 0xFF, 0xD0, 0x33, 0xC0, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0xB8, 0x2D, 0x00, 0x00, 0x00, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x5F, 0x5E, 0xB8, 0x0E, 0x00, 0x00, 0x00, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC }; inline unsigned char ManualMapping_Shell_WOW64[] = { - 0x55, 0x8B, 0xEC, 0x83, 0xEC, 0x58, 0x53, 0x56, 0x8B, 0x75, 0x08, 0x57, 0x85, 0xF6, 0x75, 0x0E, 0xB8, 0x01, 0x00, 0x40, 0x00, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x8B, 0x46, 0x04, 0x89, 0x45, 0xE4, 0x8B, 0x86, 0x9C, 0x04, 0x00, 0x00, 0xC7, 0x45, 0xD8, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x08, 0x89, 0x8E, 0xA4, 0x04, 0x00, 0x00, 0x85, 0xC9, 0x75, 0x0E, 0xB8, 0x0E, 0x00, 0x40, 0x00, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x66, 0x8B, 0x46, 0x10, 0x0F, 0x57, 0xC0, 0x66, 0x0F, 0x13, 0x45, 0xA8, 0x66, 0x89, 0x45, 0xA8, 0xB8, 0x10, 0x02, 0x00, 0x00, 0x68, 0x10, 0x02, 0x00, 0x00, 0x6A, 0x08, 0x66, 0x89, 0x45, 0xAA, 0x8B, 0x86, 0x68, 0x04, 0x00, 0x00, 0x51, 0xFF, 0xD0, 0x89, 0x45, 0xAC, 0x85, 0xC0, 0x0F, 0x84, 0x37, 0x03, 0x00, 0x00, 0x6A, 0x08, 0x8D, 0x8E, 0x30, 0x04, 0x00, 0x00, 0x51, 0x50, 0x8B, 0x86, 0x60, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x0F, 0xB7, 0x45, 0xA8, 0x50, 0x8D, 0x46, 0x18, 0x50, 0x8B, 0x45, 0xAC, 0x83, 0xC0, 0x08, 0x50, 0x8B, 0x86, 0x60, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x86, 0x68, 0x04, 0x00, 0x00, 0x83, 0xC4, 0x18, 0x66, 0x83, 0x45, 0xA8, 0x08, 0x6A, 0x18, 0x6A, 0x08, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0xD8, 0x85, 0xDB, 0x74, 0x50, 0x6A, 0x08, 0x8D, 0x45, 0xA8, 0xC7, 0x03, 0x18, 0x00, 0x00, 0x00, 0xC7, 0x43, 0x04, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x43, 0x0C, 0x40, 0x00, 0x00, 0x00, 0x89, 0x43, 0x08, 0xC7, 0x43, 0x10, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x43, 0x14, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x86, 0x68, 0x04, 0x00, 0x00, 0x6A, 0x08, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0xF8, 0x85, 0xFF, 0x75, 0x3A, 0x53, 0x50, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x45, 0xAC, 0x85, 0xC0, 0x0F, 0x84, 0x92, 0x02, 0x00, 0x00, 0x50, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xB8, 0x03, 0x00, 0x40, 0x00, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x8B, 0x86, 0x40, 0x04, 0x00, 0x00, 0x8D, 0x4D, 0xF0, 0x6A, 0x20, 0x6A, 0x01, 0x57, 0x53, 0x68, 0x89, 0x00, 0x12, 0x00, 0x51, 0xC7, 0x45, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x8E, 0x6C, 0x04, 0x00, 0x00, 0x53, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0x89, 0x45, 0xBC, 0xFF, 0xD1, 0x8B, 0x45, 0xAC, 0x85, 0xC0, 0x74, 0x11, 0x50, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x45, 0xBC, 0x85, 0xC0, 0x79, 0x25, 0x57, 0x89, 0x46, 0x08, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xB8, 0x02, 0x00, 0x40, 0x00, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x8B, 0x86, 0x68, 0x04, 0x00, 0x00, 0x68, 0x00, 0x10, 0x00, 0x00, 0x6A, 0x08, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0xD8, 0x85, 0xDB, 0x0F, 0x84, 0xD3, 0x01, 0x00, 0x00, 0x6A, 0x00, 0x6A, 0x00, 0x68, 0x00, 0x10, 0x00, 0x00, 0x53, 0x57, 0x6A, 0x00, 0x6A, 0x00, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x44, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0x75, - 0xF0, 0xFF, 0xD0, 0x53, 0x6A, 0x00, 0x85, 0xC0, 0x79, 0x41, 0x89, 0x46, 0x08, 0x0F, 0xAE, 0xE8, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x57, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xFF, 0x75, 0xF0, 0x8B, 0x86, 0x48, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xB8, 0x04, 0x00, 0x40, 0x00, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x0F, 0xAE, 0xE8, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x86, 0x68, 0x04, 0x00, 0x00, 0x6A, 0x18, 0x6A, 0x08, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0xD8, 0x0F, 0xAE, 0xE8, 0x85, 0xDB, 0x75, 0x15, 0x57, 0x50, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xE9, 0x2B, 0x01, 0x00, 0x00, 0x8B, 0x86, 0x50, 0x04, 0x00, 0x00, 0x6A, 0x05, 0x6A, 0x18, 0x53, 0x57, 0xFF, 0x75, 0xF0, 0xFF, 0xD0, 0x85, 0xC0, 0x79, 0x44, 0x53, 0x89, 0x46, 0x08, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x57, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xFF, 0x75, 0xF0, 0x8B, 0x86, 0x48, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xB8, 0x07, 0x00, 0x40, 0x00, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x6A, 0x40, 0x68, 0x00, 0x30, 0x00, 0x00, 0x8D, 0x4D, 0xE0, 0xC7, 0x45, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x03, 0x51, 0x6A, 0x00, 0x8D, 0x4D, 0xDC, 0x89, 0x45, 0xE0, 0x8B, 0x86, 0x54, 0x04, 0x00, 0x00, 0x51, 0x6A, 0xFF, 0xFF, 0xD0, 0x85, 0xC0, 0x79, 0x44, 0x53, 0x89, 0x46, 0x08, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x57, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xFF, 0x75, 0xF0, 0x8B, 0x86, 0x48, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xB8, 0x08, 0x00, 0x40, 0x00, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x8B, 0x86, 0x68, 0x04, 0x00, 0x00, 0x6A, 0x08, 0x6A, 0x08, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0xC8, 0x89, 0x4D, 0xBC, 0x0F, 0xAE, 0xE8, 0x85, 0xC9, 0x75, 0x5E, 0x53, 0x50, 0x0F, 0xAE, 0xE8, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x57, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8D, 0x45, 0xE0, 0xC7, 0x45, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x80, 0x00, 0x00, 0x50, 0x8D, 0x45, 0xDC, 0x50, 0x8B, 0x86, 0x5C, 0x04, 0x00, 0x00, 0x6A, 0xFF, 0xFF, 0xD0, 0xFF, 0x75, 0xF0, 0x8B, 0x86, 0x48, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xB8, 0x03, 0x00, 0x40, 0x00, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x8B, 0x86, 0x4C, 0x04, 0x00, 0x00, 0x6A, 0x0E, 0x6A, 0x08, 0x51, 0x57, 0xFF, 0x75, 0xF0, 0xFF, 0xD0, 0x0F, 0xAE, 0xE8, 0x85, 0xC0, 0x79, 0x5F, 0x53, 0x89, 0x46, 0x08, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x6C, 0x04, 0x00, - 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x57, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x68, 0x00, 0x80, 0x00, 0x00, 0x8D, 0x45, 0xE0, 0xC7, 0x45, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x50, 0x8D, 0x45, 0xDC, 0x50, 0x8B, 0x86, 0x5C, 0x04, 0x00, 0x00, 0x6A, 0xFF, 0xFF, 0xD0, 0xFF, 0x75, 0xF0, 0x8B, 0x86, 0x48, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xB8, 0x05, 0x00, 0x40, 0x00, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0xFF, 0x75, 0xBC, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x86, 0x44, 0x04, 0x00, 0x00, 0x6A, 0x00, 0x6A, 0x00, 0xFF, 0x33, 0xFF, 0x75, 0xDC, 0x57, 0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x00, 0xFF, 0x75, 0xF0, 0xFF, 0xD0, 0x53, 0x0F, 0xAE, 0xE8, 0x6A, 0x00, 0x85, 0xC0, 0x79, 0x48, 0x89, 0x46, 0x08, 0x0F, 0xAE, 0xE8, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x57, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x68, 0x00, 0x80, 0x00, 0x00, 0x8D, 0x45, 0xE0, 0xC7, 0x45, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x50, 0x8D, 0x45, 0xDC, 0x50, 0x8B, 0x86, 0x5C, 0x04, 0x00, 0x00, 0x6A, 0xFF, 0xFF, 0xD0, 0xE9, 0x6B, 0xFD, 0xFF, 0xFF, 0x0F, 0xAE, 0xE8, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x57, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x45, 0xDC, 0x8B, 0x58, 0x3C, 0x03, 0xD8, 0x8B, 0x45, 0xE4, 0x25, 0x00, 0x00, 0x20, 0x02, 0x89, 0x5D, 0xC0, 0x89, 0x45, 0xBC, 0x8B, 0x4B, 0x50, 0x89, 0x4D, 0xE8, 0x3D, 0x00, 0x00, 0x00, 0x02, 0x75, 0x09, 0x0F, 0xB7, 0x46, 0x0C, 0x03, 0xC1, 0x89, 0x45, 0xE8, 0x8B, 0x86, 0x54, 0x04, 0x00, 0x00, 0x8D, 0x4D, 0xE8, 0x6A, 0x40, 0x68, 0x00, 0x30, 0x00, 0x00, 0x51, 0x6A, 0x00, 0x8D, 0x4D, 0xD8, 0x51, 0x6A, 0xFF, 0xFF, 0xD0, 0x8B, 0xF8, 0x89, 0x7D, 0xD0, 0x0F, 0xAE, 0xE8, 0x85, 0xFF, 0x79, 0x26, 0x68, 0x00, 0x80, 0x00, 0x00, 0x8D, 0x45, 0xE0, 0x89, 0x7E, 0x08, 0x50, 0x8D, 0x45, 0xDC, 0xC7, 0x45, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x50, 0x8B, 0x86, 0x5C, 0x04, 0x00, 0x00, 0x6A, 0xFF, 0xFF, 0xD0, 0xE9, 0xD9, 0xFD, 0xFF, 0xFF, 0x81, 0x7D, 0xBC, 0x00, 0x00, 0x00, 0x02, 0x75, 0x09, 0x0F, 0xB7, 0x46, 0x0C, 0x03, 0x45, 0xD8, 0xEB, 0x03, 0x8B, 0x45, 0xD8, 0x89, 0x45, 0xF4, 0xFF, 0x73, 0x54, 0xFF, 0x75, 0xDC, 0x50, 0x8B, 0x86, 0x60, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x0F, 0xB7, 0x43, 0x14, 0x33, 0xC9, 0x83, 0xC4, 0x0C, 0x89, 0x4D, 0xC8, 0x83, 0xC0, 0x2C, 0x66, 0x39, 0x4B, 0x06, 0x74, 0x3A, 0x8B, 0x7D, 0xC0, 0x03, 0xD8, 0x8B, 0x43, 0xFC, 0x85, 0xC0, 0x74, 0x1C, 0x50, 0x8B, 0x03, 0x03, 0x45, 0xDC, 0x50, 0x8B, 0x43, 0xF8, 0x03, 0x45, 0xF4, 0x50, 0x8B, 0x86, 0x60, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x4D, 0xC8, 0x83, 0xC4, 0x0C, 0x0F, 0xB7, 0x47, 0x06, 0x41, 0x83, 0xC3, 0x28, 0x89, 0x4D, 0xC8, 0x3B, 0xC8, 0x75, 0xCE, 0x8B, 0x7D, 0xD0, 0x8B, 0x45, 0xF4, 0x68, 0x00, 0x80, 0x00, 0x00, 0x8B, 0x48, 0x3C, 0x03, 0xC8, 0xC7, 0x45, 0xE0, - 0x00, 0x00, 0x00, 0x00, 0x8D, 0x45, 0xE0, 0x89, 0x4D, 0xEC, 0x50, 0x8D, 0x45, 0xDC, 0x50, 0x8B, 0x86, 0x5C, 0x04, 0x00, 0x00, 0x6A, 0xFF, 0xFF, 0xD0, 0x8B, 0x55, 0xEC, 0x8B, 0x5D, 0xF4, 0x8B, 0xC3, 0x2B, 0x42, 0x34, 0x89, 0x45, 0xC8, 0x0F, 0x84, 0xC5, 0x00, 0x00, 0x00, 0x83, 0xBA, 0xA4, 0x00, 0x00, 0x00, 0x00, 0x75, 0x3A, 0x68, 0x00, 0x80, 0x00, 0x00, 0x8D, 0x45, 0xE8, 0x50, 0x8D, 0x45, 0xD8, 0x50, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x5C, 0x04, 0x00, 0x00, 0x6A, 0xFF, 0xC7, 0x45, 0xE8, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xD0, 0xFF, 0x75, 0xF0, 0x8B, 0x86, 0x48, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xB8, 0x09, 0x00, 0x40, 0x00, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x8B, 0x8A, 0xA0, 0x00, 0x00, 0x00, 0x03, 0xCB, 0x89, 0x4D, 0xCC, 0x83, 0x39, 0x00, 0x74, 0x6C, 0x0F, 0x1F, 0x40, 0x00, 0x8B, 0x41, 0x04, 0x8D, 0x51, 0x08, 0x8D, 0x78, 0xF8, 0xD1, 0xEF, 0x74, 0x33, 0x8B, 0x75, 0xCC, 0x0F, 0xB7, 0x0A, 0x8B, 0xC1, 0x25, 0x00, 0xF0, 0x00, 0x00, 0x3D, 0x00, 0x30, 0x00, 0x00, 0x75, 0x11, 0x8B, 0x45, 0xC8, 0x81, 0xE1, 0xFF, 0x0F, 0x00, 0x00, 0x03, 0x0E, 0x01, 0x04, 0x19, 0x8B, 0x5D, 0xF4, 0x83, 0xC2, 0x02, 0x83, 0xEF, 0x01, 0x75, 0xD6, 0x8B, 0x4D, 0xCC, 0x8B, 0x41, 0x04, 0x8B, 0x55, 0xEC, 0x03, 0xC8, 0x89, 0x4D, 0xCC, 0x8B, 0x82, 0xA4, 0x00, 0x00, 0x00, 0x03, 0x82, 0xA0, 0x00, 0x00, 0x00, 0x03, 0xC3, 0x3B, 0xC8, 0x73, 0x05, 0x83, 0x39, 0x00, 0x75, 0xA1, 0x8B, 0x75, 0x08, 0x8B, 0x7D, 0xD0, 0x8B, 0x45, 0xC8, 0x01, 0x42, 0x34, 0x8B, 0x5D, 0xF4, 0x8B, 0x45, 0xE4, 0xA9, 0x00, 0x00, 0x40, 0x00, 0x74, 0x3D, 0x83, 0xBA, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x74, 0x34, 0x8B, 0xCB, 0x8B, 0xC1, 0x3D, 0x4E, 0xE6, 0x40, 0xBB, 0x75, 0x05, 0x8D, 0x4B, 0x01, 0xEB, 0x14, 0xA9, 0x00, 0x00, 0xFF, 0xFF, 0x75, 0x0D, 0x8B, 0xC8, 0x81, 0xC9, 0x11, 0x47, 0x00, 0x00, 0xC1, 0xE1, 0x10, 0x0B, 0xC8, 0x8B, 0x82, 0xC8, 0x00, 0x00, 0x00, 0x89, 0x4C, 0x18, 0x3C, 0x8B, 0x5D, 0xF4, 0x8B, 0x45, 0xE4, 0xA9, 0x00, 0x00, 0x82, 0x00, 0x0F, 0x84, 0x72, 0x03, 0x00, 0x00, 0x83, 0xBA, 0x84, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x84, 0x65, 0x03, 0x00, 0x00, 0x8B, 0x8A, 0x80, 0x00, 0x00, 0x00, 0x03, 0xCB, 0x89, 0x4D, 0xC8, 0x0F, 0x84, 0x54, 0x03, 0x00, 0x00, 0x66, 0x90, 0x8B, 0x41, 0x0C, 0x85, 0xC0, 0x0F, 0x84, 0x44, 0x03, 0x00, 0x00, 0x6A, 0x08, 0x6A, 0x08, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0x8D, 0x3C, 0x18, 0x8B, 0x86, 0x68, 0x04, 0x00, 0x00, 0x89, 0x7D, 0xD0, 0xFF, 0xD0, 0x8B, 0xD8, 0x85, 0xDB, 0x0F, 0x84, 0x0B, 0x07, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x8B, 0xCF, 0x0F, 0xB7, 0xD7, 0x8B, 0xC2, 0x74, 0x10, 0x0F, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x41, 0x0F, 0xB7, 0xC1, 0x80, 0x39, 0x00, 0x75, 0xF7, 0x2B, 0xC2, 0x0F, 0xB7, 0xF8, 0x66, 0x85, 0xFF, 0x0F, 0x84, 0xC9, 0x06, 0x00, 0x00, 0x8B, 0x8E, 0x68, 0x04, 0x00, 0x00, 0x8B, 0xC7, 0x89, 0x45, 0xBC, 0x40, 0x50, 0x6A, 0x08, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD1, 0x89, 0x43, 0x04, 0x85, 0xC0, 0x0F, 0x84, 0xA7, 0x06, 0x00, 0x00, 0x57, 0xFF, 0x75, 0xD0, 0x8D, 0x4F, 0x01, 0x66, 0x89, 0x3B, 0x66, 0x89, 0x4B, 0x02, 0x50, 0x8B, 0x86, 0x60, 0x04, 0x00, 0x00, 0xFF, 0xD0, - 0x8B, 0x86, 0x68, 0x04, 0x00, 0x00, 0x83, 0xC4, 0x0C, 0x6A, 0x08, 0x6A, 0x08, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0xF8, 0x89, 0x7D, 0xD4, 0x85, 0xFF, 0x0F, 0x84, 0x4F, 0x06, 0x00, 0x00, 0x8B, 0x8E, 0x68, 0x04, 0x00, 0x00, 0x68, 0x08, 0x02, 0x00, 0x00, 0x6A, 0x08, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD1, 0x89, 0x47, 0x04, 0xB9, 0x08, 0x02, 0x00, 0x00, 0x66, 0x89, 0x4F, 0x02, 0x85, 0xC0, 0x0F, 0x84, 0xF4, 0x05, 0x00, 0x00, 0x8B, 0x86, 0x7C, 0x04, 0x00, 0x00, 0x6A, 0x00, 0x53, 0x57, 0xFF, 0xD0, 0x8B, 0xF8, 0x85, 0xFF, 0x0F, 0x88, 0x8F, 0x05, 0x00, 0x00, 0x8B, 0x86, 0x68, 0x04, 0x00, 0x00, 0x68, 0x08, 0x01, 0x00, 0x00, 0x6A, 0x08, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0xD0, 0x89, 0x55, 0xD0, 0x0F, 0xAE, 0xE8, 0x85, 0xD2, 0x0F, 0x84, 0x18, 0x05, 0x00, 0x00, 0x8D, 0x4A, 0x08, 0xB8, 0x00, 0x01, 0x00, 0x00, 0x89, 0x4A, 0x04, 0x8D, 0x4D, 0xC4, 0x51, 0x8B, 0x4D, 0xD4, 0x66, 0x89, 0x42, 0x02, 0x8B, 0x86, 0x80, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xC7, 0x45, 0xC4, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0xF8, 0x8B, 0x45, 0xD4, 0x8B, 0x48, 0x04, 0x85, 0xC9, 0x74, 0x14, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x51, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x45, 0xD4, 0x50, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x43, 0x04, 0x85, 0xC0, 0x74, 0x11, 0x50, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x53, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x5D, 0xD0, 0x0F, 0xAE, 0xE8, 0x85, 0xFF, 0x0F, 0x88, 0x7A, 0x05, 0x00, 0x00, 0x8B, 0x86, 0x70, 0x04, 0x00, 0x00, 0x8D, 0x4D, 0xCC, 0x51, 0x53, 0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x00, 0xC7, 0x45, 0xCC, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0xF8, 0x85, 0xFF, 0x79, 0x6B, 0x8B, 0x86, 0x68, 0x04, 0x00, 0x00, 0x6A, 0x14, 0x6A, 0x08, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x4B, 0x04, 0x8B, 0xD0, 0x89, 0x45, 0xBC, 0x89, 0x48, 0x10, 0x8D, 0x4D, 0xB8, 0x51, 0x8D, 0x4D, 0xC0, 0x51, 0x6A, 0x00, 0x6A, 0x00, 0x0F, 0xAE, 0xE8, 0x8B, 0xBE, 0x74, 0x04, 0x00, 0x00, 0x8B, 0xCB, 0x6A, 0x04, 0xFF, 0x75, 0xC4, 0xC7, 0x45, 0xB8, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x45, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xD7, 0x8B, 0xF8, 0x85, 0xFF, 0x78, 0x09, 0x8B, 0x45, 0xC0, 0x8B, 0x40, 0x18, 0x89, 0x45, 0xCC, 0xFF, 0x75, 0xBC, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x53, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x85, 0xFF, 0x0F, 0x88, 0xEB, 0x04, 0x00, 0x00, 0x8B, 0x55, 0xC8, 0x8B, 0x5D, 0xF4, 0x8B, 0x0A, 0x8B, 0x52, 0x10, 0x03, 0xD3, 0x85, 0xC9, 0x89, 0x55, 0xD0, 0x8D, 0x04, 0x19, 0x0F, 0x45, 0xD0, 0x89, 0x55, 0xD4, 0x8B, 0x02, 0x85, 0xC0, 0x0F, 0x84, 0xB2, 0x00, 0x00, 0x00, 0x79, 0x19, 0x8B, 0x5D, 0xD0, 0x8B, 0x8E, 0x78, 0x04, 0x00, 0x00, 0x53, 0x0F, - 0xB7, 0xC0, 0x50, 0x6A, 0x00, 0xFF, 0x75, 0xCC, 0xFF, 0xD1, 0x8B, 0xF8, 0xEB, 0x73, 0x6A, 0x08, 0x03, 0xC3, 0x6A, 0x08, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0x89, 0x45, 0xBC, 0x8B, 0x86, 0x68, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0xD8, 0x85, 0xDB, 0x0F, 0x84, 0x8A, 0x04, 0x00, 0x00, 0x8B, 0x4D, 0xBC, 0x83, 0xC1, 0x02, 0x89, 0x4B, 0x04, 0x0F, 0xB7, 0xD1, 0x8B, 0xC2, 0x80, 0x39, 0x00, 0x74, 0x09, 0x41, 0x0F, 0xB7, 0xC1, 0x80, 0x39, 0x00, 0x75, 0xF7, 0xFF, 0x75, 0xD0, 0x2B, 0xC2, 0x66, 0x89, 0x03, 0x40, 0x66, 0x89, 0x43, 0x02, 0x8B, 0x45, 0xD4, 0x8B, 0x8E, 0x78, 0x04, 0x00, 0x00, 0x0F, 0xB7, 0x00, 0x50, 0x53, 0xFF, 0x75, 0xCC, 0xFF, 0xD1, 0x53, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0x8B, 0xF8, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x5D, 0xD0, 0x85, 0xFF, 0x0F, 0x88, 0x30, 0x04, 0x00, 0x00, 0x8B, 0x55, 0xD4, 0x83, 0xC3, 0x04, 0x83, 0xC2, 0x04, 0x89, 0x5D, 0xD0, 0x8B, 0x5D, 0xF4, 0x89, 0x55, 0xD4, 0x8B, 0x02, 0x85, 0xC0, 0x0F, 0x85, 0x4E, 0xFF, 0xFF, 0xFF, 0x8B, 0x55, 0xEC, 0x8B, 0x4D, 0xC8, 0x83, 0xC1, 0x14, 0x89, 0x4D, 0xC8, 0x8B, 0x82, 0x80, 0x00, 0x00, 0x00, 0x03, 0x82, 0x84, 0x00, 0x00, 0x00, 0x03, 0xC3, 0x3B, 0xC8, 0x73, 0x08, 0x85, 0xC9, 0x0F, 0x85, 0xB1, 0xFC, 0xFF, 0xFF, 0x8B, 0x45, 0xE4, 0x25, 0x00, 0x00, 0x04, 0x00, 0x89, 0x45, 0xB0, 0x0F, 0x84, 0x48, 0x06, 0x00, 0x00, 0x33, 0xC0, 0x39, 0x82, 0xE4, 0x00, 0x00, 0x00, 0x74, 0x08, 0x8B, 0x82, 0xE0, 0x00, 0x00, 0x00, 0x03, 0xC3, 0x32, 0xC9, 0x88, 0x4D, 0xFB, 0x85, 0xC0, 0x0F, 0x84, 0x29, 0x06, 0x00, 0x00, 0x8D, 0x50, 0x08, 0x89, 0x55, 0xD0, 0x8B, 0x42, 0xFC, 0x85, 0xC0, 0x0F, 0x84, 0xB7, 0x04, 0x00, 0x00, 0x6A, 0x08, 0x6A, 0x08, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0x8D, 0x3C, 0x18, 0x8B, 0x86, 0x68, 0x04, 0x00, 0x00, 0x89, 0x7D, 0xBC, 0xFF, 0xD0, 0x8B, 0xD8, 0x85, 0xDB, 0x0F, 0x84, 0xE9, 0x05, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x8B, 0xCF, 0x0F, 0xB7, 0xD7, 0x8B, 0xC2, 0x74, 0x0B, 0x66, 0x90, 0x41, 0x0F, 0xB7, 0xC1, 0x80, 0x39, 0x00, 0x75, 0xF7, 0x2B, 0xC2, 0x0F, 0xB7, 0xF8, 0x66, 0x85, 0xFF, 0x0F, 0x84, 0xA9, 0x05, 0x00, 0x00, 0x8B, 0x8E, 0x68, 0x04, 0x00, 0x00, 0x8B, 0xC7, 0x89, 0x45, 0xB8, 0x40, 0x50, 0x6A, 0x08, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD1, 0x89, 0x43, 0x04, 0x85, 0xC0, 0x0F, 0x84, 0x87, 0x05, 0x00, 0x00, 0x57, 0xFF, 0x75, 0xBC, 0x8D, 0x4F, 0x01, 0x66, 0x89, 0x3B, 0x66, 0x89, 0x4B, 0x02, 0x50, 0x8B, 0x86, 0x60, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x86, 0x68, 0x04, 0x00, 0x00, 0x83, 0xC4, 0x0C, 0x6A, 0x08, 0x6A, 0x08, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0xF8, 0x89, 0x7D, 0xD4, 0x85, 0xFF, 0x0F, 0x84, 0x2F, 0x05, 0x00, 0x00, 0x8B, 0x8E, 0x68, 0x04, 0x00, 0x00, 0x68, 0x08, 0x02, 0x00, 0x00, 0x6A, 0x08, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD1, 0x89, 0x47, 0x04, 0xB9, 0x08, 0x02, 0x00, 0x00, 0x66, 0x89, 0x4F, 0x02, 0x85, 0xC0, 0x0F, 0x84, 0xD4, 0x04, 0x00, 0x00, 0x8B, 0x86, 0x7C, 0x04, 0x00, 0x00, 0x6A, 0x00, 0x53, 0x57, 0xFF, 0xD0, 0x8B, 0xF8, 0x85, 0xFF, 0x0F, 0x88, 0x6F, 0x04, 0x00, 0x00, 0x8B, 0x86, 0x68, 0x04, 0x00, 0x00, 0x68, - 0x08, 0x01, 0x00, 0x00, 0x6A, 0x08, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0xD0, 0x89, 0x55, 0xBC, 0x0F, 0xAE, 0xE8, 0x85, 0xD2, 0x0F, 0x84, 0xF8, 0x03, 0x00, 0x00, 0x8D, 0x4A, 0x08, 0xB8, 0x00, 0x01, 0x00, 0x00, 0x89, 0x4A, 0x04, 0x8D, 0x4D, 0xC0, 0x51, 0x8B, 0x4D, 0xD4, 0x66, 0x89, 0x42, 0x02, 0x8B, 0x86, 0x80, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xC7, 0x45, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0xF8, 0x8B, 0x45, 0xD4, 0x8B, 0x48, 0x04, 0x85, 0xC9, 0x74, 0x14, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x51, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x45, 0xD4, 0x50, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x43, 0x04, 0x85, 0xC0, 0x74, 0x11, 0x50, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x53, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x0F, 0xAE, 0xE8, 0x8B, 0x5D, 0xBC, 0x85, 0xFF, 0x0F, 0x88, 0x5A, 0x04, 0x00, 0x00, 0x8B, 0x86, 0x70, 0x04, 0x00, 0x00, 0x8D, 0x4D, 0xCC, 0x51, 0x53, 0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x00, 0xC7, 0x45, 0xCC, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0xF8, 0x85, 0xFF, 0x79, 0x6B, 0x8B, 0x86, 0x68, 0x04, 0x00, 0x00, 0x6A, 0x14, 0x6A, 0x08, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x4B, 0x04, 0x8B, 0xD0, 0x89, 0x45, 0xB8, 0x89, 0x48, 0x10, 0x8D, 0x4D, 0xB4, 0x51, 0x8D, 0x4D, 0xC4, 0x51, 0x6A, 0x00, 0x6A, 0x00, 0x0F, 0xAE, 0xE8, 0x8B, 0xBE, 0x74, 0x04, 0x00, 0x00, 0x8B, 0xCB, 0x6A, 0x04, 0xFF, 0x75, 0xC0, 0xC7, 0x45, 0xB4, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x45, 0xC4, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xD7, 0x8B, 0xF8, 0x85, 0xFF, 0x78, 0x09, 0x8B, 0x45, 0xC4, 0x8B, 0x40, 0x18, 0x89, 0x45, 0xCC, 0xFF, 0x75, 0xB8, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x53, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x85, 0xFF, 0x0F, 0x88, 0x7F, 0x02, 0x00, 0x00, 0x8B, 0x55, 0xD0, 0x8B, 0x12, 0x85, 0xD2, 0x74, 0x09, 0x8B, 0x4D, 0xF4, 0x8B, 0x45, 0xCC, 0x89, 0x04, 0x0A, 0x8B, 0x55, 0xD0, 0x8B, 0x5D, 0xF4, 0x8B, 0x4A, 0x04, 0x8B, 0x42, 0x08, 0x03, 0xCB, 0x03, 0xC3, 0x89, 0x4D, 0xBC, 0x89, 0x45, 0xC8, 0x83, 0x39, 0x00, 0x0F, 0x84, 0x18, 0x02, 0x00, 0x00, 0x8B, 0x00, 0xC7, 0x45, 0xD4, 0x00, 0x00, 0x00, 0x00, 0x85, 0xC0, 0x0F, 0x89, 0x66, 0x01, 0x00, 0x00, 0x8D, 0x4D, 0xD4, 0x0F, 0xB7, 0xC0, 0x51, 0x50, 0x8B, 0x86, 0x78, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0x75, 0xCC, 0xFF, 0xD0, 0xE9, 0xBF, 0x01, 0x00, 0x00, 0x8B, 0x45, 0xD4, 0x8B, 0x48, 0x04, 0x85, 0xC9, 0x74, 0x14, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x51, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x45, 0xD4, 0x50, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x43, 0x04, 0x85, 0xC0, 0x74, 0x63, 0x50, 0x8B, 0x86, 0x6C, 0x04, - 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x0F, 0xAE, 0xE8, 0xE9, 0xA5, 0x00, 0x00, 0x00, 0x0F, 0xAE, 0xE8, 0x8B, 0x45, 0xD4, 0x8B, 0x48, 0x04, 0x85, 0xC9, 0x74, 0x14, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x51, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x45, 0xD4, 0x50, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x43, 0x04, 0x85, 0xC0, 0x74, 0x11, 0x50, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x0F, 0xAE, 0xE8, 0xEB, 0x56, 0xFF, 0x75, 0xD4, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0xBF, 0x03, 0x00, 0x40, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x43, 0x04, 0x85, 0xC0, 0x74, 0x37, 0x50, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xEB, 0x24, 0x8B, 0x43, 0x04, 0xBF, 0x03, 0x00, 0x40, 0x00, 0x85, 0xC0, 0x74, 0x18, 0x50, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xEB, 0x05, 0xBF, 0x74, 0x03, 0x00, 0xC0, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x53, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xEB, 0x05, 0xBF, 0x03, 0x00, 0x40, 0x00, 0x68, 0x00, 0x80, 0x00, 0x00, 0x8D, 0x45, 0xE8, 0x50, 0x0F, 0xAE, 0xE8, 0x8D, 0x45, 0xD8, 0x89, 0x7E, 0x08, 0x50, 0x8B, 0x86, 0x5C, 0x04, 0x00, 0x00, 0x6A, 0xFF, 0xC7, 0x45, 0xE8, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xD0, 0xFF, 0x75, 0xF0, 0x8B, 0x86, 0x48, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xB8, 0x0A, 0x00, 0x40, 0x00, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x6A, 0x08, 0x03, 0xC3, 0x6A, 0x08, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0x89, 0x45, 0xB8, 0x8B, 0x86, 0x68, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0xD8, 0x85, 0xDB, 0x74, 0x7A, 0x8B, 0x4D, 0xB8, 0x83, 0xC1, 0x02, 0x89, 0x4B, 0x04, 0x0F, 0xB7, 0xD1, 0x8B, 0xC2, 0x80, 0x39, 0x00, 0x74, 0x0F, 0x66, 0x0F, 0x1F, 0x44, 0x00, 0x00, 0x41, 0x0F, 0xB7, 0xC1, 0x80, 0x39, 0x00, 0x75, 0xF7, 0x2B, 0xC2, 0x66, 0x89, 0x03, 0x40, 0x66, 0x89, 0x43, 0x02, 0x8D, 0x45, 0xD4, 0x8B, 0x8E, 0x78, 0x04, 0x00, 0x00, 0x50, 0x8B, 0x45, 0xC8, 0x0F, 0xB7, 0x00, 0x50, 0x53, 0xFF, 0x75, 0xCC, 0xFF, 0xD1, 0x53, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0x8B, 0xF8, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x5D, 0xF4, 0x85, 0xFF, 0x78, 0x20, 0x8B, 0x4D, 0xBC, 0x8B, 0x45, 0xC8, 0x83, 0xC1, 0x04, 0x83, 0xC0, 0x04, 0x89, 0x4D, 0xBC, 0x89, 0x45, 0xC8, 0x83, 0x39, 0x00, 0x0F, 0x85, 0xF4, 0xFD, 0xFF, 0xFF, 0xEB, 0x07, 0x8B, 0x5D, 0xF4, 0xC6, 0x45, 0xFB, 0x01, 0x8B, 0x55, 0xD0, 0x8B, 0x45, 0xEC, 0x83, 0xC2, 0x20, 0x8B, 0x75, 0xEC, 0x89, 0x55, 0xD0, 0x8B, 0x80, 0xE4, 0x00, 0x00, 0x00, 0x8D, 0x4A, 0xF8, 0x03, 0xC3, 0x03, 0x86, 0xE0, 0x00, 0x00, 0x00, 0x8B, 0x75, 0x08, 0x3B, 0xC8, 0x73, 0x08, 0x85, 0xC9, 0x0F, 0x85, 0x3E, 0xFB, 0xFF, 0xFF, 0x80, 0x7D, 0xFB, 0x00, 0x0F, 0x84, 0x54, 0x01, 0x00, 0x00, 0x68, 0x00, 0x80, 0x00, 0x00, 0x8D, 0x45, 0xE8, 0x50, 0x0F, 0xAE, 0xE8, 0x8D, 0x45, 0xD8, - 0x89, 0x7E, 0x08, 0x50, 0x8B, 0x86, 0x5C, 0x04, 0x00, 0x00, 0x6A, 0xFF, 0xC7, 0x45, 0xE8, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xD0, 0xFF, 0x75, 0xF0, 0x8B, 0x86, 0x48, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xB8, 0x0B, 0x00, 0x40, 0x00, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x8B, 0x45, 0xD4, 0x8B, 0x48, 0x04, 0x85, 0xC9, 0x74, 0x14, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x51, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x45, 0xD4, 0x50, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x43, 0x04, 0x85, 0xC0, 0x74, 0x63, 0x50, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x0F, 0xAE, 0xE8, 0xE9, 0xA5, 0x00, 0x00, 0x00, 0x0F, 0xAE, 0xE8, 0x8B, 0x45, 0xD4, 0x8B, 0x48, 0x04, 0x85, 0xC9, 0x74, 0x14, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x51, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x45, 0xD4, 0x50, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x43, 0x04, 0x85, 0xC0, 0x74, 0x11, 0x50, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x0F, 0xAE, 0xE8, 0xEB, 0x56, 0xFF, 0x75, 0xD4, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0xBF, 0x03, 0x00, 0x40, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x43, 0x04, 0x85, 0xC0, 0x74, 0x37, 0x50, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xEB, 0x24, 0x8B, 0x43, 0x04, 0xBF, 0x03, 0x00, 0x40, 0x00, 0x85, 0xC0, 0x74, 0x18, 0x50, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xEB, 0x05, 0xBF, 0x74, 0x03, 0x00, 0xC0, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x53, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xE9, 0xB6, 0xFE, 0xFF, 0xFF, 0xBF, 0x03, 0x00, 0x40, 0x00, 0xE9, 0xAC, 0xFE, 0xFF, 0xFF, 0x8B, 0x55, 0xEC, 0x8B, 0x45, 0xE4, 0x25, 0x00, 0x00, 0x20, 0x00, 0x89, 0x45, 0xC4, 0x0F, 0x84, 0x2D, 0x01, 0x00, 0x00, 0x8D, 0x4D, 0xBC, 0x51, 0x6A, 0x20, 0x8D, 0x4D, 0xB4, 0x51, 0x0F, 0xAE, 0xE8, 0x8B, 0x42, 0x54, 0x8D, 0x4D, 0xF4, 0x51, 0x89, 0x45, 0xB4, 0x8B, 0x86, 0x58, 0x04, 0x00, 0x00, 0x6A, 0xFF, 0xC7, 0x45, 0xBC, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0xD0, 0x85, 0xD2, 0x0F, 0x88, 0xBE, 0x00, 0x00, 0x00, 0x8B, 0x4D, 0xEC, 0x0F, 0xAE, 0xE8, 0x8B, 0x5D, 0xF4, 0xC7, 0x45, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xB7, 0x79, 0x14, 0x83, 0xC7, 0x3C, 0x66, 0x83, 0x79, 0x06, 0x00, 0x0F, 0x84, 0xDC, 0x00, 0x00, 0x00, 0x03, 0xF9, 0x90, 0x8B, 0x47, 0xE8, 0x8B, 0x0F, 0x03, 0xC3, 0x89, 0x45, 0xC8, 0x8B, 0x47, 0xEC, 0x89, 0x45, 0xB8, 0x85, 0xC0, 0x74, 0x63, 0xF7, 0xC1, 0x00, 0x00, 0x00, 0x20, 0x74, 0x1D, 0x85, 0xC9, 0x79, 0x07, 0xB9, 0x40, 0x00, 0x00, 0x00, 0xEB, 0x30, 0x81, 0xE1, 0x00, 0x00, 0x00, 0x40, 0xF7, 0xD9, 0x1B, 0xC9, 0x83, 0xE1, 0x10, 0x83, 0xC1, 0x10, 0xEB, 0x1E, 0x85, 0xC9, 0x79, 0x07, 0xB9, 0x04, 0x00, 0x00, 0x00, 0xEB, 0x13, - 0xF7, 0xC1, 0x00, 0x00, 0x00, 0x40, 0xB8, 0x02, 0x00, 0x00, 0x00, 0xB9, 0x01, 0x00, 0x00, 0x00, 0x0F, 0x45, 0xC8, 0x8B, 0x86, 0x58, 0x04, 0x00, 0x00, 0x8D, 0x55, 0xBC, 0x52, 0x51, 0x8D, 0x4D, 0xB8, 0x51, 0x8D, 0x4D, 0xC8, 0x51, 0x6A, 0xFF, 0xFF, 0xD0, 0x8B, 0xD0, 0x85, 0xD2, 0x78, 0x25, 0x8B, 0x5D, 0xF4, 0x8B, 0x45, 0xEC, 0x83, 0xC7, 0x28, 0x8B, 0x4D, 0xC0, 0x41, 0x89, 0x55, 0xB8, 0x89, 0x4D, 0xC0, 0x0F, 0xB7, 0x40, 0x06, 0x3B, 0xC8, 0x0F, 0x85, 0x6D, 0xFF, 0xFF, 0xFF, 0x8B, 0xC2, 0x85, 0xC0, 0x79, 0x3D, 0x68, 0x00, 0x80, 0x00, 0x00, 0x8D, 0x45, 0xE8, 0x50, 0x0F, 0xAE, 0xE8, 0x8D, 0x45, 0xD8, 0x89, 0x56, 0x08, 0x50, 0x8B, 0x86, 0x5C, 0x04, 0x00, 0x00, 0x6A, 0xFF, 0xC7, 0x45, 0xE8, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xD0, 0xFF, 0x75, 0xF0, 0x8B, 0x86, 0x48, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xB8, 0x06, 0x00, 0x40, 0x00, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x8B, 0x4D, 0xEC, 0x8B, 0x7D, 0xE4, 0xF7, 0xC7, 0x00, 0x00, 0x10, 0x00, 0x0F, 0x84, 0xAE, 0x00, 0x00, 0x00, 0x8B, 0x51, 0x50, 0x8B, 0xCB, 0x8B, 0x86, 0x84, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x85, 0xC0, 0x79, 0x3D, 0x0F, 0xAE, 0xE8, 0x89, 0x46, 0x08, 0x8D, 0x45, 0xE8, 0x68, 0x00, 0x80, 0x00, 0x00, 0x50, 0x8D, 0x45, 0xD8, 0xC7, 0x45, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x50, 0x8B, 0x86, 0x5C, 0x04, 0x00, 0x00, 0x6A, 0xFF, 0xFF, 0xD0, 0xFF, 0x75, 0xF0, 0x8B, 0x86, 0x48, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xB8, 0x0C, 0x00, 0x40, 0x00, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x8B, 0x86, 0xA0, 0x04, 0x00, 0x00, 0x33, 0xC9, 0x8B, 0x10, 0x85, 0xD2, 0x74, 0x18, 0x8B, 0x5D, 0xF4, 0x83, 0xC0, 0x14, 0x66, 0x0F, 0x1F, 0x44, 0x00, 0x00, 0x39, 0x18, 0x74, 0x42, 0x41, 0x83, 0xC0, 0x10, 0x3B, 0xCA, 0x72, 0xF4, 0x68, 0x00, 0x80, 0x00, 0x00, 0x8D, 0x45, 0xE8, 0x50, 0x8D, 0x45, 0xD8, 0x50, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x5C, 0x04, 0x00, 0x00, 0x6A, 0xFF, 0xC7, 0x45, 0xE8, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xD0, 0xFF, 0x75, 0xF0, 0x8B, 0x86, 0x48, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xB8, 0x0D, 0x00, 0x40, 0x00, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0xF7, 0xC7, 0x00, 0x00, 0x08, 0x00, 0x0F, 0x84, 0x98, 0x00, 0x00, 0x00, 0x8B, 0x45, 0xEC, 0x83, 0xB8, 0xC4, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x84, 0x88, 0x00, 0x00, 0x00, 0x8B, 0x80, 0xC0, 0x00, 0x00, 0x00, 0x68, 0xA8, 0x00, 0x00, 0x00, 0x03, 0xC3, 0x6A, 0x08, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0x89, 0x45, 0xB4, 0x8B, 0x86, 0x68, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0xF8, 0x85, 0xFF, 0x75, 0x17, 0x0F, 0xAE, 0xE8, 0x89, 0x45, 0xE8, 0x8D, 0x45, 0xE8, 0x68, 0x00, 0x80, 0x00, 0x00, 0x50, 0x8D, 0x45, 0xD8, 0xE9, 0x61, 0xF0, 0xFF, 0xFF, 0x8B, 0x45, 0xF4, 0x8B, 0xCF, 0x89, 0x47, 0x18, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x57, 0x6A, 0x00, 0xFF, 0xB6, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x7D, 0xB4, 0x8B, 0x7F, 0x0C, 0x85, 0xFF, 0x74, 0x1A, 0x66, 0x0F, 0x1F, 0x44, 0x00, 0x00, 0x8B, 0x07, 0x85, 0xC0, 0x74, 0x0E, 0x6A, 0x00, 0x6A, 0x01, 0xFF, 0x75, 0xF4, 0xFF, 0xD0, 0x83, 0xC7, 0x04, 0x75, 0xEC, 0x8B, 0x5D, 0xF4, 0x8B, - 0x7D, 0xE4, 0xF7, 0xC7, 0x00, 0x00, 0x80, 0x00, 0x8B, 0x7D, 0xEC, 0x74, 0x63, 0x8B, 0x47, 0x28, 0x85, 0xC0, 0x74, 0x5C, 0xF7, 0x45, 0xE4, 0x00, 0x00, 0x00, 0x01, 0xC7, 0x45, 0xB4, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x45, 0xBC, 0x00, 0x00, 0x00, 0x00, 0x74, 0x39, 0x8B, 0x86, 0x8C, 0x04, 0x00, 0x00, 0x8D, 0x4D, 0xBC, 0x51, 0x8D, 0x4D, 0xB4, 0x51, 0x6A, 0x00, 0xFF, 0xD0, 0x8B, 0x4D, 0xF4, 0x85, 0xC0, 0x8B, 0x47, 0x28, 0x6A, 0x00, 0x6A, 0x01, 0x0F, 0x99, 0xC3, 0x03, 0xC1, 0x51, 0xFF, 0xD0, 0x84, 0xDB, 0x74, 0x18, 0xFF, 0x75, 0xBC, 0x8B, 0x86, 0x90, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xD0, 0xEB, 0x09, 0x6A, 0x00, 0x6A, 0x01, 0x53, 0x03, 0xC3, 0xFF, 0xD0, 0x8B, 0x5D, 0xF4, 0x8B, 0x45, 0xE4, 0x25, 0x00, 0x00, 0x21, 0x00, 0x3D, 0x00, 0x00, 0x01, 0x00, 0x0F, 0x85, 0x86, 0x02, 0x00, 0x00, 0x83, 0xBF, 0x84, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x84, 0x91, 0x00, 0x00, 0x00, 0x8B, 0xBF, 0x80, 0x00, 0x00, 0x00, 0x03, 0xFB, 0x8B, 0x47, 0x0C, 0x85, 0xC0, 0x74, 0x68, 0x80, 0x3C, 0x18, 0x00, 0x74, 0x05, 0xC6, 0x44, 0x18, 0x01, 0x00, 0x8B, 0x07, 0xC7, 0x47, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x55, 0xF4, 0x8D, 0x0C, 0x10, 0x85, 0xC0, 0x75, 0x05, 0x8B, 0x4F, 0x10, 0x03, 0xCA, 0x8B, 0x11, 0x85, 0xD2, 0x74, 0x23, 0x79, 0x08, 0xC7, 0x01, 0x00, 0x00, 0x00, 0x00, 0xEB, 0x0F, 0x8B, 0x45, 0xF4, 0x80, 0x7C, 0x10, 0x02, 0x00, 0x74, 0x05, 0xC6, 0x44, 0x10, 0x03, 0x00, 0x8B, 0x51, 0x04, 0x83, 0xC1, 0x04, 0x85, 0xD2, 0x75, 0xDD, 0xC7, 0x07, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x47, 0x10, 0x00, 0x00, 0x00, 0x00, 0x83, 0xC7, 0x14, 0x8B, 0x47, 0x0C, 0x85, 0xC0, 0x74, 0x05, 0x8B, 0x5D, 0xF4, 0xEB, 0x98, 0x8B, 0x7D, 0xEC, 0xC7, 0x87, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x87, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x5D, 0xF4, 0x83, 0xBF, 0xE4, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x84, 0xD3, 0x00, 0x00, 0x00, 0x83, 0x7D, 0xB0, 0x00, 0x0F, 0x85, 0xC9, 0x00, 0x00, 0x00, 0x8B, 0x87, 0xE0, 0x00, 0x00, 0x00, 0x03, 0xC3, 0x83, 0x78, 0x04, 0x00, 0x0F, 0x84, 0xA0, 0x00, 0x00, 0x00, 0x83, 0xC0, 0x0C, 0x89, 0x45, 0xBC, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x48, 0xF8, 0x80, 0x3C, 0x19, 0x00, 0x74, 0x05, 0xC6, 0x44, 0x19, 0x01, 0x00, 0x8B, 0x38, 0x8B, 0x50, 0x04, 0xC7, 0x40, 0xF8, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x40, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x75, 0xF4, 0x03, 0xFE, 0x03, 0xD6, 0x83, 0x3F, 0x00, 0x74, 0x3E, 0x0F, 0x1F, 0x00, 0x8B, 0x1A, 0x85, 0xDB, 0x79, 0x08, 0xC7, 0x02, 0x00, 0x00, 0x00, 0x00, 0xEB, 0x1A, 0x8A, 0x44, 0x33, 0x02, 0x84, 0xC0, 0x0F, 0xB6, 0xC8, 0xC7, 0x45, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x45, 0x4D, 0xB0, 0xFE, 0xC1, 0x88, 0x4C, 0x33, 0x02, 0x83, 0xC7, 0x04, 0x83, 0xC2, 0x04, 0x83, 0x3F, 0x00, 0x74, 0x05, 0x8B, 0x75, 0xF4, 0xEB, 0xC8, 0x8B, 0x45, 0xBC, 0xC7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x83, 0xC0, 0x20, 0x89, 0x45, 0xBC, 0x83, 0x78, 0xF8, 0x00, 0x74, 0x08, 0x8B, 0x5D, 0xF4, 0xE9, 0x74, 0xFF, 0xFF, 0xFF, 0x8B, 0x75, 0x08, 0x8B, 0x7D, 0xEC, 0xC7, 0x87, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xC7, 0x87, 0xE4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x5D, 0xF4, 0x83, 0xBF, 0xAC, 0x00, 0x00, 0x00, 0x00, 0x74, 0x48, 0x8B, 0xBF, 0xA8, 0x00, 0x00, 0x00, 0x03, 0xFB, 0x8B, 0x47, 0x14, 0xFF, 0x77, 0x10, 0x03, 0xC3, 0x50, 0x8B, 0x86, 0x64, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xC7, 0x47, 0x10, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x47, 0x14, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x47, 0x18, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x7D, 0xEC, 0xC7, 0x87, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x87, 0xAC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x5D, 0xF4, 0x83, 0xBF, 0xA4, 0x00, 0x00, 0x00, 0x00, 0x74, 0x4D, 0x8B, 0x8F, 0xA0, 0x00, 0x00, 0x00, 0x03, 0xCB, 0x89, 0x4D, 0x08, 0x83, 0x39, 0x00, 0x74, 0x26, 0x8B, 0x41, 0x04, 0x8D, 0x79, 0x04, 0x83, 0xE8, 0x08, 0x50, 0x8D, 0x41, 0x08, 0x50, 0x8B, 0x86, 0x64, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x4D, 0x08, 0x03, 0x0F, 0x89, 0x4D, 0x08, 0x83, 0x39, 0x00, 0x75, 0xDD, 0x8B, 0x7D, 0xEC, 0xC7, 0x87, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x87, 0xA4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x5D, 0xF4, 0x83, 0xBF, 0xC4, 0x00, 0x00, 0x00, 0x00, 0x74, 0x58, 0x8B, 0x8F, 0xC0, 0x00, 0x00, 0x00, 0x03, 0xCB, 0x8B, 0x41, 0x0C, 0x85, 0xC0, 0x74, 0x10, 0x83, 0x38, 0x00, 0x74, 0x0B, 0xC7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0xC0, 0x04, 0x75, 0xF0, 0xC7, 0x41, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x41, 0x08, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x41, 0x04, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x41, 0x10, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x01, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x87, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x87, 0xC4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x5D, 0xF4, 0xF6, 0x45, 0xE4, 0x03, 0x74, 0x79, 0x83, 0x7D, 0xC4, 0x00, 0x8B, 0x47, 0x54, 0x89, 0x5D, 0xBC, 0x89, 0x45, 0x08, 0xC7, 0x45, 0xC8, 0x00, 0x00, 0x00, 0x00, 0x74, 0x2D, 0x8D, 0x4D, 0xC8, 0x51, 0x6A, 0x40, 0x8D, 0x4D, 0x08, 0x51, 0x8D, 0x4D, 0xBC, 0x51, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x58, 0x04, 0x00, 0x00, 0x6A, 0xFF, 0xFF, 0xD0, 0x85, 0xC0, 0x79, 0x08, 0x89, 0x46, 0x08, 0xE9, 0x39, 0xFB, 0xFF, 0xFF, 0x8B, 0x5D, 0xF4, 0x8B, 0x45, 0x08, 0xF6, 0x45, 0xE4, 0x01, 0x74, 0x4B, 0x50, 0x8B, 0x86, 0x64, 0x04, 0x00, 0x00, 0x53, 0xFF, 0xD0, 0x83, 0x7D, 0xC4, 0x00, 0x74, 0x20, 0x8D, 0x4D, 0xC8, 0x51, 0x0F, 0xAE, 0xE8, 0xFF, 0x75, 0xC8, 0x8B, 0x86, 0x58, 0x04, 0x00, 0x00, 0x8D, 0x4D, 0x08, 0x51, 0x8D, 0x4D, 0xBC, 0x51, 0x6A, 0xFF, 0xFF, 0xD0, 0x85, 0xC0, 0x78, 0xBC, 0xFF, 0x75, 0xF0, 0x8B, 0x86, 0x48, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x45, 0xF4, 0x89, 0x06, 0x33, 0xC0, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0xF6, 0x45, 0xE4, 0x02, 0x74, 0xB9, 0x64, 0xA1, 0x30, 0x00, 0x00, 0x00, 0x85, 0xC0, 0x75, 0x19, 0xFF, 0x75, 0xF0, 0x8B, 0x86, 0x48, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xB8, 0x0F, 0x00, 0x40, 0x00, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x8B, 0x40, 0x0C, 0x85, 0xC0, 0x74, 0x48, 0x8B, 0x58, 0x0C, 0x85, 0xDB, 0x74, 0x41, 0x8B, 0x1B, 0x85, 0xDB, 0x74, 0x3B, 0x8B, 0x43, 0x18, 0x85, 0xC0, 0x74, 0x34, 0x8B, - 0x78, 0x3C, 0xFF, 0x75, 0x08, 0x03, 0xF8, 0x8B, 0x86, 0x64, 0x04, 0x00, 0x00, 0xFF, 0x75, 0xF4, 0xFF, 0xD0, 0x8B, 0x4D, 0x08, 0x39, 0x4F, 0x54, 0x8B, 0x96, 0x60, 0x04, 0x00, 0x00, 0x0F, 0x42, 0x4F, 0x54, 0x51, 0xFF, 0x73, 0x18, 0xFF, 0x75, 0xF4, 0xFF, 0xD2, 0x83, 0xC4, 0x0C, 0xE9, 0x47, 0xFF, 0xFF, 0xFF, 0xFF, 0x75, 0xF0, 0x8B, 0x86, 0x48, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x5F, 0x5E, 0xB8, 0x10, 0x00, 0x40, 0x00, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0xCC, 0xCC, 0xCC, 0xCC + 0x55, 0x8B, 0xEC, 0x83, 0xEC, 0x68, 0x53, 0x56, 0x8B, 0x75, 0x08, 0x57, 0x85, 0xF6, 0x75, 0x0E, 0xB8, 0x01, 0x00, 0x40, 0x00, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x8B, 0x46, 0x04, 0x89, 0x45, 0xE4, 0x8B, 0x86, 0xC8, 0x04, 0x00, 0x00, 0xC7, 0x45, 0xD8, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x45, 0xB0, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x45, 0xD4, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x08, 0xC7, 0x45, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x89, 0x8E, 0xD4, 0x04, 0x00, 0x00, 0x85, 0xC9, 0x75, 0x0E, 0xB8, 0x0E, 0x00, 0x40, 0x00, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x66, 0x8B, 0x46, 0x10, 0x0F, 0x57, 0xC0, 0x66, 0x0F, 0x13, 0x45, 0x98, 0x66, 0x89, 0x45, 0x98, 0xB8, 0x10, 0x02, 0x00, 0x00, 0x68, 0x10, 0x02, 0x00, 0x00, 0x6A, 0x08, 0x66, 0x89, 0x45, 0x9A, 0x8B, 0x86, 0x84, 0x04, 0x00, 0x00, 0x51, 0xFF, 0xD0, 0x8B, 0xC8, 0x89, 0x4D, 0x9C, 0x85, 0xC9, 0x0F, 0x84, 0xA0, 0x02, 0x00, 0x00, 0x6A, 0x08, 0x8D, 0x86, 0x30, 0x04, 0x00, 0x00, 0x50, 0x8B, 0x86, 0x7C, 0x04, 0x00, 0x00, 0x51, 0xFF, 0xD0, 0x0F, 0xB7, 0x45, 0x98, 0x50, 0x8D, 0x46, 0x18, 0x50, 0x8B, 0x45, 0x9C, 0x83, 0xC0, 0x08, 0x50, 0x8B, 0x86, 0x7C, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x86, 0x84, 0x04, 0x00, 0x00, 0x83, 0xC4, 0x18, 0x66, 0x83, 0x45, 0x98, 0x08, 0x6A, 0x18, 0x6A, 0x08, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0xD8, 0x85, 0xDB, 0x74, 0x50, 0x6A, 0x08, 0x8D, 0x45, 0x98, 0xC7, 0x03, 0x18, 0x00, 0x00, 0x00, 0xC7, 0x43, 0x04, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x43, 0x0C, 0x40, 0x00, 0x00, 0x00, 0x89, 0x43, 0x08, 0xC7, 0x43, 0x10, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x43, 0x14, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x86, 0x84, 0x04, 0x00, 0x00, 0x6A, 0x08, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0xF8, 0x85, 0xFF, 0x75, 0x3A, 0x53, 0x50, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x45, 0x9C, 0x85, 0xC0, 0x0F, 0x84, 0xFB, 0x01, 0x00, 0x00, 0x50, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xB8, 0x03, 0x00, 0x40, 0x00, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x8B, 0x86, 0x54, 0x04, 0x00, 0x00, 0x8D, 0x4D, 0xF0, 0x6A, 0x20, 0x6A, 0x01, 0x57, 0x53, 0x68, 0x89, 0x00, 0x12, 0x00, 0x51, 0xC7, 0x45, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xD0, 0x53, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0x89, 0x45, 0xA8, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x45, 0x9C, 0x85, 0xC0, 0x74, 0x11, 0x50, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x45, 0xA8, 0x85, 0xC0, 0x79, 0x25, 0x57, 0x89, 0x46, 0x08, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xB8, 0x02, 0x00, 0x40, 0x00, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x8B, 0x86, 0x84, 0x04, 0x00, 0x00, 0x6A, 0x18, 0x6A, 0x08, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0xD8, 0x0F, 0xAE, 0xE8, 0x85, 0xDB, 0x75, 0x15, 0x57, 0x50, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0x8B, + 0x86, 0x88, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xE9, 0x2B, 0x01, 0x00, 0x00, 0x8B, 0x86, 0x64, 0x04, 0x00, 0x00, 0x6A, 0x05, 0x6A, 0x18, 0x53, 0x57, 0xFF, 0x75, 0xF0, 0xFF, 0xD0, 0x85, 0xC0, 0x79, 0x44, 0x53, 0x89, 0x46, 0x08, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x57, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xFF, 0x75, 0xF0, 0x8B, 0x86, 0x5C, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xB8, 0x07, 0x00, 0x40, 0x00, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x6A, 0x40, 0x68, 0x00, 0x30, 0x00, 0x00, 0x8D, 0x4D, 0xE0, 0xC7, 0x45, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x03, 0x51, 0x6A, 0x00, 0x8D, 0x4D, 0xDC, 0x89, 0x45, 0xE0, 0x8B, 0x86, 0x68, 0x04, 0x00, 0x00, 0x51, 0x6A, 0xFF, 0xFF, 0xD0, 0x85, 0xC0, 0x79, 0x44, 0x53, 0x89, 0x46, 0x08, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x57, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xFF, 0x75, 0xF0, 0x8B, 0x86, 0x5C, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xB8, 0x08, 0x00, 0x40, 0x00, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x8B, 0x86, 0x84, 0x04, 0x00, 0x00, 0x6A, 0x08, 0x6A, 0x08, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0xC8, 0x89, 0x4D, 0xA8, 0x0F, 0xAE, 0xE8, 0x85, 0xC9, 0x75, 0x5E, 0x53, 0x50, 0x0F, 0xAE, 0xE8, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x57, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8D, 0x45, 0xE0, 0xC7, 0x45, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x80, 0x00, 0x00, 0x50, 0x8D, 0x45, 0xDC, 0x50, 0x8B, 0x86, 0x70, 0x04, 0x00, 0x00, 0x6A, 0xFF, 0xFF, 0xD0, 0xFF, 0x75, 0xF0, 0x8B, 0x86, 0x5C, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xB8, 0x03, 0x00, 0x40, 0x00, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x8B, 0x86, 0x60, 0x04, 0x00, 0x00, 0x6A, 0x0E, 0x6A, 0x08, 0x51, 0x57, 0xFF, 0x75, 0xF0, 0xFF, 0xD0, 0x0F, 0xAE, 0xE8, 0x85, 0xC0, 0x79, 0x5F, 0x53, 0x89, 0x46, 0x08, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x57, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x68, 0x00, 0x80, 0x00, 0x00, 0x8D, 0x45, 0xE0, 0xC7, 0x45, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x50, 0x8D, 0x45, 0xDC, 0x50, 0x8B, 0x86, 0x70, 0x04, 0x00, 0x00, 0x6A, 0xFF, 0xFF, 0xD0, 0xFF, 0x75, 0xF0, 0x8B, 0x86, 0x5C, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xB8, 0x05, 0x00, 0x40, 0x00, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0xFF, 0x75, 0xA8, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x86, 0x58, 0x04, 0x00, 0x00, 0x6A, 0x00, 0x6A, 0x00, 0xFF, 0x33, 0xFF, 0x75, 0xDC, 0x57, 0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x00, 0xFF, 0x75, 0xF0, 0xFF, + 0xD0, 0x53, 0x0F, 0xAE, 0xE8, 0x6A, 0x00, 0x85, 0xC0, 0x79, 0x5C, 0x89, 0x46, 0x08, 0x0F, 0xAE, 0xE8, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x57, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x68, 0x00, 0x80, 0x00, 0x00, 0x8D, 0x45, 0xE0, 0xC7, 0x45, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x50, 0x8D, 0x45, 0xDC, 0x50, 0x8B, 0x86, 0x70, 0x04, 0x00, 0x00, 0x6A, 0xFF, 0xFF, 0xD0, 0xFF, 0x75, 0xF0, 0x8B, 0x86, 0x5C, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xB8, 0x04, 0x00, 0x40, 0x00, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x0F, 0xAE, 0xE8, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x57, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x45, 0xDC, 0x8B, 0x55, 0xE4, 0x8B, 0x58, 0x3C, 0x03, 0xD8, 0x8B, 0xC2, 0x25, 0x00, 0x00, 0x20, 0x02, 0x89, 0x5D, 0xBC, 0x89, 0x45, 0xAC, 0x8B, 0x4B, 0x50, 0x89, 0x4D, 0xE8, 0x3D, 0x00, 0x00, 0x00, 0x02, 0x75, 0x09, 0x0F, 0xB7, 0x46, 0x0C, 0x03, 0xC8, 0x89, 0x4D, 0xE8, 0x8B, 0xC2, 0x25, 0x00, 0x00, 0x10, 0x00, 0x89, 0x45, 0xA8, 0x74, 0x09, 0x8D, 0x81, 0x00, 0x10, 0x00, 0x00, 0x89, 0x45, 0xE8, 0x8B, 0x86, 0x68, 0x04, 0x00, 0x00, 0x8D, 0x4D, 0xE8, 0x6A, 0x40, 0x68, 0x00, 0x30, 0x00, 0x00, 0x51, 0x6A, 0x00, 0x8D, 0x4D, 0xD8, 0x51, 0x6A, 0xFF, 0xFF, 0xD0, 0x8B, 0xF8, 0x89, 0x7D, 0xB8, 0x0F, 0xAE, 0xE8, 0x85, 0xFF, 0x79, 0x26, 0x68, 0x00, 0x80, 0x00, 0x00, 0x8D, 0x45, 0xE0, 0x89, 0x7E, 0x08, 0x50, 0x8D, 0x45, 0xDC, 0xC7, 0x45, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x50, 0x8B, 0x86, 0x70, 0x04, 0x00, 0x00, 0x6A, 0xFF, 0xFF, 0xD0, 0xE9, 0xAE, 0xFD, 0xFF, 0xFF, 0x81, 0x7D, 0xAC, 0x00, 0x00, 0x00, 0x02, 0x75, 0x09, 0x0F, 0xB7, 0x46, 0x0C, 0x03, 0x45, 0xD8, 0xEB, 0x03, 0x8B, 0x45, 0xD8, 0x83, 0x7D, 0xA8, 0x00, 0x89, 0x45, 0xF4, 0xC6, 0x45, 0xFB, 0x00, 0x74, 0x75, 0x8B, 0x43, 0x50, 0x03, 0x45, 0xF4, 0x6A, 0x14, 0x6A, 0x08, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0x89, 0x45, 0xB0, 0x8B, 0x86, 0x84, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0xD0, 0x85, 0xD2, 0x74, 0x54, 0x8B, 0x45, 0xF4, 0x89, 0x02, 0x8B, 0x43, 0x50, 0x89, 0x42, 0x04, 0x8B, 0x86, 0x40, 0x04, 0x00, 0x00, 0x89, 0x42, 0x08, 0x8B, 0x86, 0xCC, 0x04, 0x00, 0x00, 0x89, 0x42, 0x0C, 0x8B, 0x86, 0xB4, 0x04, 0x00, 0x00, 0x89, 0x42, 0x10, 0x8B, 0x8E, 0x48, 0x04, 0x00, 0x00, 0x85, 0xC9, 0x74, 0x20, 0x8B, 0x86, 0x4C, 0x04, 0x00, 0x00, 0x83, 0xC0, 0xFC, 0x03, 0xC1, 0x3B, 0xC8, 0x77, 0x11, 0x81, 0x39, 0x0C, 0xB0, 0xCE, 0xFA, 0x0F, 0x84, 0xE9, 0x00, 0x00, 0x00, 0x41, 0x3B, 0xC8, 0x76, 0xEF, 0xC6, 0x45, 0xFB, 0x00, 0xFF, 0x73, 0x54, 0x8B, 0x86, 0x7C, 0x04, 0x00, 0x00, 0xFF, 0x75, 0xDC, 0xFF, 0x75, 0xF4, 0xFF, 0xD0, 0x0F, 0xB7, 0x43, 0x14, 0x33, 0xC9, 0x83, 0xC4, 0x0C, 0x89, 0x4D, 0xB4, 0x83, 0xC0, 0x2C, 0x66, 0x39, 0x4B, 0x06, 0x74, 0x3A, 0x8B, 0x7D, 0xBC, 0x03, 0xD8, 0x8B, 0x43, 0xFC, 0x85, 0xC0, 0x74, 0x1C, 0x50, 0x8B, 0x03, 0x03, 0x45, 0xDC, 0x50, 0x8B, 0x43, 0xF8, 0x03, 0x45, 0xF4, 0x50, 0x8B, 0x86, 0x7C, 0x04, + 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x4D, 0xB4, 0x83, 0xC4, 0x0C, 0x0F, 0xB7, 0x47, 0x06, 0x41, 0x83, 0xC3, 0x28, 0x89, 0x4D, 0xB4, 0x3B, 0xC8, 0x75, 0xCE, 0x8B, 0x7D, 0xB8, 0x8B, 0x45, 0xF4, 0x68, 0x00, 0x80, 0x00, 0x00, 0x8B, 0x48, 0x3C, 0x03, 0xC8, 0xC7, 0x45, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x8D, 0x45, 0xE0, 0x89, 0x4D, 0xEC, 0x50, 0x8D, 0x45, 0xDC, 0x50, 0x8B, 0x86, 0x70, 0x04, 0x00, 0x00, 0x6A, 0xFF, 0xFF, 0xD0, 0x8B, 0x55, 0xEC, 0x8B, 0x5D, 0xF4, 0x8B, 0xC3, 0x2B, 0x42, 0x34, 0x89, 0x45, 0xB4, 0x0F, 0x84, 0xE9, 0x00, 0x00, 0x00, 0x83, 0xBA, 0xA4, 0x00, 0x00, 0x00, 0x00, 0x75, 0x5F, 0x68, 0x00, 0x80, 0x00, 0x00, 0x8D, 0x45, 0xE8, 0x50, 0x8D, 0x45, 0xD8, 0x50, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x70, 0x04, 0x00, 0x00, 0x6A, 0xFF, 0xC7, 0x45, 0xE8, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xD0, 0xFF, 0x75, 0xF0, 0x8B, 0x86, 0x5C, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xB8, 0x09, 0x00, 0x40, 0x00, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x89, 0x11, 0xFF, 0xB6, 0x4C, 0x04, 0x00, 0x00, 0x8B, 0x86, 0x7C, 0x04, 0x00, 0x00, 0xFF, 0xB6, 0x48, 0x04, 0x00, 0x00, 0xC6, 0x45, 0xFB, 0x01, 0xFF, 0x75, 0xB0, 0xFF, 0xD0, 0x83, 0xC4, 0x0C, 0xE9, 0xFB, 0xFE, 0xFF, 0xFF, 0x8B, 0x8A, 0xA0, 0x00, 0x00, 0x00, 0x03, 0xCB, 0x89, 0x4D, 0xBC, 0x83, 0x39, 0x00, 0x74, 0x6B, 0x0F, 0x1F, 0x00, 0x8B, 0x41, 0x04, 0x8D, 0x51, 0x08, 0x8D, 0x78, 0xF8, 0xD1, 0xEF, 0x74, 0x33, 0x8B, 0x75, 0xBC, 0x0F, 0xB7, 0x0A, 0x8B, 0xC1, 0x25, 0x00, 0xF0, 0x00, 0x00, 0x3D, 0x00, 0x30, 0x00, 0x00, 0x75, 0x11, 0x8B, 0x45, 0xB4, 0x81, 0xE1, 0xFF, 0x0F, 0x00, 0x00, 0x03, 0x0E, 0x01, 0x04, 0x19, 0x8B, 0x5D, 0xF4, 0x83, 0xC2, 0x02, 0x83, 0xEF, 0x01, 0x75, 0xD6, 0x8B, 0x4D, 0xBC, 0x8B, 0x41, 0x04, 0x8B, 0x55, 0xEC, 0x03, 0xC8, 0x89, 0x4D, 0xBC, 0x8B, 0x82, 0xA4, 0x00, 0x00, 0x00, 0x03, 0x82, 0xA0, 0x00, 0x00, 0x00, 0x03, 0xC3, 0x3B, 0xC8, 0x73, 0x05, 0x83, 0x39, 0x00, 0x75, 0xA1, 0x8B, 0x75, 0x08, 0x8B, 0x7D, 0xB8, 0x8B, 0x45, 0xB4, 0x01, 0x42, 0x34, 0x8B, 0x5D, 0xF4, 0x8B, 0x45, 0xE4, 0xA9, 0x00, 0x00, 0x40, 0x00, 0x74, 0x3D, 0x83, 0xBA, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x74, 0x34, 0x8B, 0xCB, 0x8B, 0xC1, 0x3D, 0x4E, 0xE6, 0x40, 0xBB, 0x75, 0x05, 0x8D, 0x4B, 0x01, 0xEB, 0x14, 0xA9, 0x00, 0x00, 0xFF, 0xFF, 0x75, 0x0D, 0x8B, 0xC8, 0x81, 0xC9, 0x11, 0x47, 0x00, 0x00, 0xC1, 0xE1, 0x10, 0x0B, 0xC8, 0x8B, 0x82, 0xC8, 0x00, 0x00, 0x00, 0x89, 0x4C, 0x18, 0x3C, 0x8B, 0x5D, 0xF4, 0x8B, 0x45, 0xE4, 0xA9, 0x00, 0x00, 0x82, 0x00, 0x0F, 0x84, 0x4C, 0x05, 0x00, 0x00, 0x83, 0xBA, 0x84, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x84, 0x3F, 0x05, 0x00, 0x00, 0x8B, 0x8A, 0x80, 0x00, 0x00, 0x00, 0x03, 0xCB, 0x89, 0x4D, 0xB8, 0x0F, 0x84, 0x2E, 0x05, 0x00, 0x00, 0x66, 0x90, 0x8B, 0x41, 0x0C, 0x85, 0xC0, 0x0F, 0x84, 0x1E, 0x05, 0x00, 0x00, 0x6A, 0x08, 0x6A, 0x08, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0x03, 0xD8, 0xC7, 0x45, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x86, 0x84, 0x04, 0x00, 0x00, 0x89, 0x5D, 0xC8, 0xC7, 0x45, 0xCC, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0xF8, 0x89, 0x7D, 0xC4, 0x85, 0xFF, 0x75, 0x0A, 0xBF, 0x03, 0x00, 0x40, 0x00, 0xE9, 0xE6, + 0x03, 0x00, 0x00, 0x80, 0x3B, 0x00, 0x8B, 0xC3, 0x0F, 0xB7, 0xD3, 0x8B, 0xCA, 0x74, 0x0A, 0x90, 0x40, 0x0F, 0xB7, 0xC8, 0x80, 0x38, 0x00, 0x75, 0xF7, 0x2B, 0xCA, 0x0F, 0xB7, 0xD9, 0x66, 0x85, 0xDB, 0x0F, 0x84, 0x5D, 0x06, 0x00, 0x00, 0x8B, 0x8E, 0x84, 0x04, 0x00, 0x00, 0x8B, 0xC3, 0x89, 0x45, 0xAC, 0x40, 0x50, 0x6A, 0x08, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD1, 0x8B, 0xC8, 0x89, 0x4F, 0x04, 0x85, 0xC9, 0x0F, 0x84, 0x39, 0x06, 0x00, 0x00, 0x53, 0xFF, 0x75, 0xC8, 0x8D, 0x43, 0x01, 0x66, 0x89, 0x1F, 0x66, 0x89, 0x47, 0x02, 0x8B, 0x86, 0x7C, 0x04, 0x00, 0x00, 0x51, 0xFF, 0xD0, 0x8B, 0x86, 0x84, 0x04, 0x00, 0x00, 0x83, 0xC4, 0x0C, 0x6A, 0x08, 0x6A, 0x08, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0xD8, 0x85, 0xDB, 0x75, 0x32, 0x8B, 0x47, 0x04, 0x85, 0xC0, 0x74, 0x10, 0x50, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x53, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x57, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xBF, 0x03, 0x00, 0x40, 0x00, 0xE9, 0x3A, 0x03, 0x00, 0x00, 0x8B, 0x86, 0x84, 0x04, 0x00, 0x00, 0x68, 0x08, 0x02, 0x00, 0x00, 0x6A, 0x08, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x89, 0x43, 0x04, 0xB9, 0x08, 0x02, 0x00, 0x00, 0x66, 0x89, 0x4B, 0x02, 0x85, 0xC0, 0x75, 0x43, 0x53, 0x50, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x47, 0x04, 0x85, 0xC0, 0x74, 0x11, 0x50, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x57, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xBF, 0x03, 0x00, 0x40, 0x00, 0xE9, 0xD2, 0x02, 0x00, 0x00, 0x8B, 0x86, 0x9C, 0x04, 0x00, 0x00, 0x6A, 0x00, 0x57, 0x53, 0xFF, 0xD0, 0x8B, 0xF8, 0x0F, 0xAE, 0xE8, 0x85, 0xFF, 0x0F, 0x88, 0xFA, 0x04, 0x00, 0x00, 0x8B, 0x7D, 0xC4, 0x8B, 0x47, 0x04, 0x85, 0xC0, 0x74, 0x11, 0x50, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x57, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x86, 0x40, 0x04, 0x00, 0x00, 0x83, 0xF8, 0x64, 0x0F, 0x82, 0x0A, 0x01, 0x00, 0x00, 0x8B, 0x86, 0x84, 0x04, 0x00, 0x00, 0x68, 0x08, 0x01, 0x00, 0x00, 0x6A, 0x08, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0xC8, 0x89, 0x4D, 0xC8, 0x0F, 0xAE, 0xE8, 0x85, 0xC9, 0x0F, 0x84, 0x64, 0x04, 0x00, 0x00, 0xB8, 0x00, 0x01, 0x00, 0x00, 0x8D, 0x55, 0xBC, 0x66, 0x89, 0x41, 0x02, 0x8D, 0x41, 0x08, 0x89, 0x41, 0x04, 0x8B, 0x86, 0xA0, 0x04, 0x00, 0x00, 0x52, 0x8B, 0xD1, 0xC7, 0x45, 0xBC, 0x00, 0x00, 0x00, 0x00, 0x6A, 0x00, 0x8B, 0xCB, 0xFF, 0xD0, 0x8B, 0xF8, 0x85, 0xFF, 0x0F, 0x88, 0xEB, 0x03, 0x00, 0x00, 0x8B, 0x86, 0x84, 0x04, 0x00, 0x00, 0x6A, 0x50, 0x6A, 0x08, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0xC8, 0x89, 0x4D, 0xAC, 0x85, 0xC9, 0x0F, 0x84, 0x7D, 0x03, 0x00, 0x00, 0x81, 0xBE, 0x44, 0x04, 0x00, 0x00, 0x5A, 0x29, 0x00, 0x00, 0x8B, 0x43, 0x04, 0x77, 0x05, 0x89, + 0x41, 0x0C, 0xEB, 0x03, 0x89, 0x41, 0x10, 0x81, 0xBE, 0x44, 0x04, 0x00, 0x00, 0x63, 0x4A, 0x00, 0x00, 0x8D, 0x55, 0xB4, 0xC7, 0x45, 0xB4, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x90, 0x04, 0x00, 0x00, 0x76, 0x19, 0x6A, 0x00, 0x52, 0x8D, 0x55, 0xCC, 0x52, 0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x04, 0xFF, 0x75, 0xBC, 0x8B, 0xD1, 0x8B, 0x4D, 0xC8, 0xFF, 0xD0, 0xEB, 0x15, 0x52, 0x8D, 0x55, 0xCC, 0x52, 0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x04, 0xFF, 0x75, 0xBC, 0x8B, 0xD1, 0x8B, 0x4D, 0xC8, 0xFF, 0xD0, 0xFF, 0x75, 0xAC, 0x8B, 0xF8, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x0F, 0xAE, 0xE8, 0xFF, 0x75, 0xC8, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xE9, 0xD8, 0x00, 0x00, 0x00, 0x83, 0xF8, 0x3F, 0x75, 0x4E, 0x8B, 0x86, 0x84, 0x04, 0x00, 0x00, 0x6A, 0x14, 0x6A, 0x08, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0xC8, 0x89, 0x4D, 0xC4, 0x85, 0xC9, 0x0F, 0x84, 0x83, 0x00, 0x00, 0x00, 0x8D, 0x55, 0xAC, 0x52, 0x0F, 0xAE, 0xE8, 0x8B, 0x43, 0x04, 0x8D, 0x55, 0xCC, 0x52, 0x89, 0x41, 0x0C, 0x8B, 0xD1, 0x8B, 0x86, 0x8C, 0x04, 0x00, 0x00, 0x8B, 0xCB, 0x6A, 0x01, 0x6A, 0x00, 0xC7, 0x45, 0xAC, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xD0, 0xFF, 0x75, 0xC4, 0x8B, 0xF8, 0xEB, 0x98, 0x83, 0xF8, 0x3E, 0x75, 0x56, 0x8B, 0x86, 0x84, 0x04, 0x00, 0x00, 0x6A, 0x18, 0x6A, 0x08, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0xC8, 0x89, 0x4D, 0xC4, 0x85, 0xC9, 0x74, 0x34, 0x8D, 0x55, 0xAC, 0x52, 0x8D, 0x55, 0xCC, 0x52, 0x6A, 0x01, 0x0F, 0xAE, 0xE8, 0x8B, 0x43, 0x04, 0x6A, 0x00, 0x51, 0x89, 0x41, 0x04, 0xC6, 0x41, 0x08, 0x01, 0x8B, 0x86, 0x8C, 0x04, 0x00, 0x00, 0x53, 0xC7, 0x45, 0xAC, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xD0, 0xFF, 0x75, 0xC4, 0x8B, 0xF8, 0xE9, 0x44, 0xFF, 0xFF, 0xFF, 0xBF, 0x17, 0x00, 0x00, 0xC0, 0xEB, 0x2A, 0x83, 0xF8, 0x3D, 0x75, 0x20, 0x8D, 0x4D, 0xCC, 0x51, 0x6A, 0x00, 0x6A, 0x01, 0x6A, 0x00, 0x0F, 0xAE, 0xE8, 0xFF, 0xB6, 0xD0, 0x04, 0x00, 0x00, 0x8B, 0x86, 0x8C, 0x04, 0x00, 0x00, 0x53, 0xFF, 0xD0, 0x8B, 0xF8, 0xEB, 0x05, 0xBF, 0x02, 0x00, 0x00, 0xC0, 0x0F, 0xAE, 0xE8, 0x8B, 0x43, 0x04, 0x85, 0xC0, 0x74, 0x11, 0x50, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x53, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x85, 0xFF, 0x0F, 0x88, 0x13, 0x03, 0x00, 0x00, 0x8B, 0x45, 0xCC, 0x85, 0xC0, 0x74, 0x4E, 0x8B, 0x58, 0x18, 0x8B, 0x8E, 0xD4, 0x04, 0x00, 0x00, 0x8B, 0x86, 0x84, 0x04, 0x00, 0x00, 0x6A, 0x0C, 0x6A, 0x08, 0x51, 0x89, 0x5D, 0xC0, 0xFF, 0xD0, 0x83, 0x7D, 0xD4, 0x00, 0x75, 0x13, 0x8B, 0xD0, 0x89, 0x55, 0xD4, 0x85, 0xD2, 0x74, 0x2B, 0x89, 0x12, 0x89, 0x52, 0x04, 0x89, 0x5A, 0x08, 0xEB, 0x21, 0x85, 0xC0, 0x74, 0x1D, 0x8B, 0x55, 0xD4, 0x8B, 0x4A, 0x04, 0x89, 0x01, 0x8B, 0x4A, 0x04, 0x89, 0x48, 0x04, 0x89, 0x42, 0x04, 0x89, 0x10, 0x89, 0x58, 0x08, 0xEB, 0x05, 0xBF, 0x35, 0x01, 0x00, 0xC0, 0x85, 0xFF, 0x0F, 0x88, 0xB1, 0x02, 0x00, + 0x00, 0x8B, 0x55, 0xB8, 0x8B, 0x5D, 0xF4, 0x8B, 0x0A, 0x8B, 0x52, 0x10, 0x03, 0xD3, 0x85, 0xC9, 0x89, 0x55, 0xC8, 0x8D, 0x04, 0x19, 0x89, 0x55, 0xC4, 0x8B, 0xCA, 0x0F, 0x45, 0xC8, 0x89, 0x4D, 0xC8, 0x8B, 0x01, 0x85, 0xC0, 0x0F, 0x84, 0xB0, 0x00, 0x00, 0x00, 0x79, 0x16, 0x8B, 0x8E, 0x94, 0x04, 0x00, 0x00, 0x52, 0x0F, 0xB7, 0xC0, 0x50, 0x6A, 0x00, 0xFF, 0x75, 0xC0, 0xFF, 0xD1, 0x8B, 0xF8, 0xEB, 0x71, 0x6A, 0x08, 0x03, 0xC3, 0x6A, 0x08, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0x89, 0x45, 0xAC, 0x8B, 0x86, 0x84, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0xD8, 0x85, 0xDB, 0x0F, 0x84, 0x4E, 0x02, 0x00, 0x00, 0x8B, 0x4D, 0xAC, 0x83, 0xC1, 0x02, 0x89, 0x4B, 0x04, 0x0F, 0xB7, 0xD1, 0x8B, 0xC2, 0x80, 0x39, 0x00, 0x74, 0x0A, 0x90, 0x41, 0x0F, 0xB7, 0xC1, 0x80, 0x39, 0x00, 0x75, 0xF7, 0xFF, 0x75, 0xC4, 0x2B, 0xC2, 0x66, 0x89, 0x03, 0x40, 0x66, 0x89, 0x43, 0x02, 0x8B, 0x45, 0xC8, 0x8B, 0x8E, 0x94, 0x04, 0x00, 0x00, 0x0F, 0xB7, 0x00, 0x50, 0x53, 0xFF, 0x75, 0xC0, 0xFF, 0xD1, 0x53, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0x8B, 0xF8, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x85, 0xFF, 0x0F, 0x88, 0xF6, 0x01, 0x00, 0x00, 0x8B, 0x4D, 0xC8, 0x8B, 0x55, 0xC4, 0x83, 0xC1, 0x04, 0x8B, 0x5D, 0xF4, 0x83, 0xC2, 0x04, 0x89, 0x4D, 0xC8, 0x89, 0x55, 0xC4, 0x8B, 0x01, 0x85, 0xC0, 0x0F, 0x85, 0x50, 0xFF, 0xFF, 0xFF, 0x8B, 0x55, 0xEC, 0x8B, 0x4D, 0xB8, 0x83, 0xC1, 0x14, 0x89, 0x4D, 0xB8, 0x8B, 0x82, 0x84, 0x00, 0x00, 0x00, 0x03, 0x82, 0x80, 0x00, 0x00, 0x00, 0x03, 0xC3, 0x3B, 0xC8, 0x73, 0x08, 0x85, 0xC9, 0x0F, 0x85, 0xD7, 0xFA, 0xFF, 0xFF, 0x8B, 0x45, 0xE4, 0x25, 0x00, 0x00, 0x04, 0x00, 0x89, 0x45, 0xA0, 0x0F, 0x84, 0x0D, 0x09, 0x00, 0x00, 0x83, 0xBA, 0xE4, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x84, 0x00, 0x09, 0x00, 0x00, 0x8B, 0x82, 0xE0, 0x00, 0x00, 0x00, 0xC6, 0x45, 0xFA, 0x00, 0x03, 0xC3, 0x0F, 0x84, 0xEE, 0x08, 0x00, 0x00, 0x8D, 0x50, 0x08, 0x89, 0x55, 0xBC, 0x90, 0x8B, 0x42, 0xFC, 0x85, 0xC0, 0x0F, 0x84, 0xDE, 0x06, 0x00, 0x00, 0x03, 0xD8, 0x33, 0xC0, 0x6A, 0x08, 0x6A, 0x08, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0x89, 0x45, 0xC4, 0x89, 0x45, 0xC8, 0x8B, 0x86, 0x84, 0x04, 0x00, 0x00, 0x89, 0x5D, 0xA4, 0xFF, 0xD0, 0x8B, 0xF8, 0x89, 0x7D, 0xB4, 0x85, 0xFF, 0x0F, 0x85, 0xB9, 0x01, 0x00, 0x00, 0xBF, 0x03, 0x00, 0x40, 0x00, 0xE9, 0x92, 0x05, 0x00, 0x00, 0x0F, 0xAE, 0xE8, 0x0F, 0xAE, 0xE8, 0xFF, 0x75, 0xC8, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x43, 0x04, 0x85, 0xC0, 0x74, 0x11, 0x50, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x53, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xBF, 0x17, 0x00, 0x00, 0xC0, 0xE9, 0xEA, 0x00, 0x00, 0x00, 0x0F, 0xAE, 0xE8, 0xFF, 0x75, 0xC8, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x43, 0x04, 0x85, 0xC0, 0x74, 0x11, 0x50, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, + 0xFF, 0xD0, 0x53, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xE9, 0xA3, 0x00, 0x00, 0x00, 0x8B, 0x43, 0x04, 0x85, 0xC0, 0x74, 0x11, 0x50, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x53, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xBF, 0x17, 0x00, 0x00, 0xC0, 0xEB, 0x70, 0x8B, 0x43, 0x04, 0x85, 0xC0, 0x74, 0x11, 0x50, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x53, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x5D, 0xC4, 0x8B, 0x43, 0x04, 0x85, 0xC0, 0x74, 0x11, 0x50, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x53, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xEB, 0x16, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x57, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xBF, 0x74, 0x03, 0x00, 0xC0, 0x8B, 0x45, 0xD4, 0x0F, 0xAE, 0xE8, 0x89, 0x7E, 0x08, 0x85, 0xC0, 0x74, 0x32, 0x8B, 0x78, 0x04, 0x8B, 0xDF, 0x0F, 0x1F, 0x40, 0x00, 0xFF, 0x77, 0x08, 0x8B, 0x86, 0x98, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x7F, 0x04, 0x8B, 0x07, 0x85, 0xC0, 0x74, 0x11, 0x50, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x3B, 0xFB, 0x75, 0xD7, 0x68, 0x00, 0x80, 0x00, 0x00, 0x8D, 0x45, 0xE8, 0xC7, 0x45, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x50, 0x8D, 0x45, 0xD8, 0x50, 0x8B, 0x86, 0x70, 0x04, 0x00, 0x00, 0x6A, 0xFF, 0xFF, 0xD0, 0xFF, 0x75, 0xF0, 0x8B, 0x86, 0x5C, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xB8, 0x0A, 0x00, 0x40, 0x00, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x80, 0x3B, 0x00, 0x8B, 0xC3, 0x0F, 0xB7, 0xD3, 0x8B, 0xCA, 0x74, 0x0D, 0x0F, 0x1F, 0x40, 0x00, 0x40, 0x0F, 0xB7, 0xC8, 0x80, 0x38, 0x00, 0x75, 0xF7, 0x2B, 0xCA, 0x0F, 0xB7, 0xD9, 0x66, 0x85, 0xDB, 0x0F, 0x84, 0xB2, 0x06, 0x00, 0x00, 0x8B, 0x8E, 0x84, 0x04, 0x00, 0x00, 0x8B, 0xC3, 0x89, 0x45, 0xC0, 0x40, 0x50, 0x6A, 0x08, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD1, 0x89, 0x47, 0x04, 0x85, 0xC0, 0x0F, 0x84, 0x90, 0x06, 0x00, 0x00, 0x53, 0xFF, 0x75, 0xA4, 0x8D, 0x4B, 0x01, 0x66, 0x89, 0x1F, 0x66, 0x89, 0x4F, 0x02, 0x50, 0x8B, 0x86, 0x7C, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x86, 0x84, 0x04, 0x00, 0x00, 0x83, 0xC4, 0x0C, 0x6A, 0x08, 0x6A, 0x08, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0xD8, 0x85, 0xDB, 0x75, 0x32, 0x8B, 0x47, 0x04, 0x85, 0xC0, 0x74, 0x10, 0x50, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x53, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x57, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xBF, 0x03, 0x00, 0x40, 0x00, 0xE9, 0x36, 0x03, 0x00, 0x00, 0x8B, 0x86, 0x84, 0x04, 0x00, 0x00, 0x68, 0x08, 0x02, 0x00, 0x00, 0x6A, 0x08, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, + 0xFF, 0xD0, 0x89, 0x43, 0x04, 0xB9, 0x08, 0x02, 0x00, 0x00, 0x66, 0x89, 0x4B, 0x02, 0x85, 0xC0, 0x75, 0x43, 0x53, 0x50, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x47, 0x04, 0x85, 0xC0, 0x74, 0x11, 0x50, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x57, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xBF, 0x03, 0x00, 0x40, 0x00, 0xE9, 0xCE, 0x02, 0x00, 0x00, 0x8B, 0x86, 0x9C, 0x04, 0x00, 0x00, 0x6A, 0x00, 0x57, 0x53, 0xFF, 0xD0, 0x8B, 0xF8, 0x0F, 0xAE, 0xE8, 0x85, 0xFF, 0x0F, 0x88, 0x4E, 0x05, 0x00, 0x00, 0x8B, 0x7D, 0xB4, 0x8B, 0x47, 0x04, 0x85, 0xC0, 0x74, 0x11, 0x50, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x57, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x86, 0x40, 0x04, 0x00, 0x00, 0x83, 0xF8, 0x64, 0x0F, 0x82, 0x08, 0x01, 0x00, 0x00, 0x8B, 0x86, 0x84, 0x04, 0x00, 0x00, 0x68, 0x08, 0x01, 0x00, 0x00, 0x6A, 0x08, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0xD0, 0x89, 0x55, 0xC0, 0x0F, 0xAE, 0xE8, 0x85, 0xD2, 0x0F, 0x84, 0xB5, 0x04, 0x00, 0x00, 0x8D, 0x4A, 0x08, 0xB8, 0x00, 0x01, 0x00, 0x00, 0x89, 0x4A, 0x04, 0x8D, 0x4D, 0xB8, 0x51, 0x66, 0x89, 0x42, 0x02, 0x8B, 0xCB, 0x8B, 0x86, 0xA0, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xC7, 0x45, 0xB8, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0xF8, 0x85, 0xFF, 0x0F, 0x88, 0x3E, 0x04, 0x00, 0x00, 0x8B, 0x86, 0x84, 0x04, 0x00, 0x00, 0x6A, 0x50, 0x6A, 0x08, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0xC8, 0x89, 0x4D, 0xA4, 0x85, 0xC9, 0x0F, 0x84, 0xD0, 0x03, 0x00, 0x00, 0x81, 0xBE, 0x44, 0x04, 0x00, 0x00, 0x5A, 0x29, 0x00, 0x00, 0x8B, 0x43, 0x04, 0x77, 0x05, 0x89, 0x41, 0x0C, 0xEB, 0x03, 0x89, 0x41, 0x10, 0x81, 0xBE, 0x44, 0x04, 0x00, 0x00, 0x63, 0x4A, 0x00, 0x00, 0x8D, 0x55, 0xAC, 0xC7, 0x45, 0xAC, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x90, 0x04, 0x00, 0x00, 0x76, 0x19, 0x6A, 0x00, 0x52, 0x8D, 0x55, 0xC8, 0x52, 0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x04, 0xFF, 0x75, 0xB8, 0x8B, 0xD1, 0x8B, 0x4D, 0xC0, 0xFF, 0xD0, 0xEB, 0x15, 0x52, 0x8D, 0x55, 0xC8, 0x52, 0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x04, 0xFF, 0x75, 0xB8, 0x8B, 0xD1, 0x8B, 0x4D, 0xC0, 0xFF, 0xD0, 0xFF, 0x75, 0xA4, 0x8B, 0xF8, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x0F, 0xAE, 0xE8, 0xFF, 0x75, 0xC0, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xE9, 0xD6, 0x00, 0x00, 0x00, 0x83, 0xF8, 0x3F, 0x75, 0x4C, 0x8B, 0x86, 0x84, 0x04, 0x00, 0x00, 0x6A, 0x14, 0x6A, 0x08, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x89, 0x45, 0xB4, 0x85, 0xC0, 0x0F, 0x84, 0x83, 0x00, 0x00, 0x00, 0x0F, 0xAE, 0xE8, 0x8B, 0x4B, 0x04, 0x8B, 0xD0, 0x89, 0x48, 0x0C, 0x8D, 0x4D, 0xA4, 0x8B, 0xBE, 0x8C, 0x04, 0x00, 0x00, 0x51, 0x8D, 0x4D, 0xC8, 0xC7, 0x45, 0xA4, 0x00, 0x00, 0x00, + 0x00, 0x51, 0x6A, 0x01, 0x6A, 0x00, 0x8B, 0xCB, 0xFF, 0xD7, 0xFF, 0x75, 0xB4, 0x8B, 0xF8, 0xEB, 0x9A, 0x83, 0xF8, 0x3E, 0x75, 0x56, 0x8B, 0x86, 0x84, 0x04, 0x00, 0x00, 0x6A, 0x18, 0x6A, 0x08, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0xD0, 0x89, 0x55, 0xB4, 0x85, 0xD2, 0x74, 0x34, 0x0F, 0xAE, 0xE8, 0x8B, 0x4B, 0x04, 0x89, 0x4A, 0x04, 0x8D, 0x4D, 0xA4, 0x51, 0x8D, 0x4D, 0xC8, 0xC6, 0x42, 0x08, 0x01, 0x8B, 0x86, 0x8C, 0x04, 0x00, 0x00, 0x51, 0x6A, 0x01, 0x6A, 0x00, 0x52, 0x53, 0xC7, 0x45, 0xA4, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xD0, 0xFF, 0x75, 0xB4, 0x8B, 0xF8, 0xE9, 0x46, 0xFF, 0xFF, 0xFF, 0xBF, 0x17, 0x00, 0x00, 0xC0, 0xEB, 0x2A, 0x83, 0xF8, 0x3D, 0x75, 0x20, 0x8D, 0x4D, 0xC8, 0x51, 0x6A, 0x00, 0x6A, 0x01, 0x6A, 0x00, 0x0F, 0xAE, 0xE8, 0xFF, 0xB6, 0xD0, 0x04, 0x00, 0x00, 0x8B, 0x86, 0x8C, 0x04, 0x00, 0x00, 0x53, 0xFF, 0xD0, 0x8B, 0xF8, 0xEB, 0x05, 0xBF, 0x02, 0x00, 0x00, 0xC0, 0x0F, 0xAE, 0xE8, 0x8B, 0x43, 0x04, 0x85, 0xC0, 0x74, 0x11, 0x50, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x53, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x85, 0xFF, 0x0F, 0x88, 0x82, 0x01, 0x00, 0x00, 0x8B, 0x45, 0xC8, 0x85, 0xC0, 0x74, 0x4E, 0x8B, 0x58, 0x18, 0x8B, 0x8E, 0xD4, 0x04, 0x00, 0x00, 0x8B, 0x86, 0x84, 0x04, 0x00, 0x00, 0x6A, 0x0C, 0x6A, 0x08, 0x51, 0x89, 0x5D, 0xC4, 0xFF, 0xD0, 0x83, 0x7D, 0xD0, 0x00, 0x75, 0x13, 0x8B, 0xD0, 0x89, 0x55, 0xD0, 0x85, 0xD2, 0x74, 0x2B, 0x89, 0x12, 0x89, 0x52, 0x04, 0x89, 0x5A, 0x08, 0xEB, 0x21, 0x85, 0xC0, 0x74, 0x1D, 0x8B, 0x55, 0xD0, 0x8B, 0x4A, 0x04, 0x89, 0x01, 0x8B, 0x4A, 0x04, 0x89, 0x48, 0x04, 0x89, 0x42, 0x04, 0x89, 0x10, 0x89, 0x58, 0x08, 0xEB, 0x05, 0xBF, 0x35, 0x01, 0x00, 0xC0, 0x85, 0xFF, 0x0F, 0x88, 0x20, 0x01, 0x00, 0x00, 0x8B, 0x45, 0xBC, 0x8B, 0x55, 0xC4, 0x8B, 0x08, 0x85, 0xC9, 0x74, 0x09, 0x8B, 0x45, 0xF4, 0x89, 0x14, 0x01, 0x8B, 0x45, 0xBC, 0x8B, 0x48, 0x04, 0x8B, 0x5D, 0xF4, 0x03, 0xCB, 0x8B, 0x40, 0x08, 0x03, 0xC3, 0x89, 0x4D, 0xC0, 0x89, 0x45, 0xB4, 0x83, 0x39, 0x00, 0x0F, 0x84, 0xB6, 0x00, 0x00, 0x00, 0x8B, 0x00, 0x85, 0xC0, 0x79, 0x12, 0x51, 0x0F, 0xB7, 0xC0, 0x50, 0x8B, 0x86, 0x94, 0x04, 0x00, 0x00, 0x6A, 0x00, 0x52, 0xFF, 0xD0, 0xEB, 0x71, 0x6A, 0x08, 0x03, 0xC3, 0x6A, 0x08, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0x89, 0x45, 0xA4, 0x8B, 0x86, 0x84, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0xD8, 0x85, 0xDB, 0x74, 0x7A, 0x8B, 0x4D, 0xA4, 0x83, 0xC1, 0x02, 0x89, 0x4B, 0x04, 0x0F, 0xB7, 0xD1, 0x8B, 0xC2, 0x80, 0x39, 0x00, 0x74, 0x0D, 0x0F, 0x1F, 0x40, 0x00, 0x41, 0x0F, 0xB7, 0xC1, 0x80, 0x39, 0x00, 0x75, 0xF7, 0xFF, 0x75, 0xC0, 0x2B, 0xC2, 0x66, 0x89, 0x03, 0x40, 0x66, 0x89, 0x43, 0x02, 0x8B, 0x45, 0xB4, 0x8B, 0x8E, 0x94, 0x04, 0x00, 0x00, 0x0F, 0xB7, 0x00, 0x50, 0x8B, 0x45, 0xC4, 0x53, 0x50, 0xFF, 0xD1, 0x53, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0x8B, 0xF8, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x5D, 0xF4, 0x85, 0xFF, 0x78, 0x22, 0x8B, 0x4D, 0xC0, 0x8B, + 0x45, 0xB4, 0x83, 0xC1, 0x04, 0x83, 0xC0, 0x04, 0x89, 0x4D, 0xC0, 0x89, 0x45, 0xB4, 0x83, 0x39, 0x00, 0x74, 0x0F, 0x8B, 0x55, 0xC4, 0xE9, 0x51, 0xFF, 0xFF, 0xFF, 0x8B, 0x5D, 0xF4, 0xC6, 0x45, 0xFA, 0x01, 0x8B, 0x45, 0xEC, 0x8B, 0x55, 0xBC, 0x8B, 0x75, 0xEC, 0x83, 0xC2, 0x20, 0x89, 0x55, 0xBC, 0x8B, 0x80, 0xE0, 0x00, 0x00, 0x00, 0x03, 0xC3, 0x03, 0x86, 0xE4, 0x00, 0x00, 0x00, 0x8D, 0x4A, 0xF8, 0x8B, 0x75, 0x08, 0x3B, 0xC8, 0x73, 0x08, 0x85, 0xC9, 0x0F, 0x85, 0x17, 0xF9, 0xFF, 0xFF, 0x80, 0x7D, 0xFA, 0x00, 0x0F, 0x84, 0xF1, 0x01, 0x00, 0x00, 0x8B, 0x45, 0xD0, 0x0F, 0xAE, 0xE8, 0x89, 0x7E, 0x08, 0x85, 0xC0, 0x74, 0x2E, 0x8B, 0x78, 0x04, 0x8B, 0xDF, 0xFF, 0x77, 0x08, 0x8B, 0x86, 0x98, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x7F, 0x04, 0x8B, 0x07, 0x85, 0xC0, 0x74, 0x11, 0x50, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x3B, 0xFB, 0x75, 0xD7, 0x8B, 0x45, 0xD4, 0x85, 0xC0, 0x74, 0x34, 0x8B, 0x78, 0x04, 0x8B, 0xDF, 0x66, 0x0F, 0x1F, 0x44, 0x00, 0x00, 0xFF, 0x77, 0x08, 0x8B, 0x86, 0x98, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x7F, 0x04, 0x8B, 0x07, 0x85, 0xC0, 0x74, 0x11, 0x50, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x3B, 0xFB, 0x75, 0xD7, 0x68, 0x00, 0x80, 0x00, 0x00, 0x8D, 0x45, 0xE8, 0xC7, 0x45, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x50, 0x8D, 0x45, 0xD8, 0x50, 0x8B, 0x86, 0x70, 0x04, 0x00, 0x00, 0x6A, 0xFF, 0xFF, 0xD0, 0xFF, 0x75, 0xF0, 0x8B, 0x86, 0x5C, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xB8, 0x0B, 0x00, 0x40, 0x00, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x0F, 0xAE, 0xE8, 0x0F, 0xAE, 0xE8, 0xFF, 0x75, 0xC0, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x43, 0x04, 0x85, 0xC0, 0x74, 0x11, 0x50, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x53, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xBF, 0x17, 0x00, 0x00, 0xC0, 0xE9, 0x04, 0xFF, 0xFF, 0xFF, 0x0F, 0xAE, 0xE8, 0xFF, 0x75, 0xC0, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x43, 0x04, 0x85, 0xC0, 0x74, 0x11, 0x50, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x53, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xE9, 0xBD, 0xFE, 0xFF, 0xFF, 0x8B, 0x43, 0x04, 0x85, 0xC0, 0x74, 0x11, 0x50, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x53, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xBF, 0x17, 0x00, 0x00, 0xC0, 0xE9, 0x87, 0xFE, 0xFF, 0xFF, 0x8B, 0x43, 0x04, 0x85, 0xC0, 0x74, 0x11, 0x50, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x53, 0x6A, + 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x5D, 0xB4, 0x8B, 0x43, 0x04, 0x85, 0xC0, 0x74, 0x11, 0x50, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x53, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xE9, 0x2A, 0xFE, 0xFF, 0xFF, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x57, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xBF, 0x74, 0x03, 0x00, 0xC0, 0xE9, 0x0F, 0xFE, 0xFF, 0xFF, 0x8B, 0x55, 0xEC, 0x8B, 0x45, 0xE4, 0x25, 0x00, 0x00, 0x20, 0x00, 0x89, 0x45, 0xB8, 0x0F, 0x84, 0x9D, 0x01, 0x00, 0x00, 0x8D, 0x4D, 0xAC, 0x51, 0x6A, 0x20, 0x8D, 0x4D, 0xA4, 0x51, 0x0F, 0xAE, 0xE8, 0x8B, 0x42, 0x54, 0x8D, 0x4D, 0xF4, 0x51, 0x89, 0x45, 0xA4, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x6A, 0xFF, 0xC7, 0x45, 0xAC, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0xD0, 0x85, 0xD2, 0x0F, 0x88, 0xBD, 0x00, 0x00, 0x00, 0x8B, 0x4D, 0xEC, 0x0F, 0xAE, 0xE8, 0x8B, 0x5D, 0xF4, 0xC7, 0x45, 0xB4, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xB7, 0x79, 0x14, 0x83, 0xC7, 0x3C, 0x66, 0x83, 0x79, 0x06, 0x00, 0x0F, 0x84, 0x4C, 0x01, 0x00, 0x00, 0x03, 0xF9, 0x66, 0x90, 0x8B, 0x47, 0xE8, 0x8B, 0x0F, 0x03, 0xC3, 0x89, 0x45, 0xC0, 0x8B, 0x47, 0xEC, 0x89, 0x45, 0xBC, 0x85, 0xC0, 0x74, 0x63, 0xF7, 0xC1, 0x00, 0x00, 0x00, 0x20, 0x74, 0x1D, 0x85, 0xC9, 0x79, 0x07, 0xB9, 0x40, 0x00, 0x00, 0x00, 0xEB, 0x30, 0x81, 0xE1, 0x00, 0x00, 0x00, 0x40, 0xF7, 0xD9, 0x1B, 0xC9, 0x83, 0xE1, 0x10, 0x83, 0xC1, 0x10, 0xEB, 0x1E, 0x85, 0xC9, 0x79, 0x07, 0xB9, 0x04, 0x00, 0x00, 0x00, 0xEB, 0x13, 0xF7, 0xC1, 0x00, 0x00, 0x00, 0x40, 0xB8, 0x02, 0x00, 0x00, 0x00, 0xB9, 0x01, 0x00, 0x00, 0x00, 0x0F, 0x45, 0xC8, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x8D, 0x55, 0xAC, 0x52, 0x51, 0x8D, 0x4D, 0xBC, 0x51, 0x8D, 0x4D, 0xC0, 0x51, 0x6A, 0xFF, 0xFF, 0xD0, 0x8B, 0xD0, 0x85, 0xD2, 0x78, 0x23, 0x8B, 0x5D, 0xF4, 0x8B, 0x45, 0xEC, 0x83, 0xC7, 0x28, 0xFF, 0x45, 0xB4, 0x8B, 0xCA, 0x0F, 0xB7, 0x40, 0x06, 0x39, 0x45, 0xB4, 0x0F, 0x85, 0x71, 0xFF, 0xFF, 0xFF, 0x85, 0xC9, 0x0F, 0x89, 0xAE, 0x00, 0x00, 0x00, 0x8B, 0x45, 0xD0, 0x0F, 0xAE, 0xE8, 0x89, 0x56, 0x08, 0x85, 0xC0, 0x74, 0x35, 0x8B, 0x78, 0x04, 0x8B, 0xDF, 0x0F, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x77, 0x08, 0x8B, 0x86, 0x98, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x7F, 0x04, 0x8B, 0x07, 0x85, 0xC0, 0x74, 0x11, 0x50, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x3B, 0xFB, 0x75, 0xD7, 0x8B, 0x45, 0xD4, 0x85, 0xC0, 0x74, 0x2E, 0x8B, 0x78, 0x04, 0x8B, 0xDF, 0xFF, 0x77, 0x08, 0x8B, 0x86, 0x98, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x7F, 0x04, 0x8B, 0x07, 0x85, 0xC0, 0x74, 0x11, 0x50, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x3B, 0xFB, 0x75, 0xD7, 0x68, 0x00, 0x80, 0x00, 0x00, 0x8D, 0x45, 0xE8, 0xC7, 0x45, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x50, 0x8D, 0x45, 0xD8, 0x50, 0x8B, 0x86, 0x70, 0x04, 0x00, 0x00, 0x6A, 0xFF, 0xFF, 0xD0, 0xFF, 0x75, 0xF0, 0x8B, + 0x86, 0x5C, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xB8, 0x06, 0x00, 0x40, 0x00, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x8B, 0x4D, 0xEC, 0x83, 0x7D, 0xA8, 0x00, 0x0F, 0x84, 0x15, 0x02, 0x00, 0x00, 0x8B, 0x86, 0x40, 0x04, 0x00, 0x00, 0x83, 0xF8, 0x3F, 0x72, 0x0F, 0x8B, 0x51, 0x50, 0x8B, 0xCB, 0x8B, 0x86, 0xA4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xEB, 0x2A, 0x83, 0xF8, 0x3E, 0x75, 0x0E, 0xFF, 0x71, 0x50, 0x8B, 0x86, 0xA4, 0x04, 0x00, 0x00, 0x53, 0xFF, 0xD0, 0xEB, 0x17, 0x83, 0xF8, 0x3D, 0x75, 0x15, 0xFF, 0x71, 0x50, 0x8B, 0x86, 0xA4, 0x04, 0x00, 0x00, 0x53, 0xFF, 0xB6, 0xCC, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x5D, 0xF4, 0x8B, 0x8E, 0xCC, 0x04, 0x00, 0x00, 0x33, 0xC0, 0xBA, 0x35, 0x01, 0x00, 0xC0, 0x8B, 0x09, 0x85, 0xC9, 0x74, 0x26, 0x83, 0xBE, 0x40, 0x04, 0x00, 0x00, 0x3E, 0x1B, 0xFF, 0x83, 0xE7, 0xFC, 0x83, 0xC7, 0x10, 0x03, 0xBE, 0xCC, 0x04, 0x00, 0x00, 0x39, 0x5F, 0x04, 0x0F, 0x84, 0xCB, 0x00, 0x00, 0x00, 0x40, 0x83, 0xC7, 0x10, 0x3B, 0xC1, 0x72, 0xEF, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x50, 0x04, 0x00, 0x00, 0x89, 0x56, 0x08, 0x85, 0xC0, 0x74, 0x09, 0x50, 0x8B, 0x86, 0xBC, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x45, 0xD0, 0x85, 0xC0, 0x74, 0x37, 0x8B, 0x78, 0x04, 0x8B, 0xDF, 0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x77, 0x08, 0x8B, 0x86, 0x98, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x7F, 0x04, 0x8B, 0x07, 0x85, 0xC0, 0x74, 0x11, 0x50, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x3B, 0xFB, 0x75, 0xD7, 0x8B, 0x45, 0xD4, 0x85, 0xC0, 0x74, 0x2E, 0x8B, 0x78, 0x04, 0x8B, 0xDF, 0xFF, 0x77, 0x08, 0x8B, 0x86, 0x98, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x7F, 0x04, 0x8B, 0x07, 0x85, 0xC0, 0x74, 0x11, 0x50, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x3B, 0xFB, 0x75, 0xD7, 0x68, 0x00, 0x80, 0x00, 0x00, 0x8D, 0x45, 0xE8, 0xC7, 0x45, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x50, 0x8D, 0x45, 0xD8, 0x50, 0x8B, 0x86, 0x70, 0x04, 0x00, 0x00, 0x6A, 0xFF, 0xFF, 0xD0, 0xFF, 0x75, 0xF0, 0x8B, 0x86, 0x5C, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xB8, 0x0C, 0x00, 0x40, 0x00, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x83, 0x7F, 0x0C, 0x00, 0x0F, 0x85, 0xC8, 0x00, 0x00, 0x00, 0x6A, 0x04, 0x68, 0x00, 0x30, 0x00, 0x00, 0x8D, 0x4D, 0xA8, 0x51, 0x6A, 0x00, 0x8D, 0x4D, 0xB4, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x68, 0x04, 0x00, 0x00, 0x51, 0x6A, 0xFF, 0xC7, 0x45, 0xB4, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x45, 0xA8, 0x00, 0x20, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0xD0, 0x85, 0xD2, 0x0F, 0x88, 0xFD, 0xFE, 0xFF, 0xFF, 0x8B, 0x15, 0x30, 0x03, 0xFE, 0x7F, 0x8B, 0xC2, 0x33, 0x55, 0xB4, 0x83, 0xE0, 0x1F, 0x8B, 0xC8, 0x8B, 0xDA, 0xF7, 0xD9, 0xD3, 0xE3, 0x8B, 0xC8, 0xD3, 0xEA, 0x0B, 0xDA, 0x83, 0xBE, 0x40, 0x04, 0x00, 0x00, 0x3F, 0x72, 0x33, 0x8B, 0x86, 0xB4, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xD0, 0x89, 0x45, 0xA4, 0x85, 0xC0, 0x79, 0x22, 0x68, 0x00, 0x80, 0x00, 0x00, 0x8D, 0x45, 0xA8, 0x50, 0x8D, 0x45, 0xB4, 0x50, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x70, 0x04, 0x00, 0x00, 0x6A, 0xFF, 0xFF, + 0xD0, 0x8B, 0x55, 0xA4, 0xE9, 0xA5, 0xFE, 0xFF, 0xFF, 0x89, 0x1F, 0x83, 0xBE, 0x40, 0x04, 0x00, 0x00, 0x3F, 0x72, 0x0A, 0x8B, 0x86, 0xB4, 0x04, 0x00, 0x00, 0x6A, 0x01, 0xFF, 0xD0, 0x80, 0x7D, 0xFB, 0x00, 0x74, 0x1C, 0x83, 0xBE, 0x50, 0x04, 0x00, 0x00, 0x00, 0x75, 0x13, 0xFF, 0x75, 0xB0, 0x8B, 0x86, 0xB8, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xD0, 0x89, 0x86, 0x50, 0x04, 0x00, 0x00, 0x8B, 0x5D, 0xF4, 0xF7, 0x45, 0xE4, 0x00, 0x00, 0x08, 0x00, 0x8B, 0x7D, 0xEC, 0x0F, 0x84, 0x13, 0x01, 0x00, 0x00, 0x83, 0xBF, 0xC4, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x84, 0x06, 0x01, 0x00, 0x00, 0x8B, 0x87, 0xC0, 0x00, 0x00, 0x00, 0x68, 0xB8, 0x00, 0x00, 0x00, 0x03, 0xC3, 0x6A, 0x08, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0x89, 0x45, 0xA4, 0x8B, 0x86, 0x84, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0xF8, 0x85, 0xFF, 0x0F, 0x85, 0x88, 0x00, 0x00, 0x00, 0x8B, 0x45, 0xD0, 0x0F, 0xAE, 0xE8, 0x85, 0xC0, 0x74, 0x31, 0x8B, 0x78, 0x04, 0x8B, 0xDF, 0x0F, 0x1F, 0x00, 0xFF, 0x77, 0x08, 0x8B, 0x86, 0x98, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x7F, 0x04, 0x8B, 0x07, 0x85, 0xC0, 0x74, 0x11, 0x50, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x3B, 0xFB, 0x75, 0xD7, 0x8B, 0x45, 0xD4, 0x85, 0xC0, 0x74, 0x2E, 0x8B, 0x78, 0x04, 0x8B, 0xDF, 0xFF, 0x77, 0x08, 0x8B, 0x86, 0x98, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x7F, 0x04, 0x8B, 0x07, 0x85, 0xC0, 0x74, 0x11, 0x50, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x3B, 0xFB, 0x75, 0xD7, 0x8D, 0x45, 0xE8, 0xC7, 0x45, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x80, 0x00, 0x00, 0x50, 0x8D, 0x45, 0xD8, 0xE9, 0xAA, 0xE8, 0xFF, 0xFF, 0x8B, 0x45, 0xF4, 0x89, 0x47, 0x18, 0x83, 0xBE, 0x40, 0x04, 0x00, 0x00, 0x3E, 0x8B, 0x86, 0xA8, 0x04, 0x00, 0x00, 0x77, 0x05, 0x57, 0xFF, 0xD0, 0xEB, 0x04, 0x8B, 0xCF, 0xFF, 0xD0, 0x8B, 0x86, 0x88, 0x04, 0x00, 0x00, 0x57, 0x6A, 0x00, 0xFF, 0xB6, 0xD4, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x7D, 0xA4, 0x8B, 0x7F, 0x0C, 0x85, 0xFF, 0x74, 0x15, 0x90, 0x8B, 0x07, 0x85, 0xC0, 0x74, 0x0E, 0x6A, 0x00, 0x6A, 0x01, 0xFF, 0x75, 0xF4, 0xFF, 0xD0, 0x83, 0xC7, 0x04, 0x75, 0xEC, 0x8B, 0x5D, 0xF4, 0x8B, 0x7D, 0xEC, 0x8B, 0x4D, 0xE4, 0xF7, 0xC1, 0x00, 0x00, 0x80, 0x00, 0x74, 0x65, 0x8B, 0x47, 0x28, 0x85, 0xC0, 0x74, 0x5E, 0xC7, 0x45, 0xA4, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x45, 0xA8, 0x00, 0x00, 0x00, 0x00, 0xF7, 0xC1, 0x00, 0x00, 0x00, 0x01, 0x74, 0x39, 0x8B, 0x86, 0xAC, 0x04, 0x00, 0x00, 0x8D, 0x4D, 0xA8, 0x51, 0x8D, 0x4D, 0xA4, 0x51, 0x6A, 0x00, 0xFF, 0xD0, 0x8B, 0x4D, 0xF4, 0x85, 0xC0, 0x8B, 0x47, 0x28, 0x6A, 0x00, 0x6A, 0x01, 0x0F, 0x99, 0xC3, 0x03, 0xC1, 0x51, 0xFF, 0xD0, 0x84, 0xDB, 0x74, 0x18, 0xFF, 0x75, 0xA8, 0x8B, 0x86, 0xB0, 0x04, 0x00, 0x00, 0x6A, 0x00, 0xFF, 0xD0, 0xEB, 0x09, 0x6A, 0x00, 0x6A, 0x01, 0x53, 0x03, 0xC3, 0xFF, 0xD0, 0x8B, 0x5D, 0xF4, 0x8B, 0x4D, 0xE4, 0x81, 0xE1, 0x00, 0x00, 0x21, 0x00, 0x81, 0xF9, 0x00, 0x00, 0x01, 0x00, 0x0F, 0x85, 0x85, 0x02, 0x00, 0x00, 0x83, 0xBF, 0x84, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x84, 0x91, 0x00, 0x00, + 0x00, 0x8B, 0xBF, 0x80, 0x00, 0x00, 0x00, 0x03, 0xFB, 0x8B, 0x47, 0x0C, 0x85, 0xC0, 0x74, 0x68, 0x80, 0x3C, 0x18, 0x00, 0x74, 0x05, 0xC6, 0x44, 0x18, 0x01, 0x00, 0x8B, 0x07, 0xC7, 0x47, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x55, 0xF4, 0x8D, 0x0C, 0x10, 0x85, 0xC0, 0x75, 0x05, 0x8B, 0x4F, 0x10, 0x03, 0xCA, 0x8B, 0x11, 0x85, 0xD2, 0x74, 0x23, 0x79, 0x08, 0xC7, 0x01, 0x00, 0x00, 0x00, 0x00, 0xEB, 0x0F, 0x8B, 0x45, 0xF4, 0x80, 0x7C, 0x10, 0x02, 0x00, 0x74, 0x05, 0xC6, 0x44, 0x10, 0x03, 0x00, 0x8B, 0x51, 0x04, 0x83, 0xC1, 0x04, 0x85, 0xD2, 0x75, 0xDD, 0xC7, 0x07, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x47, 0x10, 0x00, 0x00, 0x00, 0x00, 0x83, 0xC7, 0x14, 0x8B, 0x47, 0x0C, 0x85, 0xC0, 0x74, 0x05, 0x8B, 0x5D, 0xF4, 0xEB, 0x98, 0x8B, 0x7D, 0xEC, 0xC7, 0x87, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x87, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x5D, 0xF4, 0x83, 0xBF, 0xE4, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x84, 0xD2, 0x00, 0x00, 0x00, 0x83, 0x7D, 0xA0, 0x00, 0x0F, 0x85, 0xC8, 0x00, 0x00, 0x00, 0x8B, 0x87, 0xE0, 0x00, 0x00, 0x00, 0x03, 0xC3, 0x83, 0x78, 0x04, 0x00, 0x0F, 0x84, 0x9F, 0x00, 0x00, 0x00, 0x83, 0xC0, 0x0C, 0x89, 0x45, 0xA8, 0x0F, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x48, 0xF8, 0x80, 0x3C, 0x19, 0x00, 0x74, 0x05, 0xC6, 0x44, 0x19, 0x01, 0x00, 0x8B, 0x38, 0x8B, 0x50, 0x04, 0xC7, 0x40, 0xF8, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x40, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x75, 0xF4, 0x03, 0xFE, 0x03, 0xD6, 0x83, 0x3F, 0x00, 0x74, 0x3E, 0x0F, 0x1F, 0x00, 0x8B, 0x1A, 0x85, 0xDB, 0x79, 0x08, 0xC7, 0x02, 0x00, 0x00, 0x00, 0x00, 0xEB, 0x1A, 0x8A, 0x44, 0x33, 0x02, 0x84, 0xC0, 0x0F, 0xB6, 0xC8, 0xC7, 0x45, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x45, 0x4D, 0xA0, 0xFE, 0xC1, 0x88, 0x4C, 0x33, 0x02, 0x83, 0xC7, 0x04, 0x83, 0xC2, 0x04, 0x83, 0x3F, 0x00, 0x74, 0x05, 0x8B, 0x75, 0xF4, 0xEB, 0xC8, 0x8B, 0x45, 0xA8, 0xC7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x83, 0xC0, 0x20, 0x89, 0x45, 0xA8, 0x83, 0x78, 0xF8, 0x00, 0x74, 0x08, 0x8B, 0x5D, 0xF4, 0xE9, 0x74, 0xFF, 0xFF, 0xFF, 0x8B, 0x75, 0x08, 0x8B, 0x7D, 0xEC, 0xC7, 0x87, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x87, 0xE4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x5D, 0xF4, 0x83, 0xBF, 0xAC, 0x00, 0x00, 0x00, 0x00, 0x74, 0x48, 0x8B, 0xBF, 0xA8, 0x00, 0x00, 0x00, 0x03, 0xFB, 0x8B, 0x47, 0x14, 0xFF, 0x77, 0x10, 0x03, 0xC3, 0x50, 0x8B, 0x86, 0x80, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xC7, 0x47, 0x10, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x47, 0x14, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x47, 0x18, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x7D, 0xEC, 0xC7, 0x87, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x87, 0xAC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x5D, 0xF4, 0x83, 0xBF, 0xA4, 0x00, 0x00, 0x00, 0x00, 0x74, 0x4D, 0x8B, 0x8F, 0xA0, 0x00, 0x00, 0x00, 0x03, 0xCB, 0x89, 0x4D, 0x08, 0x83, 0x39, 0x00, 0x74, 0x26, 0x8B, 0x41, 0x04, 0x8D, 0x79, 0x04, 0x83, 0xE8, 0x08, 0x50, 0x8D, 0x41, 0x08, 0x50, 0x8B, 0x86, 0x80, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x4D, 0x08, + 0x03, 0x0F, 0x89, 0x4D, 0x08, 0x83, 0x39, 0x00, 0x75, 0xDD, 0x8B, 0x7D, 0xEC, 0xC7, 0x87, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x87, 0xA4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x5D, 0xF4, 0x83, 0xBF, 0xC4, 0x00, 0x00, 0x00, 0x00, 0x74, 0x58, 0x8B, 0x8F, 0xC0, 0x00, 0x00, 0x00, 0x03, 0xCB, 0x8B, 0x41, 0x0C, 0x85, 0xC0, 0x74, 0x10, 0x83, 0x38, 0x00, 0x74, 0x0B, 0xC7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0xC0, 0x04, 0x75, 0xF0, 0xC7, 0x41, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x41, 0x08, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x41, 0x04, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x41, 0x10, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x01, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x87, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x87, 0xC4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x5D, 0xF4, 0xF6, 0x45, 0xE4, 0x03, 0x74, 0x79, 0x83, 0x7D, 0xB8, 0x00, 0x8B, 0x47, 0x54, 0x89, 0x5D, 0xA8, 0x89, 0x45, 0x08, 0xC7, 0x45, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x74, 0x2D, 0x8D, 0x4D, 0xB0, 0x51, 0x6A, 0x40, 0x8D, 0x4D, 0x08, 0x51, 0x8D, 0x4D, 0xA8, 0x51, 0x0F, 0xAE, 0xE8, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x6A, 0xFF, 0xFF, 0xD0, 0x85, 0xC0, 0x79, 0x08, 0x89, 0x46, 0x08, 0xE9, 0x58, 0xF9, 0xFF, 0xFF, 0x8B, 0x5D, 0xF4, 0x8B, 0x45, 0x08, 0xF6, 0x45, 0xE4, 0x01, 0x74, 0x4B, 0x50, 0x8B, 0x86, 0x80, 0x04, 0x00, 0x00, 0x53, 0xFF, 0xD0, 0x83, 0x7D, 0xB8, 0x00, 0x74, 0x20, 0x8D, 0x4D, 0xB0, 0x51, 0x0F, 0xAE, 0xE8, 0xFF, 0x75, 0xB0, 0x8B, 0x86, 0x6C, 0x04, 0x00, 0x00, 0x8D, 0x4D, 0x08, 0x51, 0x8D, 0x4D, 0xA8, 0x51, 0x6A, 0xFF, 0xFF, 0xD0, 0x85, 0xC0, 0x78, 0xBC, 0xFF, 0x75, 0xF0, 0x8B, 0x86, 0x5C, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x8B, 0x45, 0xF4, 0x89, 0x06, 0x33, 0xC0, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0xF6, 0x45, 0xE4, 0x02, 0x74, 0xB9, 0x64, 0xA1, 0x30, 0x00, 0x00, 0x00, 0x85, 0xC0, 0x75, 0x19, 0xFF, 0x75, 0xF0, 0x8B, 0x86, 0x5C, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0xB8, 0x0F, 0x00, 0x40, 0x00, 0x5F, 0x5E, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0x8B, 0x40, 0x0C, 0x85, 0xC0, 0x74, 0x48, 0x8B, 0x58, 0x0C, 0x85, 0xDB, 0x74, 0x41, 0x8B, 0x1B, 0x85, 0xDB, 0x74, 0x3B, 0x8B, 0x43, 0x18, 0x85, 0xC0, 0x74, 0x34, 0x8B, 0x78, 0x3C, 0xFF, 0x75, 0x08, 0x03, 0xF8, 0x8B, 0x86, 0x80, 0x04, 0x00, 0x00, 0xFF, 0x75, 0xF4, 0xFF, 0xD0, 0x8B, 0x4D, 0x08, 0x39, 0x4F, 0x54, 0x8B, 0x96, 0x7C, 0x04, 0x00, 0x00, 0x0F, 0x42, 0x4F, 0x54, 0x51, 0xFF, 0x73, 0x18, 0xFF, 0x75, 0xF4, 0xFF, 0xD2, 0x83, 0xC4, 0x0C, 0xE9, 0x47, 0xFF, 0xFF, 0xFF, 0xFF, 0x75, 0xF0, 0x8B, 0x86, 0x5C, 0x04, 0x00, 0x00, 0xFF, 0xD0, 0x5F, 0x5E, 0xB8, 0x10, 0x00, 0x40, 0x00, 0x5B, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0xCC, 0xCC, 0xCC, 0xCC +}; + +inline unsigned char VectoredHandlerShell_WOW64[] = +{ + 0x55, 0x8B, 0xEC, 0x83, 0xEC, 0x40, 0x56, 0xC7, 0x45, 0xEC, 0x0C, 0xB0, 0xCE, 0xFA, 0xC7, 0x45, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x64, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x89, 0x45, 0xE8, 0x83, 0x7D, 0xE8, 0x00, 0x75, 0x07, 0x33, 0xC0, 0xE9, 0xDF, 0x02, 0x00, 0x00, 0xC7, 0x45, 0xE4, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x4D, 0xEC, 0x83, 0x79, 0x08, 0x3D, 0x75, 0x09, 0xC7, 0x45, 0xD4, 0x01, 0x00, 0x00, 0x00, 0xEB, 0x07, 0xC7, 0x45, 0xD4, 0x00, 0x00, 0x00, 0x00, 0x8A, 0x55, 0xD4, 0x88, 0x55, 0xFF, 0x0F, 0xB6, 0x45, 0xFF, 0x85, 0xC0, 0x74, 0x17, 0x8B, 0x4D, 0xEC, 0x8B, 0x51, 0x0C, 0xB8, 0x10, 0x00, 0x00, 0x00, 0x6B, 0xC8, 0x00, 0x8D, 0x54, 0x0A, 0x0C, 0x89, 0x55, 0xE4, 0xEB, 0x15, 0x8B, 0x45, 0xEC, 0x8B, 0x48, 0x0C, 0xBA, 0x10, 0x00, 0x00, 0x00, 0x6B, 0xC2, 0x00, 0x8D, 0x4C, 0x01, 0x10, 0x89, 0x4D, 0xE4, 0xC7, 0x45, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x55, 0xEC, 0x83, 0x7A, 0x08, 0x3F, 0x72, 0x1E, 0x8B, 0x45, 0xEC, 0x8B, 0x48, 0x10, 0x89, 0x4D, 0xC4, 0x6A, 0x00, 0xFF, 0x55, 0xC4, 0x89, 0x45, 0xD0, 0x83, 0x7D, 0xD0, 0x00, 0x7D, 0x07, 0x33, 0xC0, 0xE9, 0x57, 0x02, 0x00, 0x00, 0x8B, 0x15, 0x30, 0x03, 0xFE, 0x7F, 0x89, 0x55, 0xC8, 0xEB, 0x08, 0x8B, 0x45, 0xE8, 0x8B, 0x08, 0x89, 0x4D, 0xE8, 0x83, 0x7D, 0xE8, 0x00, 0x0F, 0x84, 0x21, 0x02, 0x00, 0x00, 0x83, 0x7D, 0xE8, 0xFF, 0x0F, 0x84, 0x17, 0x02, 0x00, 0x00, 0x8B, 0x55, 0xE8, 0x83, 0x3A, 0xFF, 0x0F, 0x84, 0x0B, 0x02, 0x00, 0x00, 0xC7, 0x45, 0xF0, 0x00, 0x00, 0x00, 0x00, 0xEB, 0x09, 0x8B, 0x45, 0xF0, 0x83, 0xC0, 0x01, 0x89, 0x45, 0xF0, 0x8B, 0x4D, 0xEC, 0x8B, 0x51, 0x0C, 0x8B, 0x45, 0xF0, 0x3B, 0x02, 0x0F, 0x83, 0xE3, 0x01, 0x00, 0x00, 0x0F, 0xB6, 0x4D, 0xFF, 0x85, 0xC9, 0x75, 0x08, 0x83, 0x7D, 0xF0, 0x00, 0x75, 0x02, 0xEB, 0xD6, 0x8B, 0x55, 0xF0, 0xC1, 0xE2, 0x04, 0x8B, 0x45, 0xEC, 0x8B, 0x08, 0x8B, 0x45, 0xE4, 0x39, 0x4C, 0x10, 0x04, 0x74, 0x02, 0xEB, 0xC0, 0x8B, 0x4D, 0xEC, 0x8B, 0x11, 0x8B, 0x45, 0xE8, 0x39, 0x50, 0x04, 0x72, 0x13, 0x8B, 0x4D, 0xEC, 0x8B, 0x11, 0x8B, 0x45, 0xEC, 0x03, 0x50, 0x04, 0x8B, 0x4D, 0xE8, 0x39, 0x51, 0x04, 0x72, 0x02, 0xEB, 0x9E, 0xC6, 0x45, 0xFE, 0x00, 0x8B, 0x55, 0xF0, 0xC1, 0xE2, 0x04, 0x8B, 0x45, 0xE4, 0x8B, 0x0C, 0x10, 0x89, 0x4D, 0xDC, 0x8B, 0x55, 0xC8, 0x83, 0xE2, 0x1F, 0x89, 0x55, 0xCC, 0x8B, 0x4D, 0xCC, 0xF7, 0xD9, 0x8B, 0x45, 0xDC, 0xD3, 0xE8, 0x8B, 0x55, 0xDC, 0x8B, 0x4D, 0xCC, 0xD3, 0xE2, 0x0B, 0xD0, 0x89, 0x55, 0xDC, 0x8B, 0x45, 0xDC, 0x33, 0x45, 0xC8, 0x89, 0x45, 0xDC, 0x8B, 0x4D, 0xDC, 0x89, 0x4D, 0xF4, 0x8B, 0x55, 0xF4, 0x89, 0x55, 0xE0, 0xEB, 0x09, 0x8B, 0x45, 0xE0, 0x83, 0xC0, 0x04, 0x89, 0x45, 0xE0, 0x83, 0x7D, 0xE0, 0x00, 0x74, 0x71, 0x8B, 0x4D, 0xF4, 0x81, 0xC1, 0x00, 0x04, 0x00, 0x00, 0x39, 0x4D, 0xE0, 0x73, 0x63, 0x8B, 0x55, 0xE0, 0x83, 0x3A, 0x00, 0x75, 0x3D, 0x8B, 0x45, 0xF0, 0xC1, 0xE0, 0x04, 0x8B, 0x4D, 0xE8, 0x8B, 0x55, 0xE4, 0x8B, 0x49, 0x04, 0x2B, 0x4C, 0x02, 0x04, 0x8B, 0x55, 0xE0, 0x89, 0x0A, 0x8B, 0x45, 0xF0, 0xC1, 0xE0, 0x04, 0x8B, 0x4D, 0xE4, 0x8B, 0x54, 0x01, 0x0C, 0x83, 0xC2, 0x01, 0x8B, 0x45, 0xF0, 0xC1, 0xE0, 0x04, 0x8B, 0x4D, 0xE4, 0x89, 0x54, 0x01, + 0x0C, 0xC6, 0x45, 0xFE, 0x01, 0xEB, 0x20, 0xEB, 0x1C, 0x8B, 0x55, 0xF0, 0xC1, 0xE2, 0x04, 0x8B, 0x45, 0xE4, 0x8B, 0x4C, 0x10, 0x04, 0x8B, 0x55, 0xE0, 0x03, 0x0A, 0x8B, 0x45, 0xE8, 0x39, 0x48, 0x04, 0x75, 0x02, 0xEB, 0x02, 0xEB, 0x80, 0x0F, 0xB6, 0x4D, 0xFE, 0x85, 0xC9, 0x0F, 0x84, 0xC0, 0x00, 0x00, 0x00, 0xC7, 0x45, 0xD8, 0x00, 0x00, 0x00, 0x00, 0xEB, 0x09, 0x8B, 0x55, 0xD8, 0x83, 0xC2, 0x01, 0x89, 0x55, 0xD8, 0x8B, 0x45, 0xF0, 0xC1, 0xE0, 0x04, 0x8B, 0x4D, 0xE4, 0x8B, 0x55, 0xD8, 0x3B, 0x54, 0x01, 0x0C, 0x0F, 0x83, 0x98, 0x00, 0x00, 0x00, 0x8B, 0x45, 0xF0, 0xC1, 0xE0, 0x04, 0x8B, 0x4D, 0xE4, 0x8B, 0x54, 0x01, 0x0C, 0x83, 0xEA, 0x01, 0x89, 0x55, 0xF8, 0xEB, 0x09, 0x8B, 0x45, 0xF8, 0x83, 0xE8, 0x01, 0x89, 0x45, 0xF8, 0x8B, 0x4D, 0xF8, 0x3B, 0x4D, 0xD8, 0x76, 0x6D, 0x8B, 0x55, 0xF8, 0x8B, 0x45, 0xF4, 0x8B, 0x4D, 0xF8, 0x8B, 0x75, 0xF4, 0x8B, 0x54, 0x90, 0xFC, 0x3B, 0x14, 0x8E, 0x76, 0x56, 0x8B, 0x45, 0xF8, 0x8B, 0x4D, 0xF4, 0x8B, 0x55, 0xF8, 0x8B, 0x75, 0xF4, 0x8B, 0x44, 0x81, 0xFC, 0x33, 0x04, 0x96, 0x8B, 0x4D, 0xF8, 0x8B, 0x55, 0xF4, 0x89, 0x44, 0x8A, 0xFC, 0x8B, 0x45, 0xF8, 0x8B, 0x4D, 0xF4, 0x8B, 0x55, 0xF8, 0x8B, 0x75, 0xF4, 0x8B, 0x04, 0x81, 0x33, 0x44, 0x96, 0xFC, 0x8B, 0x4D, 0xF8, 0x8B, 0x55, 0xF4, 0x89, 0x04, 0x8A, 0x8B, 0x45, 0xF8, 0x8B, 0x4D, 0xF4, 0x8B, 0x55, 0xF8, 0x8B, 0x75, 0xF4, 0x8B, 0x44, 0x81, 0xFC, 0x33, 0x04, 0x96, 0x8B, 0x4D, 0xF8, 0x8B, 0x55, 0xF4, 0x89, 0x44, 0x8A, 0xFC, 0xEB, 0x82, 0xE9, 0x49, 0xFF, 0xFF, 0xFF, 0xE9, 0x03, 0xFE, 0xFF, 0xFF, 0xE9, 0xCD, 0xFD, 0xFF, 0xFF, 0x8B, 0x45, 0xEC, 0x83, 0x78, 0x08, 0x3F, 0x72, 0x0E, 0x8B, 0x4D, 0xEC, 0x8B, 0x51, 0x10, 0x89, 0x55, 0xC0, 0x6A, 0x01, 0xFF, 0x55, 0xC0, 0x33, 0xC0, 0x5E, 0x8B, 0xE5, 0x5D, 0xC2, 0x04, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC }; #endif \ No newline at end of file diff --git a/GH Injector Library/Win10.h b/GH Injector Library/Win10.h new file mode 100644 index 0000000..d894066 --- /dev/null +++ b/GH Injector Library/Win10.h @@ -0,0 +1,201 @@ +#pragma once + +#include "NT Defs.h" + +typedef struct _LDR_DDAG_NODE_WIN10 +{ + LIST_ENTRY Modules; + PLDR_SERVICE_TAG_RECORD ServiceTagList; + ULONG LoadCount; + ULONG LoadWhileUnloadingCount; + ULONG LowestLink; + PLDRP_CSLIST Dependencies; + PLDRP_CSLIST IncomingDependencies; + LDR_DDAG_STATE State; + SINGLE_LIST_ENTRY CondenseLink; + ULONG PreorderNumber; +} LDR_DDAG_NODE_WIN10, * PLDR_DDAG_NODE_WIN10; + +typedef struct _LDR_DATA_TABLE_ENTRY_WIN10 +{ + LIST_ENTRY InLoadOrderLinks; + LIST_ENTRY InMemoryOrderLinks; + LIST_ENTRY InInitializationOrderLinks; + + PVOID DllBase; + PVOID EntryPoint; + ULONG SizeOfImage; + + UNICODE_STRING FullDllName; + UNICODE_STRING BaseDllName; + + union + { + UCHAR FlagGroup[4]; + ULONG Flags; + + struct + { + ULONG PackagedBinary : 1; + ULONG MarkedForRemoval : 1; + ULONG ImageDll : 1; + ULONG LoadNotificationsSent : 1; + ULONG TelemetryEntryProcessed : 1; + ULONG ProcessStaticImport : 1; + ULONG InLegacyLists : 1; + ULONG InIndexes : 1; + ULONG ShimDll : 1; + ULONG InExceptionTable : 1; + ULONG ReservedFlags1 : 2; + ULONG LoadInProgress : 1; + ULONG LoadConfigProcessed : 1; + ULONG EntryProcessed : 1; + ULONG ProtectDelayLoad : 1; + ULONG ReservedFlags3 : 2; + ULONG DontCallForThreads : 1; + ULONG ProcessAttachCalled : 1; + ULONG ProcessAttachFailed : 1; + ULONG CorDeferredValidate : 1; + ULONG CorImage : 1; + ULONG DontRelocate : 1; + ULONG CorILOnly : 1; + ULONG ChpeImage : 1; + ULONG ReservedFlags5 : 2; + ULONG Redirected : 1; + ULONG ReservedFlags6 : 2; + ULONG CompatDatabaseProcessed : 1; + }; + }; + + WORD ObsoleteLoadCount; + WORD TlsIndex; + + LIST_ENTRY HashLinks; + + ULONG TimedateStamp; + PVOID EntryPointActivationContext; + PVOID Lock; + + LDR_DDAG_NODE_WIN10 * DdagNode; + + LIST_ENTRY NodeModuleLink; + PVOID LoadContext; + PVOID ParentDllBase; + PVOID SwitchBackContext; + + RTL_BALANCED_NODE BaseAddressIndexNode; + RTL_BALANCED_NODE MappingInfoIndexNode; + + ULONG_PTR OriginalBase; + LARGE_INTEGER LoadTime; + ULONG BaseNameHashValue; + LDR_DLL_LOAD_REASON LoadReason; + ULONG ImplicitPathOptions; + + ULONG ReferenceCount; + + //1607+ + ULONG DependentLoadFlags; + + //1703+ + UCHAR SigningLevel; +} LDR_DATA_TABLE_ENTRY_WIN10, * PLDR_DATA_TABLE_ENTRY_WIN10; + +#ifdef _WIN64 + +typedef ALIGN_86 struct _LDR_DDAG_NODE_WIN10_32 +{ + LIST_ENTRY32 Modules; + DWORD ServiceTagList; // -> LDR_SERVICE_TAG_RECORD_32 + ULONG LoadCount; + ULONG LoadWhileUnloadingCount; + ULONG LowestLink; + DWORD Dependencies; // -> LDRP_CSLIST_32 + DWORD IncomingDependencies; // -> LDRP_CSLIST_32 + LDR_DDAG_STATE State; + SINGLE_LIST_ENTRY_32 CondenseLink; + ULONG PreorderNumber; +} LDR_DDAG_NODE_WIN10_32, * PLDR_DDAG_NODE_WIN10_32; + +typedef struct _LDR_DATA_TABLE_ENTRY_WIN10_32 +{ + LIST_ENTRY32 InLoadOrderLinks; + LIST_ENTRY32 InMemoryOrderLinks; + LIST_ENTRY32 InInitializationOrderLinks; + + DWORD DllBase; + DWORD EntryPoint; + ULONG SizeOfImage; + + UNICODE_STRING_32 FullDllName; + UNICODE_STRING_32 BaseDllName; + + union + { + UCHAR FlagGroup[4]; + ULONG Flags; + + struct + { + ULONG PackagedBinary : 1; + ULONG MarkedForRemoval : 1; + ULONG ImageDll : 1; + ULONG LoadNotificationsSent : 1; + ULONG TelemetryEntryProcessed : 1; + ULONG ProcessStaticImport : 1; + ULONG InLegacyLists : 1; + ULONG InIndexes : 1; + ULONG ShimDll : 1; + ULONG InExceptionTable : 1; + ULONG ReservedFlags1 : 2; + ULONG LoadInProgress : 1; + ULONG LoadConfigProcessed : 1; + ULONG EntryProcessed : 1; + ULONG ProtectDelayLoad : 1; + ULONG ReservedFlags3 : 2; + ULONG DontCallForThreads : 1; + ULONG ProcessAttachCalled : 1; + ULONG ProcessAttachFailed : 1; + ULONG CorDeferredValidate : 1; + ULONG CorImage : 1; + ULONG DontRelocate : 1; + ULONG CorILOnly : 1; + ULONG ChpeImage : 1; + ULONG ReservedFlags5 : 2; + ULONG Redirected : 1; + ULONG ReservedFlags6 : 2; + ULONG CompatDatabaseProcessed : 1; + }; + }; + + WORD ObsoleteLoadCount; + WORD TlsIndex; + + LIST_ENTRY32 HashLinks; + + ULONG TimedateStamp; + DWORD EntryPointActivationContext; + DWORD Spare; + + DWORD DdagNode; // -> LDR_DDAG_NODE_WIN10_32 + + LIST_ENTRY32 NodeModuleLink; + DWORD LoadContext; + DWORD ParentDllBase; + DWORD SwitchBackContext; + + RTL_BALANCED_NODE_32 BaseAddressIndexNode; + RTL_BALANCED_NODE_32 MappingInfoIndexNode; + + DWORD OriginalBase; + LARGE_INTEGER LoadTime; + ULONG BaseNameHashValue; + LDR_DLL_LOAD_REASON LoadReason; + ULONG ImplicitPathOptions; + + ULONG ReferenceCount; + ULONG DependentLoadFlags; + UCHAR SigningLevel; +} LDR_DATA_TABLE_ENTRY_WIN10_32, * PLDR_DATA_TABLE_ENTRY_WIN10_32; + +#endif \ No newline at end of file diff --git a/GH Injector Library/Win11.h b/GH Injector Library/Win11.h new file mode 100644 index 0000000..daeb172 --- /dev/null +++ b/GH Injector Library/Win11.h @@ -0,0 +1,205 @@ +#pragma once + +#include "NT Defs.h" + +typedef struct _LDR_DDAG_NODE_WIN11 +{ + LIST_ENTRY Modules; + PLDR_SERVICE_TAG_RECORD ServiceTagList; + ULONG LoadCount; + ULONG LoadWhileUnloadingCount; + ULONG LowestLink; + PLDRP_CSLIST Dependencies; + PLDRP_CSLIST IncomingDependencies; + LDR_DDAG_STATE State; + SINGLE_LIST_ENTRY CondenseLink; + ULONG PreorderNumber; +} LDR_DDAG_NODE_WIN11, * PLDR_DDAG_NODE_WIN11; + +typedef struct _LDR_DATA_TABLE_ENTRY_WIN11 +{ + LIST_ENTRY InLoadOrderLinks; + LIST_ENTRY InMemoryOrderLinks; + LIST_ENTRY InInitializationOrderLinks; + + PVOID DllBase; + PVOID EntryPoint; + ULONG SizeOfImage; + + UNICODE_STRING FullDllName; + UNICODE_STRING BaseDllName; + + union + { + UCHAR FlagGroup[4]; + ULONG Flags; + + struct + { + ULONG PackagedBinary : 1; + ULONG MarkedForRemoval : 1; + ULONG ImageDll : 1; + ULONG LoadNotificationsSent : 1; + ULONG TelemetryEntryProcessed : 1; + ULONG ProcessStaticImport : 1; + ULONG InLegacyLists : 1; + ULONG InIndexes : 1; + ULONG ShimDll : 1; + ULONG InExceptionTable : 1; + ULONG ReservedFlags1 : 2; + ULONG LoadInProgress : 1; + ULONG LoadConfigProcessed : 1; + ULONG EntryProcessed : 1; + ULONG ProtectDelayLoad : 1; + ULONG ReservedFlags3 : 2; + ULONG DontCallForThreads : 1; + ULONG ProcessAttachCalled : 1; + ULONG ProcessAttachFailed : 1; + ULONG CorDeferredValidate : 1; + ULONG CorImage : 1; + ULONG DontRelocate : 1; + ULONG CorILOnly : 1; + ULONG ChpeImage : 1; + ULONG ReservedFlags5 : 2; + ULONG Redirected : 1; + ULONG ReservedFlags6 : 2; + ULONG CompatDatabaseProcessed : 1; + }; + }; + + WORD ObsoleteLoadCount; + WORD TlsIndex; + + LIST_ENTRY HashLinks; + + ULONG TimedateStamp; + PVOID EntryPointActivationContext; + PVOID Lock; + + LDR_DDAG_NODE_WIN11 * DdagNode; + + LIST_ENTRY NodeModuleLink; + PVOID LoadContext; + PVOID ParentDllBase; + PVOID SwitchBackContext; + + RTL_BALANCED_NODE BaseAddressIndexNode; + RTL_BALANCED_NODE MappingInfoIndexNode; + + ULONG_PTR OriginalBase; + LARGE_INTEGER LoadTime; + ULONG BaseNameHashValue; + LDR_DLL_LOAD_REASON LoadReason; + ULONG ImplicitPathOptions; + + ULONG ReferenceCount; + ULONG DependentLoadFlags; + UCHAR SigningLevel; + + ULONG CheckSum; + PVOID ActivePathImageBase; + LDR_HOT_PATCH_STATE HotPatchState; +} LDR_DATA_TABLE_ENTRY_WIN11, * PLDR_DATA_TABLE_ENTRY_WIN11; + +#ifdef _WIN64 + +typedef ALIGN_86 struct _LDR_DDAG_NODE_WIN11_32 +{ + LIST_ENTRY32 Modules; + DWORD ServiceTagList; // -> LDR_SERVICE_TAG_RECORD_32 + ULONG LoadCount; + ULONG LoadWhileUnloadingCount; + ULONG LowestLink; + DWORD Dependencies; // -> LDRP_CSLIST_32 + DWORD IncomingDependencies; // -> LDRP_CSLIST_32 + LDR_DDAG_STATE State; + SINGLE_LIST_ENTRY_32 CondenseLink; + ULONG PreorderNumber; +} LDR_DDAG_NODE_WIN11_32, * PLDR_DDAG_NODE_WIN11_32; + +typedef struct _LDR_DATA_TABLE_ENTRY_WIN11_32 +{ + LIST_ENTRY32 InLoadOrderLinks; + LIST_ENTRY32 InMemoryOrderLinks; + LIST_ENTRY32 InInitializationOrderLinks; + + DWORD DllBase; + DWORD EntryPoint; + ULONG SizeOfImage; + + UNICODE_STRING_32 FullDllName; + UNICODE_STRING_32 BaseDllName; + + union + { + UCHAR FlagGroup[4]; + ULONG Flags; + + struct + { + ULONG PackagedBinary : 1; + ULONG MarkedForRemoval : 1; + ULONG ImageDll : 1; + ULONG LoadNotificationsSent : 1; + ULONG TelemetryEntryProcessed : 1; + ULONG ProcessStaticImport : 1; + ULONG InLegacyLists : 1; + ULONG InIndexes : 1; + ULONG ShimDll : 1; + ULONG InExceptionTable : 1; + ULONG ReservedFlags1 : 2; + ULONG LoadInProgress : 1; + ULONG LoadConfigProcessed : 1; + ULONG EntryProcessed : 1; + ULONG ProtectDelayLoad : 1; + ULONG ReservedFlags3 : 2; + ULONG DontCallForThreads : 1; + ULONG ProcessAttachCalled : 1; + ULONG ProcessAttachFailed : 1; + ULONG CorDeferredValidate : 1; + ULONG CorImage : 1; + ULONG DontRelocate : 1; + ULONG CorILOnly : 1; + ULONG ChpeImage : 1; + ULONG ReservedFlags5 : 2; + ULONG Redirected : 1; + ULONG ReservedFlags6 : 2; + ULONG CompatDatabaseProcessed : 1; + }; + }; + + WORD ObsoleteLoadCount; + WORD TlsIndex; + + LIST_ENTRY32 HashLinks; + + ULONG TimedateStamp; + DWORD EntryPointActivationContext; + DWORD Spare; + + DWORD DdagNode; // -> LDR_DDAG_NODE_WIN11_32 + + LIST_ENTRY32 NodeModuleLink; + DWORD LoadContext; + DWORD ParentDllBase; + DWORD SwitchBackContext; + + RTL_BALANCED_NODE_32 BaseAddressIndexNode; + RTL_BALANCED_NODE_32 MappingInfoIndexNode; + + DWORD OriginalBase; + LARGE_INTEGER LoadTime; + ULONG BaseNameHashValue; + LDR_DLL_LOAD_REASON LoadReason; + ULONG ImplicitPathOptions; + + ULONG ReferenceCount; + ULONG DependentLoadFlags; + UCHAR SigningLevel; + + ULONG CheckSum; + DWORD ActivePathImageBase; + LDR_HOT_PATCH_STATE HotPatchState; +} LDR_DATA_TABLE_ENTRY_WIN11_32, * PLDR_DATA_TABLE_ENTRY_WIN11_32; + +#endif \ No newline at end of file diff --git a/GH Injector Library/Win7.h b/GH Injector Library/Win7.h new file mode 100644 index 0000000..ac4a7b9 --- /dev/null +++ b/GH Injector Library/Win7.h @@ -0,0 +1,161 @@ +#pragma once + +#include "NT Defs.h" + +//some flags might not be Win7 but w/e, stolen from here: +//https://doxygen.reactos.org/d1/d97/ldrtypes_8h_source.html#l00034 + +//0x00000001 +#define LDRP_STATIC_LINK 0x00000002 +#define LDRP_IMAGE_DLL 0x00000004 +#define LDRP_SHIMENG_ENTRY_PROCESSED 0x00000008 +#define LDRP_TELEMETRY_ENTRY_PROCESSED 0x00000010 +#define LDRP_IMAGE_INTEGRITY_FORCED 0x00000020 +//0x00000040 - 0x00000800 +#define LDRP_LOAD_IN_PROGRESS 0x00001000 +#define LDRP_UNLOAD_IN_PROGRESS 0x00002000 +#define LDRP_ENTRY_PROCESSED 0x00004000 +#define LDRP_ENTRY_INSERTED 0x00008000 +#define LDRP_CURRENT_LOAD 0x00010000 +#define LDRP_FAILED_BUILTIN_LOAD 0x00020000 +#define LDRP_DONT_CALL_FOR_THREADS 0x00040000 +#define LDRP_PROCESS_ATTACH_CALLED 0x00080000 +#define LDRP_DEBUG_SYMBOLS_LOADED 0x00100000 +#define LDRP_IMAGE_NOT_AT_BASE 0x00200000 +#define LDRP_COR_IMAGE 0x00400000 +#define LDR_COR_OWNS_UNMAP 0x00800000 +#define LDRP_SYSTEM_MAPPED 0x01000000 +#define LDRP_IMAGE_VERIFYING 0x02000000 +#define LDRP_DRIVER_DEPENDENT_DLL 0x04000000 +#define LDRP_ENTRY_NATIVE 0x08000000 +#define LDRP_REDIRECTED 0x10000000 +#define LDRP_NON_PAGED_DEBUG_INFO 0x20000000 +#define LDRP_MM_LOADED 0x40000000 +#define LDRP_COMPAT_DATABASE_PROCESSED 0x80000000 + +typedef struct _LDR_DDAG_NODE_WIN7 //dummy for macros +{ +} LDR_DDAG_NODE_WIN7, * PLDR_DDAG_NODE_WIN7; + +typedef struct _LDR_DATA_TABLE_ENTRY_WIN7 +{ + LIST_ENTRY InLoadOrderLinks; + LIST_ENTRY InMemoryOrderLinks; + LIST_ENTRY InInitializationOrderLinks; + + PVOID DllBase; + PVOID EntryPoint; + ULONG SizeOfImage; + + UNICODE_STRING FullDllName; + UNICODE_STRING BaseDllName; + + ULONG Flags; + WORD LoadCount; + WORD TlsIndex; + + union + { + LIST_ENTRY HashLinks; + struct + { + PVOID SectionPointer; + ULONG CheckSum; + }; + }; + + union + { + ULONG TimeDateStamp; + PVOID LoadedImports; + }; + + PVOID EntryPointActivationContext; + PVOID PatchInformation; + + LIST_ENTRY ForwarderLinks; + LIST_ENTRY ServiceTagLinks; + LIST_ENTRY StaticLinks; + + PVOID ContextInformation; + ULONG_PTR OriginalBase; + LARGE_INTEGER LoadTime; +} LDR_DATA_TABLE_ENTRY_WIN7, * PLDR_DATA_TABLE_ENTRY_WIN7; + +using f_LdrpLoadDll_WIN7 = NTSTATUS (__stdcall *) +( + UNICODE_STRING * dll_path, + UNICODE_STRING * search_path, + LDRP_LOAD_CONTEXT_FLAGS Flags, + BOOLEAN Unknown1, //set to TRUE + PVOID Unknown2, //can be nullptr + LDR_DATA_TABLE_ENTRY_WIN7 ** ldr_out +); + +typedef struct _RTL_INVERTED_FUNCTION_TABLE_WIN7 +{ + ULONG Count; + ULONG MaxCount; + ULONG Epoch; + RTL_INVERTED_FUNCTION_TABLE_ENTRY Entries[ANYSIZE_ARRAY]; +} RTL_INVERTED_FUNCTION_TABLE_WIN7, * PRTL_INVERTED_FUNCTION_TABLE_WIN7; + +using f_RtlInsertInvertedFunctionTable_WIN7 = NTSTATUS (__stdcall *) +( + RTL_INVERTED_FUNCTION_TABLE_WIN7 * pTable, + void * ImageBase, + DWORD SizeOfImage +); + +#ifdef _WIN64 + +typedef struct _LDR_DDAG_NODE_WIN7_32 //dummy for macros +{ +} LDR_DDAG_NODE_WIN7_32, * PLDR_DDAG_NODE_WIN7_32; + +typedef struct _LDR_DATA_TABLE_ENTRY_WIN7_32 +{ + LIST_ENTRY32 InLoadOrderLinks; + LIST_ENTRY32 InMemoryOrderLinks; + LIST_ENTRY32 InInitializationOrderLinks; + + DWORD DllBase; + DWORD EntryPoint; + ULONG SizeOfImage; + + UNICODE_STRING_32 FullDllName; + UNICODE_STRING_32 BaseDllName; + + ULONG Flags; + WORD LoadCount; + WORD TlsIndex; + + union + { + LIST_ENTRY32 HashLinks; + struct + { + DWORD SectionPointer; + ULONG CheckSum; + }; + }; + + union + { + ULONG TimeDateStamp; + DWORD LoadedImports; + }; + + DWORD EntryPointActivationContext; + DWORD PatchInformation; + + LIST_ENTRY32 ForwarderLinks; + LIST_ENTRY32 ServiceTagLinks; + LIST_ENTRY32 StaticLinks; + + DWORD ContextInformation; + DWORD OriginalBase; + LARGE_INTEGER LoadTime; +} LDR_DATA_TABLE_ENTRY_WIN7_32, * PLDR_DATA_TABLE_ENTRY_WIN7_32; + +#endif \ No newline at end of file diff --git a/GH Injector Library/Win8.h b/GH Injector Library/Win8.h new file mode 100644 index 0000000..5f25319 --- /dev/null +++ b/GH Injector Library/Win8.h @@ -0,0 +1,238 @@ +#pragma once + +#include "NT Defs.h" + +typedef struct _LDR_DDAG_NODE_WIN8 +{ + LIST_ENTRY Modules; + PLDR_SERVICE_TAG_RECORD ServiceTagList; + ULONG LoadCount; + ULONG ReferenceCount; + ULONG DependencyCount; + union + { + LDRP_CSLIST Dependencies; + SINGLE_LIST_ENTRY * RemovalLink; + }; + PLDRP_CSLIST IncomingDependencies; + LDR_DDAG_STATE State; + SINGLE_LIST_ENTRY CondenseLink; + ULONG PreorderNumber; + ULONG LowestLink; +} LDR_DDAG_NODE_WIN8, * PLDR_DDAG_NODE_WIN8; + +typedef struct _LDR_DATA_TABLE_ENTRY_WIN8 +{ + LIST_ENTRY InLoadOrderLinks; + LIST_ENTRY InMemoryOrderLinks; + union + { + LIST_ENTRY InInitializationOrderLinks; + LIST_ENTRY InProgressLinks; + }; + + PVOID DllBase; + PVOID EntryPoint; + ULONG SizeOfImage; + + UNICODE_STRING FullDllName; + UNICODE_STRING BaseDllName; + + union + { + UCHAR FlagGroup[4]; + ULONG Flags; + + struct + { + ULONG PackagedBinary : 1; + ULONG MarkedForRemoval : 1; + ULONG ImageDll : 1; + ULONG LoadNotificationsSent : 1; + ULONG TelemetryEntryProcessed : 1; + ULONG ProcessStaticImport : 1; + ULONG InLegacyLists : 1; + ULONG InIndexes : 1; + ULONG ShimDll : 1; + ULONG InExceptionTable : 1; + ULONG ReservedFlags1 : 2; + ULONG LoadInProgress : 1; + ULONG ReservedFlags2 : 1; + ULONG EntryProcessed : 1; + ULONG ReservedFlags3 : 3; + ULONG DontCallForThreads : 1; + ULONG ProcessAttachCalled : 1; + ULONG ProcessAttachFailed : 1; + ULONG CorDeferredValidate : 1; + ULONG CorImage : 1; + ULONG DontRelocate : 1; + ULONG CorILOnly : 1; + ULONG ReservedFlags5 : 3; + ULONG Redirected : 1; + ULONG ReservedFlags6 : 2; + ULONG CompatDatabaseProcessed : 1; + }; + }; + + WORD ObsoleteLoadCount; + WORD TlsIndex; + + LIST_ENTRY HashLinks; + + ULONG TimedateStamp; + PVOID EntryPointActivationContext; + PVOID PatchInformation; + + LDR_DDAG_NODE_WIN8 * DdagNode; + + LIST_ENTRY NodeModuleLink; + PVOID SnapContext; + PVOID ParentDllBase; + PVOID SwitchBackContext; + + RTL_BALANCED_NODE BaseAddressIndexNode; + RTL_BALANCED_NODE MappingInfoIndexNode; + + ULONG_PTR OriginalBase; + LARGE_INTEGER LoadTime; + ULONG BaseNameHashValue; + LDR_DLL_LOAD_REASON LoadReason; +} LDR_DATA_TABLE_ENTRY_WIN8, * PLDR_DATA_TABLE_ENTRY_WIN8; + +typedef struct _LDRP_PATH_SEARCH_CONTEXT_WIN8 +{ + ULONG_PTR Flags; //probably LDRP_LOAD_CONTEXT_FLAGS + wchar_t * OriginalFullDllName; //can be path + BOOLEAN unknown2; //only low byte relevant + ULONG_PTR unknown3[3]; //sometimes imagebase? +} LDRP_PATH_SEARCH_CONTEXT_WIN8, * PLDRP_PATH_SEARCH_CONTEXT_WIN8; + +using f_LdrLoadDll_WIN8 = NTSTATUS (__stdcall *) +( + BOOLEAN Unknown1, //set to TRUE + ULONG * LoadFlags, + UNICODE_STRING * pModuleFileName, + HANDLE * pOut +); + +using f_LdrpLoadDll_WIN8 = NTSTATUS (__stdcall *) +( + UNICODE_STRING * dll_path, + LDRP_PATH_SEARCH_CONTEXT_WIN8 * search_ctx, + LDRP_LOAD_CONTEXT_FLAGS Flags, + BOOLEAN Unknown, //set to TRUE + LDR_DATA_TABLE_ENTRY_WIN8 ** entry_out, + LDR_DDAG_NODE_WIN8 ** ddag_out +); + +using f_RtlInsertInvertedFunctionTable_WIN8 = NTSTATUS (__stdcall *) +( + void * ImageBase, + DWORD SizeOfImage +); + +using f_LdrpHandleTlsData_WIN8 = NTSTATUS (__stdcall *) +( + LDR_DATA_TABLE_ENTRY_WIN8 * pEntry +); + +#ifdef _WIN64 + +typedef ALIGN_86 struct _LDR_DDAG_NODE_WIN8_32 +{ + LIST_ENTRY32 Modules; + DWORD ServiceTagList; // -> LDR_SERVICE_TAG_RECORD_32 + ULONG LoadCount; + ULONG ReferenceCount; + ULONG DependencyCount; + union + { + LDRP_CSLIST_32 Dependencies; + DWORD RemovalLink; // -> SINGLE_LIST_ENTRY_32 + }; + DWORD IncomingDependencies; // -> LDRP_CSLIST_32 + LDR_DDAG_STATE State; + SINGLE_LIST_ENTRY_32 CondenseLink; + ULONG PreorderNumber; + ULONG LowestLink; +} LDR_DDAG_NODE_WIN8_32, * PLDR_DDAG_NODE_WIN8_32; + +typedef struct _LDR_DATA_TABLE_ENTRY_WIN8_32 +{ + LIST_ENTRY32 InLoadOrderLinks; + LIST_ENTRY32 InMemoryOrderLinks; + union + { + LIST_ENTRY32 InInitializationOrderLinks; + LIST_ENTRY32 InProgressLinks; + }; + + DWORD DllBase; + DWORD EntryPoint; + ULONG SizeOfImage; + + UNICODE_STRING_32 FullDllName; + UNICODE_STRING_32 BaseDllName; + + union + { + UCHAR FlagGroup[4]; + ULONG Flags; + + struct + { + ULONG PackagedBinary : 1; + ULONG MarkedForRemoval : 1; + ULONG ImageDll : 1; + ULONG LoadNotificationsSent : 1; + ULONG TelemetryEntryProcessed : 1; + ULONG ProcessStaticImport : 1; + ULONG InLegacyLists : 1; + ULONG InIndexes : 1; + ULONG ShimDll : 1; + ULONG InExceptionTable : 1; + ULONG ReservedFlags1 : 2; + ULONG LoadInProgress : 1; + ULONG ReservedFlags2 : 1; + ULONG EntryProcessed : 1; + ULONG ReservedFlags3 : 3; + ULONG DontCallForThreads : 1; + ULONG ProcessAttachCalled : 1; + ULONG ProcessAttachFailed : 1; + ULONG CorDeferredValidate : 1; + ULONG CorImage : 1; + ULONG DontRelocate : 1; + ULONG CorILOnly : 1; + ULONG ReservedFlags5 : 3; + ULONG Redirected : 1; + ULONG ReservedFlags6 : 2; + ULONG CompatDatabaseProcessed : 1; + }; + }; + + WORD ObsoleteLoadCount; + WORD TlsIndex; + + LIST_ENTRY32 HashLinks; + + ULONG TimedateStamp; + DWORD EntryPointActivationContext; + DWORD PatchInformation; + + DWORD DdagNode; // -> LDR_DDAG_NODE_WIN8_32 + + LIST_ENTRY32 NodeModuleLink; + DWORD SnapContext; + DWORD ParentDllBase; + DWORD SwitchBackContext; + + RTL_BALANCED_NODE_32 BaseAddressIndexNode; + RTL_BALANCED_NODE_32 MappingInfoIndexNode; + + DWORD OriginalBase; + LARGE_INTEGER LoadTime; + ULONG BaseNameHashValue; + LDR_DLL_LOAD_REASON LoadReason; +} LDR_DATA_TABLE_ENTRY_WIN8_32, * PLDR_DATA_TABLE_ENTRY_WIN8_32; + +#endif \ No newline at end of file diff --git a/GH Injector Library/Win81.h b/GH Injector Library/Win81.h new file mode 100644 index 0000000..88e2f86 --- /dev/null +++ b/GH Injector Library/Win81.h @@ -0,0 +1,222 @@ +#pragma once + +#include "NT Defs.h" + +typedef struct _LDR_DDAG_NODE_WIN81 +{ + LIST_ENTRY Modules; + PLDR_SERVICE_TAG_RECORD ServiceTagList; + ULONG LoadCount; + ULONG ReferenceCount; + ULONG DependencyCount; + union + { + LDRP_CSLIST Dependencies; + SINGLE_LIST_ENTRY * RemovalLink; + }; + PLDRP_CSLIST IncomingDependencies; + LDR_DDAG_STATE State; + SINGLE_LIST_ENTRY CondenseLink; + ULONG PreorderNumber; + ULONG LowestLink; +} LDR_DDAG_NODE_WIN81, * PLDR_DDAG_NODE_WIN81; + +typedef struct _LDR_DATA_TABLE_ENTRY_WIN81 +{ + LIST_ENTRY InLoadOrderLinks; + LIST_ENTRY InMemoryOrderLinks; + union + { + LIST_ENTRY InInitializationOrderLinks; + LIST_ENTRY InProgressLinks; + }; + + PVOID DllBase; + PVOID EntryPoint; + ULONG SizeOfImage; + + UNICODE_STRING FullDllName; + UNICODE_STRING BaseDllName; + + union + { + UCHAR FlagGroup[4]; + ULONG Flags; + + struct + { + ULONG PackagedBinary : 1; + ULONG MarkedForRemoval : 1; + ULONG ImageDll : 1; + ULONG LoadNotificationsSent : 1; + ULONG TelemetryEntryProcessed : 1; + ULONG ProcessStaticImport : 1; + ULONG InLegacyLists : 1; + ULONG InIndexes : 1; + ULONG ShimDll : 1; + ULONG InExceptionTable : 1; + ULONG ReservedFlags1 : 2; + ULONG LoadInProgress : 1; + ULONG ReservedFlags2 : 1; + ULONG EntryProcessed : 1; + ULONG ReservedFlags3 : 3; + ULONG DontCallForThreads : 1; + ULONG ProcessAttachCalled : 1; + ULONG ProcessAttachFailed : 1; + ULONG CorDeferredValidate : 1; + ULONG CorImage : 1; + ULONG DontRelocate : 1; + ULONG CorILOnly : 1; + ULONG ReservedFlags5 : 3; + ULONG Redirected : 1; + ULONG ReservedFlags6 : 2; + ULONG CompatDatabaseProcessed : 1; + }; + }; + + WORD ObsoleteLoadCount; + WORD TlsIndex; + + LIST_ENTRY HashLinks; + + ULONG TimedateStamp; + PVOID EntryPointActivationContext; + PVOID Spare; + + LDR_DDAG_NODE_WIN81 * DdagNode; + + LIST_ENTRY NodeModuleLink; + PVOID SnapContext; + PVOID ParentDllBase; + PVOID SwitchBackContext; + + RTL_BALANCED_NODE BaseAddressIndexNode; + RTL_BALANCED_NODE MappingInfoIndexNode; + + ULONG_PTR OriginalBase; + LARGE_INTEGER LoadTime; + ULONG BaseNameHashValue; + LDR_DLL_LOAD_REASON LoadReason; + + ULONG ImplicitPathOptions; +} LDR_DATA_TABLE_ENTRY_WIN81, * PLDR_DATA_TABLE_ENTRY_WIN81; + +typedef struct _LDRP_PATH_SEARCH_CONTEXT_WIN81 +{ + UINT_PTR unknown_0[3]; + wchar_t * OriginalFullDllName; + UINT_PTR unknown_1[1]; +} LDRP_PATH_SEARCH_CONTEXT_WIN81, * PLDRP_PATH_SEARCH_CONTEXT_WIN81; //x86 size = 0x14, x64 size = 0x28 + +using f_LdrpLoadDll_WIN81 = NTSTATUS (__fastcall *) +( + UNICODE_STRING * dll_path, + LDRP_PATH_SEARCH_CONTEXT_WIN81 * search_ctx, + LDRP_LOAD_CONTEXT_FLAGS Flags, + BOOLEAN Unknown, //set to TRUE + LDR_DATA_TABLE_ENTRY_WIN81 ** entry_out, + LDR_DDAG_NODE_WIN81 ** ddag_out +); + +#ifdef _WIN64 + +typedef ALIGN_86 struct _LDR_DDAG_NODE_WIN81_32 +{ + LIST_ENTRY32 Modules; + DWORD ServiceTagList; // -> LDR_SERVICE_TAG_RECORD_32 + ULONG LoadCount; + ULONG ReferenceCount; + ULONG DependencyCount; + union + { + LDRP_CSLIST_32 Dependencies; + DWORD RemovalLink; // -> SINGLE_LIST_ENTRY_32 + }; + DWORD IncomingDependencies; // -> LDRP_CSLIST_32 + LDR_DDAG_STATE State; + SINGLE_LIST_ENTRY_32 CondenseLink; + ULONG PreorderNumber; + ULONG LowestLink; +} LDR_DDAG_NODE_WIN81_32, * PLDR_DDAG_NODE_WIN81_32; + +typedef struct _LDR_DATA_TABLE_ENTRY_WIN81_32 +{ + LIST_ENTRY32 InLoadOrderLinks; + LIST_ENTRY32 InMemoryOrderLinks; + union + { + LIST_ENTRY32 InInitializationOrderLinks; + LIST_ENTRY32 InProgressLinks; + }; + + DWORD DllBase; + DWORD EntryPoint; + ULONG SizeOfImage; + + UNICODE_STRING_32 FullDllName; + UNICODE_STRING_32 BaseDllName; + + union + { + UCHAR FlagGroup[4]; + ULONG Flags; + + struct + { + ULONG PackagedBinary : 1; + ULONG MarkedForRemoval : 1; + ULONG ImageDll : 1; + ULONG LoadNotificationsSent : 1; + ULONG TelemetryEntryProcessed : 1; + ULONG ProcessStaticImport : 1; + ULONG InLegacyLists : 1; + ULONG InIndexes : 1; + ULONG ShimDll : 1; + ULONG InExceptionTable : 1; + ULONG ReservedFlags1 : 2; + ULONG LoadInProgress : 1; + ULONG ReservedFlags2 : 1; + ULONG EntryProcessed : 1; + ULONG ReservedFlags3 : 3; + ULONG DontCallForThreads : 1; + ULONG ProcessAttachCalled : 1; + ULONG ProcessAttachFailed : 1; + ULONG CorDeferredValidate : 1; + ULONG CorImage : 1; + ULONG DontRelocate : 1; + ULONG CorILOnly : 1; + ULONG ReservedFlags5 : 3; + ULONG Redirected : 1; + ULONG ReservedFlags6 : 2; + ULONG CompatDatabaseProcessed : 1; + }; + }; + + WORD ObsoleteLoadCount; + WORD TlsIndex; + + LIST_ENTRY32 HashLinks; + + ULONG TimedateStamp; + DWORD EntryPointActivationContext; + DWORD Spare; + + DWORD DdagNode; // -> LDR_DDAG_NODE_WIN81_32 + + LIST_ENTRY32 NodeModuleLink; + DWORD SnapContext; + DWORD ParentDllBase; + DWORD SwitchBackContext; + + RTL_BALANCED_NODE_32 BaseAddressIndexNode; + RTL_BALANCED_NODE_32 MappingInfoIndexNode; + + DWORD OriginalBase; + LARGE_INTEGER LoadTime; + ULONG BaseNameHashValue; + LDR_DLL_LOAD_REASON LoadReason; + + ULONG ImplicitPathOptions; +} LDR_DATA_TABLE_ENTRY_WIN81_32, * PLDR_DATA_TABLE_ENTRY_WIN81_32; + +#endif \ No newline at end of file diff --git a/GH Injector Library/main.cpp b/GH Injector Library/main.cpp index 44bae4f..604c70f 100644 --- a/GH Injector Library/main.cpp +++ b/GH Injector Library/main.cpp @@ -25,16 +25,7 @@ BOOL WINAPI DllMain(HINSTANCE hDll, DWORD dwReason, void * pReserved) g_hInjMod = hDll; - char szRootPathA[MAX_PATH]{ 0 }; wchar_t szRootPathW[MAX_PATH]{ 0 }; - - if (!GetOwnModulePathA(szRootPathA, sizeof(szRootPathA) / sizeof(szRootPathA[0]))) - { - LOG("Couldn't resolve own module path (ansi)\n"); - - return FALSE; - } - if (!GetOwnModulePathW(szRootPathW, sizeof(szRootPathW) / sizeof(szRootPathW[0]))) { LOG("Couldn't resolve own module path (unicode)\n"); @@ -42,6 +33,8 @@ BOOL WINAPI DllMain(HINSTANCE hDll, DWORD dwReason, void * pReserved) return FALSE; } + LOG("Rootpath is %ls\n", szRootPathW); + wchar_t * szWindowsDir = nullptr; if (_wdupenv_s(&szWindowsDir, nullptr, L"WINDIR") || !szWindowsDir) @@ -56,11 +49,8 @@ BOOL WINAPI DllMain(HINSTANCE hDll, DWORD dwReason, void * pReserved) return FALSE; } - g_RootPathA = szRootPathA; g_RootPathW = szRootPathW; - LOG("Rootpath is %ls\n", szRootPathW); - std::wstring szNtDllNative = szWindowsDir; szNtDllNative += L"\\System32\\ntdll.dll"; diff --git a/GH Injector Library/pch.cpp b/GH Injector Library/pch.cpp index 753441e..d6de2fd 100644 --- a/GH Injector Library/pch.cpp +++ b/GH Injector Library/pch.cpp @@ -88,6 +88,10 @@ void custom_print(const char * format, ...) break; } } + else if (result < 0) + { + break; + } } while (result < 0); _set_thread_local_invalid_parameter_handler(old); diff --git a/GH Injector Library/pch.h b/GH Injector Library/pch.h index 921a6b6..9c8ad97 100644 --- a/GH Injector Library/pch.h +++ b/GH Injector Library/pch.h @@ -30,17 +30,17 @@ //symbol shit #include #include -#include //internet shit #include +#include //warning shit -#pragma warning(disable: 4201) //unnamed union (nt strucutres like unnamed unions) +#pragma warning(disable: 4201) //unnamed union (nt structures) #pragma warning(disable: 4324) //structure member alignment resulting in additional bytes being added as padding #pragma warning(disable: 6001) //uninitialized memory & handles (false positive in for loops with continue statements) #pragma warning(disable: 6258) //TerminateThread warning -#pragma warning(disable: 28159) //I want to used GetTickCount, suck it Bill +#pragma warning(disable: 28159) //I want to use GetTickCount, suck it Bill //reinterpret_cast = too long to type #define ReCa reinterpret_cast diff --git a/GH Injector SM/GH Injector SM/GH Injector SM.vcxproj b/GH Injector SM/GH Injector SM/GH Injector SM.vcxproj index 5e9f9ec..067c3b0 100644 --- a/GH Injector SM/GH Injector SM/GH Injector SM.vcxproj +++ b/GH Injector SM/GH Injector SM/GH Injector SM.vcxproj @@ -22,7 +22,7 @@ 15.0 {6F0A0AA5-4B61-4323-B9A5-B3EF0088DC1B} GHInjectorSM - 10.0.19041.0 + 10.0.22000.0 @@ -128,7 +128,7 @@ true true - RequireAdministrator + AsInvoker false @@ -145,7 +145,7 @@ true true - RequireAdministrator + AsInvoker false diff --git a/GH Injector SM/GH Injector SM/main.cpp b/GH Injector SM/GH Injector SM/main.cpp index 8562035..27c5f4e 100644 --- a/GH Injector SM/GH Injector SM/main.cpp +++ b/GH Injector SM/GH Injector SM/main.cpp @@ -22,11 +22,10 @@ int wmain(int argc, wchar_t * argv[]) #ifndef _WIN64 else if (argv[1][0] == ID_WOW64) { - HANDLE hEventStart = reinterpret_cast(wcstol(argv[2], nullptr, 0x10)); - SetEvent(hEventStart); + HANDLE hEventStart = reinterpret_cast(wcstol(argv[2], nullptr, 0x10)); + HANDLE hEventEnd = reinterpret_cast(wcstol(argv[3], nullptr, 0x10)); - HANDLE hEventEnd = reinterpret_cast(wcstol(argv[3], nullptr, 0x10)); - WaitForSingleObject(hEventEnd, INFINITE); + SignalObjectAndWait(hEventStart, hEventEnd, INFINITE, FALSE); CloseHandle(hEventStart); CloseHandle(hEventEnd);