From ec9696d97d0e174cb583f98ab0b238c5cec06795 Mon Sep 17 00:00:00 2001 From: sonyps5201314 Date: Fri, 4 Sep 2020 12:22:18 +0800 Subject: [PATCH 1/5] fix can not use createwith api to start all kinds of .net exe, like Reflector.exe, it can be install by https://download.red-gate.com/ReflectorInstaller.exe --- src/creatwth.cpp | 136 ++++++++++++++++++++++++++--------------------- src/modules.cpp | 4 +- 2 files changed, 78 insertions(+), 62 deletions(-) diff --git a/src/creatwth.cpp b/src/creatwth.cpp index 96d6b651..2ca916f9 100644 --- a/src/creatwth.cpp +++ b/src/creatwth.cpp @@ -408,7 +408,8 @@ static BOOL UpdateFrom32To64(HANDLE hProcess, HMODULE hModule, WORD machine, // inh64.Signature = inh32.Signature; inh64.FileHeader = inh32.FileHeader; - inh64.FileHeader.Machine = machine; + inh64.FileHeader.Machine = machine;//If inh32.FileHeader.Machine is assigned here, the PE loader of win7 and below will not be able to pass, + //It will report an error STATUS_INVALID_IMAGE_FORMAT, so you need to save the value of Machine in the original PE header in dep, that is, the value of inh32.FileHeader.Machine, inh64.FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER64); inh64.OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR64_MAGIC; @@ -476,6 +477,10 @@ static BOOL UpdateFrom32To64(HANDLE hProcess, HMODULE hModule, WORD machine, if (!RecordExeRestore(hProcess, hModule, der)) { return FALSE; } + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //After the above RecordExeRestore call, the 64-bit PE header is saved in dep, so it is necessary to restore the Machine value of the PE header saved in der, so that the PE parser of .NET can load the CLR file normally + der.inh.FileHeader.Machine = inh32.FileHeader.Machine; + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Remove the import table. if (der.pclr != NULL && (der.clr.Flags & COMIMAGE_FLAGS_ILONLY)) { @@ -499,37 +504,59 @@ static BOOL UpdateFrom32To64(HANDLE hProcess, HMODULE hModule, WORD machine, } #endif // DETOURS_64BIT -typedef BOOL(WINAPI *LPFN_ISWOW64PROCESS)(HANDLE, PBOOL); - -static BOOL IsWow64ProcessHelper(HANDLE hProcess, - PBOOL Wow64Process) +namespace Detour { -#ifdef _X86_ - if (Wow64Process == NULL) { - return FALSE; - } - - // IsWow64Process is not available on all supported versions of Windows. - // - HMODULE hKernel32 = LoadLibraryW(L"KERNEL32.DLL"); - if (hKernel32 == NULL) { - DETOUR_TRACE(("LoadLibraryW failed: %d\n", GetLastError())); - return FALSE; - } - - LPFN_ISWOW64PROCESS pfnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress( - hKernel32, "IsWow64Process"); - - if (pfnIsWow64Process == NULL) { - DETOUR_TRACE(("GetProcAddress failed: %d\n", GetLastError())); - return FALSE; - } - return pfnIsWow64Process(hProcess, Wow64Process); -#else - return IsWow64Process(hProcess, Wow64Process); +#ifndef PROCESSOR_ARCHITECTURE_ARM64 +#define PROCESSOR_ARCHITECTURE_ARM64 12 #endif + BOOL Is64BitOS() + { + BOOL bRet = FALSE; + HMODULE hModule = GetModuleHandle(TEXT("kernel32.dll")); + if (!hModule) + { + return bRet; + } + VOID(WINAPI * _GetNativeSystemInfo)(OUT LPSYSTEM_INFO lpSystemInfo) = (void(__stdcall *)(LPSYSTEM_INFO))GetProcAddress(hModule, "GetNativeSystemInfo"); + if (!_GetNativeSystemInfo) + { + return bRet; + } + + SYSTEM_INFO si; + _GetNativeSystemInfo(&si); + if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 || si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM64 || + si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64 || si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ALPHA64) + { + bRet = TRUE; + } + return bRet; + }; + //The process handle hProcess needs to have PROCESS_QUERY_INFORMATION or PROCESS_QUERY_LIMITED_INFORMATION access rights + BOOL Is64BitProcess(HANDLE hProcess) + { + BOOL bRet = FALSE; + if (hProcess) + { + if (Is64BitOS()) + { + HMODULE hModule = GetModuleHandle(TEXT("kernel32.dll")); + if (hModule) + { + BOOL(WINAPI * _IsWow64Process)(IN HANDLE hProcess, + OUT PBOOL Wow64Process) + = (BOOL(__stdcall*)(HANDLE, PBOOL))GetProcAddress(hModule, "IsWow64Process"); + BOOL b32BitProcessRunAt64BitOS; + if (_IsWow64Process && _IsWow64Process(hProcess, &b32BitProcessRunAt64BitOS) && b32BitProcessRunAt64BitOS == FALSE) + { + bRet = TRUE; + } + } + } + } + return bRet; + } } - ////////////////////////////////////////////////////////////////////////////// // BOOL WINAPI DetourUpdateProcessWithDll(_In_ HANDLE hProcess, @@ -538,8 +565,9 @@ BOOL WINAPI DetourUpdateProcessWithDll(_In_ HANDLE hProcess, { // Find the next memory region that contains a mapped PE image. // + BOOL bHas64BitDll = FALSE; + BOOL bHas32BitExe = FALSE; BOOL bIs32BitProcess; - BOOL bIs64BitOS = FALSE; HMODULE hModule = NULL; HMODULE hLast = NULL; @@ -557,8 +585,20 @@ BOOL WINAPI DetourUpdateProcessWithDll(_In_ HANDLE hProcess, if ((inh.FileHeader.Characteristics & IMAGE_FILE_DLL) == 0) { hModule = hLast; + if (inh.OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC + && inh.FileHeader.Machine != 0) { + + bHas32BitExe = TRUE; + } DETOUR_TRACE(("%p Found EXE\n", hLast)); } + else { + if (inh.OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC + && inh.FileHeader.Machine != 0) { + + bHas64BitDll = TRUE; + } + } } if (hModule == NULL) { @@ -566,37 +606,9 @@ BOOL WINAPI DetourUpdateProcessWithDll(_In_ HANDLE hProcess, return FALSE; } - // Determine if the target process is 32bit or 64bit. This is a two-stop process: - // - // 1. First, determine if we're running on a 64bit operating system. - // - If we're running 64bit code (i.e. _WIN64 is defined), this is trivially true. - // - If we're running 32bit code (i.e. _WIN64 is not defined), test if - // we're running under Wow64. If so, it implies that the operating system - // is 64bit. - // -#ifdef _WIN64 - bIs64BitOS = TRUE; -#else - if (!IsWow64ProcessHelper(GetCurrentProcess(), &bIs64BitOS)) { - return FALSE; - } -#endif - - // 2. With the operating system bitness known, we can now consider the target process: - // - If we're running on a 64bit OS, the target process is 32bit in case - // it is running under Wow64. Otherwise, it's 64bit, running natively - // (without Wow64). - // - If we're running on a 32bit OS, the target process must be 32bit, too. - // - if (bIs64BitOS) { - if (!IsWow64ProcessHelper(hProcess, &bIs32BitProcess)) { - return FALSE; - } - } else { - bIs32BitProcess = TRUE; - } + bIs32BitProcess = !Detour::Is64BitProcess(hProcess); - DETOUR_TRACE((" 32BitExe=%d 32BitProcess\n", bHas32BitExe, bIs32BitProcess)); + DETOUR_TRACE((" 32BitExe=%d 32BitProcess=%d\n", bHas32BitExe, bIs32BitProcess)); return DetourUpdateProcessWithDllEx(hProcess, hModule, @@ -630,7 +642,7 @@ BOOL WINAPI DetourUpdateProcessWithDllEx(_In_ HANDLE hProcess, bIs32BitExe = TRUE; } - DETOUR_TRACE((" 32BitExe=%d 32BitProcess\n", bIs32BitExe, bIs32BitProcess)); + DETOUR_TRACE((" 32BitExe=%d 32BitProcess=%d\n", bIs32BitExe, bIs32BitProcess)); if (hModule == NULL) { SetLastError(ERROR_INVALID_OPERATION); @@ -714,6 +726,8 @@ BOOL WINAPI DetourUpdateProcessWithDllEx(_In_ HANDLE hProcess, DETOUR_CLR_HEADER clr; CopyMemory(&clr, &der.clr, sizeof(clr)); clr.Flags &= ~COMIMAGE_FLAGS_ILONLY; // Clear the IL_ONLY flag. + //The above sentence clears the IL_ONLY flag, so we need to restore the IL_ONLY flag after the IAT is restored after starting the process completion + //Not clearing the IL_ONLY flag will result in the inability to start the process, because we replaced the original IAT with the new IAT containing the name of our DLL DWORD dwProtect; if (!DetourVirtualProtectSameExecuteEx(hProcess, der.pclr, sizeof(clr), PAGE_READWRITE, &dwProtect)) { diff --git a/src/modules.cpp b/src/modules.cpp index ade78c97..d4ec35f1 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -858,6 +858,7 @@ BOOL WINAPI DetourRestoreAfterWithEx(_In_reads_bytes_(cbData) PVOID pvData, if (pder->pclr != NULL && pder->clr.Flags != ((PDETOUR_CLR_HEADER)pder->pclr)->Flags) { // If we had to promote the 32/64-bit agnostic IL to 64-bit, we can't restore // that. + //Now we have supported the recovery of CLR header data in the above situation (IL code of unknown target bit is compiled into native code of 64-bit process by instant compilation) fUpdated32To64 = TRUE; } @@ -869,7 +870,8 @@ BOOL WINAPI DetourRestoreAfterWithEx(_In_reads_bytes_(cbData) PVOID pvData, CopyMemory(pder->pidh, &pder->idh, pder->cbidh); CopyMemory(pder->pinh, &pder->inh, pder->cbinh); - if (pder->pclr != NULL && !fUpdated32To64) { + //It can be restored now when fUpdated32To64 is TRUE. At present, only the clr.Flags field is restored. + if (pder->pclr != NULL /*&& !fUpdated32To64*/) { if (DetourVirtualProtectSameExecute(pder->pclr, pder->cbclr, PAGE_EXECUTE_READWRITE, &dwPermClr)) { CopyMemory(pder->pclr, &pder->clr, pder->cbclr); From b4f98d4d9e0036df25b1d276d52425ce30eaf34d Mon Sep 17 00:00:00 2001 From: sonyps5201314 Date: Sun, 6 Sep 2020 21:26:48 +0800 Subject: [PATCH 2/5] The code format is adapted to the Detours code style, and better english annotations --- src/creatwth.cpp | 110 ++++++++++++++++++++++++----------------------- src/modules.cpp | 8 ++-- 2 files changed, 62 insertions(+), 56 deletions(-) diff --git a/src/creatwth.cpp b/src/creatwth.cpp index 2ca916f9..189b8008 100644 --- a/src/creatwth.cpp +++ b/src/creatwth.cpp @@ -408,8 +408,11 @@ static BOOL UpdateFrom32To64(HANDLE hProcess, HMODULE hModule, WORD machine, // inh64.Signature = inh32.Signature; inh64.FileHeader = inh32.FileHeader; - inh64.FileHeader.Machine = machine;//If inh32.FileHeader.Machine is assigned here, the PE loader of win7 and below will not be able to pass, - //It will report an error STATUS_INVALID_IMAGE_FORMAT, so you need to save the value of Machine in the original PE header in dep, that is, the value of inh32.FileHeader.Machine, + inh64.FileHeader.Machine = machine;//If inh32.FileHeader.Machine is assigned here, + //the PE loader of win7 and below will not be able to pass, + //It will report an error STATUS_INVALID_IMAGE_FORMAT, + //so we need to save the value of Machine in the original PE header to "der", + //that is, the value of inh32.FileHeader.Machine. inh64.FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER64); inh64.OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR64_MAGIC; @@ -477,10 +480,11 @@ static BOOL UpdateFrom32To64(HANDLE hProcess, HMODULE hModule, WORD machine, if (!RecordExeRestore(hProcess, hModule, der)) { return FALSE; } - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - //After the above RecordExeRestore call, the 64-bit PE header is saved in dep, so it is necessary to restore the Machine value of the PE header saved in der, so that the PE parser of .NET can load the CLR file normally - der.inh.FileHeader.Machine = inh32.FileHeader.Machine; - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + //After the above RecordExeRestore call, the 64-bit PE header is saved in "der", + //so it is necessary to restore the Machine value of the PE header saved in "der", + //so that the PE parser of .NET can load the CLR file normally + der.inh.FileHeader.Machine = inh32.FileHeader.Machine; // Remove the import table. if (der.pclr != NULL && (der.clr.Flags & COMIMAGE_FLAGS_ILONLY)) { @@ -504,58 +508,56 @@ static BOOL UpdateFrom32To64(HANDLE hProcess, HMODULE hModule, WORD machine, } #endif // DETOURS_64BIT -namespace Detour -{ +namespace Detour { + +#ifndef PROCESSOR_ARCHITECTURE_AMD64 +#define PROCESSOR_ARCHITECTURE_AMD64 9 +#endif + #ifndef PROCESSOR_ARCHITECTURE_ARM64 #define PROCESSOR_ARCHITECTURE_ARM64 12 #endif - BOOL Is64BitOS() - { - BOOL bRet = FALSE; + + BOOL Is64BitOS() + { + BOOL bRet = FALSE; HMODULE hModule = GetModuleHandle(TEXT("kernel32.dll")); - if (!hModule) - { + if (!hModule) { return bRet; } - VOID(WINAPI * _GetNativeSystemInfo)(OUT LPSYSTEM_INFO lpSystemInfo) = (void(__stdcall *)(LPSYSTEM_INFO))GetProcAddress(hModule, "GetNativeSystemInfo"); - if (!_GetNativeSystemInfo) - { - return bRet; - } - - SYSTEM_INFO si; - _GetNativeSystemInfo(&si); - if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 || si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM64 || - si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64 || si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ALPHA64) - { - bRet = TRUE; - } - return bRet; - }; - //The process handle hProcess needs to have PROCESS_QUERY_INFORMATION or PROCESS_QUERY_LIMITED_INFORMATION access rights - BOOL Is64BitProcess(HANDLE hProcess) - { - BOOL bRet = FALSE; - if (hProcess) - { - if (Is64BitOS()) - { + VOID(WINAPI * _GetNativeSystemInfo)(OUT LPSYSTEM_INFO lpSystemInfo) = (void(__stdcall*)(LPSYSTEM_INFO))GetProcAddress(hModule, "GetNativeSystemInfo"); + if (!_GetNativeSystemInfo) { + return bRet; + } + + SYSTEM_INFO si; + _GetNativeSystemInfo(&si); + if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 || si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM64 || + si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64 || si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ALPHA64) { + bRet = TRUE; + } + return bRet; + }; + //The process handle hProcess needs to have PROCESS_QUERY_INFORMATION or PROCESS_QUERY_LIMITED_INFORMATION access rights + BOOL Is64BitProcess(HANDLE hProcess) + { + BOOL bRet = FALSE; + if (hProcess) { + if (Is64BitOS()) { HMODULE hModule = GetModuleHandle(TEXT("kernel32.dll")); - if (hModule) - { - BOOL(WINAPI * _IsWow64Process)(IN HANDLE hProcess, - OUT PBOOL Wow64Process) - = (BOOL(__stdcall*)(HANDLE, PBOOL))GetProcAddress(hModule, "IsWow64Process"); - BOOL b32BitProcessRunAt64BitOS; - if (_IsWow64Process && _IsWow64Process(hProcess, &b32BitProcessRunAt64BitOS) && b32BitProcessRunAt64BitOS == FALSE) - { - bRet = TRUE; - } + if (hModule) { + BOOL(WINAPI * _IsWow64Process)(IN HANDLE hProcess, + OUT PBOOL Wow64Process) + = (BOOL(__stdcall*)(HANDLE, PBOOL))GetProcAddress(hModule, "IsWow64Process"); + BOOL b32BitProcessRunAt64BitOS; + if (_IsWow64Process && _IsWow64Process(hProcess, &b32BitProcessRunAt64BitOS) && b32BitProcessRunAt64BitOS == FALSE) { + bRet = TRUE; + } } - } - } - return bRet; - } + } + } + return bRet; + } } ////////////////////////////////////////////////////////////////////////////// // @@ -606,7 +608,7 @@ BOOL WINAPI DetourUpdateProcessWithDll(_In_ HANDLE hProcess, return FALSE; } - bIs32BitProcess = !Detour::Is64BitProcess(hProcess); + bIs32BitProcess = !Detour::Is64BitProcess(hProcess); DETOUR_TRACE((" 32BitExe=%d 32BitProcess=%d\n", bHas32BitExe, bIs32BitProcess)); @@ -726,8 +728,10 @@ BOOL WINAPI DetourUpdateProcessWithDllEx(_In_ HANDLE hProcess, DETOUR_CLR_HEADER clr; CopyMemory(&clr, &der.clr, sizeof(clr)); clr.Flags &= ~COMIMAGE_FLAGS_ILONLY; // Clear the IL_ONLY flag. - //The above sentence clears the IL_ONLY flag, so we need to restore the IL_ONLY flag after the IAT is restored after starting the process completion - //Not clearing the IL_ONLY flag will result in the inability to start the process, because we replaced the original IAT with the new IAT containing the name of our DLL + //The above sentence clears the IL_ONLY flag, + //so we need to restore the IL_ONLY flag after the IAT is restored after starting the process completion + //Not clearing the IL_ONLY flag will result in the inability to start the process, + //because we replaced the original IAT with the new IAT containing the name of our DLL DWORD dwProtect; if (!DetourVirtualProtectSameExecuteEx(hProcess, der.pclr, sizeof(clr), PAGE_READWRITE, &dwProtect)) { diff --git a/src/modules.cpp b/src/modules.cpp index d4ec35f1..902d141a 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -858,7 +858,8 @@ BOOL WINAPI DetourRestoreAfterWithEx(_In_reads_bytes_(cbData) PVOID pvData, if (pder->pclr != NULL && pder->clr.Flags != ((PDETOUR_CLR_HEADER)pder->pclr)->Flags) { // If we had to promote the 32/64-bit agnostic IL to 64-bit, we can't restore // that. - //Now we have supported the recovery of CLR header data in the above situation (IL code of unknown target bit is compiled into native code of 64-bit process by instant compilation) + //Now we have supported the restore of CLR header data in the above situation, + //that IL code with unknown target bits is compiled into native code for 64-bit processes fUpdated32To64 = TRUE; } @@ -870,8 +871,9 @@ BOOL WINAPI DetourRestoreAfterWithEx(_In_reads_bytes_(cbData) PVOID pvData, CopyMemory(pder->pidh, &pder->idh, pder->cbidh); CopyMemory(pder->pinh, &pder->inh, pder->cbinh); - //It can be restored now when fUpdated32To64 is TRUE. At present, only the clr.Flags field is restored. - if (pder->pclr != NULL /*&& !fUpdated32To64*/) { + //Now, restoration is supported even if fUpdated32To64 is TRUE. + //Currently, only the clr.Flags field is actually restored. + if (pder->pclr != NULL) { if (DetourVirtualProtectSameExecute(pder->pclr, pder->cbclr, PAGE_EXECUTE_READWRITE, &dwPermClr)) { CopyMemory(pder->pclr, &pder->clr, pder->cbclr); From 238513ed255ef872978ee47508536d3f5dfed1ac Mon Sep 17 00:00:00 2001 From: sonyps5201314 Date: Mon, 7 Sep 2020 22:35:00 +0800 Subject: [PATCH 3/5] The code format is adapted to the Detours code style --- src/creatwth.cpp | 98 ++++++++++++++++++++++++------------------------ src/modules.cpp | 8 ++-- 2 files changed, 52 insertions(+), 54 deletions(-) diff --git a/src/creatwth.cpp b/src/creatwth.cpp index 189b8008..f20f046e 100644 --- a/src/creatwth.cpp +++ b/src/creatwth.cpp @@ -408,11 +408,11 @@ static BOOL UpdateFrom32To64(HANDLE hProcess, HMODULE hModule, WORD machine, // inh64.Signature = inh32.Signature; inh64.FileHeader = inh32.FileHeader; - inh64.FileHeader.Machine = machine;//If inh32.FileHeader.Machine is assigned here, - //the PE loader of win7 and below will not be able to pass, - //It will report an error STATUS_INVALID_IMAGE_FORMAT, - //so we need to save the value of Machine in the original PE header to "der", - //that is, the value of inh32.FileHeader.Machine. + inh64.FileHeader.Machine = machine;// If inh32.FileHeader.Machine is assigned here, + // the PE loader of win7 and below will not be able to pass, + // It will report an error STATUS_INVALID_IMAGE_FORMAT, + // so we need to save the value of Machine in the original PE header to "der", + // that is, the value of inh32.FileHeader.Machine. inh64.FileHeader.SizeOfOptionalHeader = sizeof(IMAGE_OPTIONAL_HEADER64); inh64.OptionalHeader.Magic = IMAGE_NT_OPTIONAL_HDR64_MAGIC; @@ -481,9 +481,9 @@ static BOOL UpdateFrom32To64(HANDLE hProcess, HMODULE hModule, WORD machine, return FALSE; } - //After the above RecordExeRestore call, the 64-bit PE header is saved in "der", - //so it is necessary to restore the Machine value of the PE header saved in "der", - //so that the PE parser of .NET can load the CLR file normally + // After the above RecordExeRestore call, the 64-bit PE header is saved in "der", + // so it is necessary to restore the Machine value of the PE header saved in "der", + // so that the PE parser of .NET can load the CLR file normally der.inh.FileHeader.Machine = inh32.FileHeader.Machine; // Remove the import table. @@ -508,8 +508,6 @@ static BOOL UpdateFrom32To64(HANDLE hProcess, HMODULE hModule, WORD machine, } #endif // DETOURS_64BIT -namespace Detour { - #ifndef PROCESSOR_ARCHITECTURE_AMD64 #define PROCESSOR_ARCHITECTURE_AMD64 9 #endif @@ -518,47 +516,47 @@ namespace Detour { #define PROCESSOR_ARCHITECTURE_ARM64 12 #endif - BOOL Is64BitOS() - { - BOOL bRet = FALSE; - HMODULE hModule = GetModuleHandle(TEXT("kernel32.dll")); - if (!hModule) { - return bRet; - } - VOID(WINAPI * _GetNativeSystemInfo)(OUT LPSYSTEM_INFO lpSystemInfo) = (void(__stdcall*)(LPSYSTEM_INFO))GetProcAddress(hModule, "GetNativeSystemInfo"); - if (!_GetNativeSystemInfo) { - return bRet; - } - - SYSTEM_INFO si; - _GetNativeSystemInfo(&si); - if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 || si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM64 || - si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64 || si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ALPHA64) { - bRet = TRUE; - } +static BOOL Is64BitOS() +{ + BOOL bRet = FALSE; + HMODULE hModule = GetModuleHandle(TEXT("kernel32.dll")); + if (!hModule) { + return bRet; + } + VOID(WINAPI * _GetNativeSystemInfo)(OUT LPSYSTEM_INFO lpSystemInfo) = (void(__stdcall*)(LPSYSTEM_INFO))GetProcAddress(hModule, "GetNativeSystemInfo"); + if (!_GetNativeSystemInfo) { return bRet; - }; - //The process handle hProcess needs to have PROCESS_QUERY_INFORMATION or PROCESS_QUERY_LIMITED_INFORMATION access rights - BOOL Is64BitProcess(HANDLE hProcess) - { - BOOL bRet = FALSE; - if (hProcess) { - if (Is64BitOS()) { - HMODULE hModule = GetModuleHandle(TEXT("kernel32.dll")); - if (hModule) { - BOOL(WINAPI * _IsWow64Process)(IN HANDLE hProcess, - OUT PBOOL Wow64Process) - = (BOOL(__stdcall*)(HANDLE, PBOOL))GetProcAddress(hModule, "IsWow64Process"); - BOOL b32BitProcessRunAt64BitOS; - if (_IsWow64Process && _IsWow64Process(hProcess, &b32BitProcessRunAt64BitOS) && b32BitProcessRunAt64BitOS == FALSE) { - bRet = TRUE; - } + } + + SYSTEM_INFO si; + _GetNativeSystemInfo(&si); + if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 || si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM64 || + si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64 || si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ALPHA64) { + bRet = TRUE; + } + return bRet; +}; +// The process handle hProcess needs to have PROCESS_QUERY_INFORMATION or PROCESS_QUERY_LIMITED_INFORMATION access rights +static BOOL Is64BitProcess(HANDLE hProcess) +{ + BOOL bRet = FALSE; + if (hProcess) { + if (Is64BitOS()) { + HMODULE hModule = GetModuleHandle(TEXT("kernel32.dll")); + if (hModule) { + BOOL(WINAPI * _IsWow64Process)(IN HANDLE hProcess, + OUT PBOOL Wow64Process) + = (BOOL(__stdcall*)(HANDLE, PBOOL))GetProcAddress(hModule, "IsWow64Process"); + BOOL b32BitProcessRunAt64BitOS; + if (_IsWow64Process && _IsWow64Process(hProcess, &b32BitProcessRunAt64BitOS) && b32BitProcessRunAt64BitOS == FALSE) { + bRet = TRUE; } } } - return bRet; } + return bRet; } + ////////////////////////////////////////////////////////////////////////////// // BOOL WINAPI DetourUpdateProcessWithDll(_In_ HANDLE hProcess, @@ -608,7 +606,7 @@ BOOL WINAPI DetourUpdateProcessWithDll(_In_ HANDLE hProcess, return FALSE; } - bIs32BitProcess = !Detour::Is64BitProcess(hProcess); + bIs32BitProcess = !Is64BitProcess(hProcess); DETOUR_TRACE((" 32BitExe=%d 32BitProcess=%d\n", bHas32BitExe, bIs32BitProcess)); @@ -728,10 +726,10 @@ BOOL WINAPI DetourUpdateProcessWithDllEx(_In_ HANDLE hProcess, DETOUR_CLR_HEADER clr; CopyMemory(&clr, &der.clr, sizeof(clr)); clr.Flags &= ~COMIMAGE_FLAGS_ILONLY; // Clear the IL_ONLY flag. - //The above sentence clears the IL_ONLY flag, - //so we need to restore the IL_ONLY flag after the IAT is restored after starting the process completion - //Not clearing the IL_ONLY flag will result in the inability to start the process, - //because we replaced the original IAT with the new IAT containing the name of our DLL + // The above sentence clears the IL_ONLY flag, + // so we need to restore the IL_ONLY flag after the IAT is restored after starting the process completion + // Not clearing the IL_ONLY flag will result in the inability to start the process, + // because we replaced the original IAT with the new IAT containing the name of our DLL DWORD dwProtect; if (!DetourVirtualProtectSameExecuteEx(hProcess, der.pclr, sizeof(clr), PAGE_READWRITE, &dwProtect)) { diff --git a/src/modules.cpp b/src/modules.cpp index 902d141a..9703e992 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -858,8 +858,8 @@ BOOL WINAPI DetourRestoreAfterWithEx(_In_reads_bytes_(cbData) PVOID pvData, if (pder->pclr != NULL && pder->clr.Flags != ((PDETOUR_CLR_HEADER)pder->pclr)->Flags) { // If we had to promote the 32/64-bit agnostic IL to 64-bit, we can't restore // that. - //Now we have supported the restore of CLR header data in the above situation, - //that IL code with unknown target bits is compiled into native code for 64-bit processes + // Now we have supported the restore of CLR header data in the above situation, + // that IL code with unknown target bits is compiled into native code for 64-bit processes fUpdated32To64 = TRUE; } @@ -871,8 +871,8 @@ BOOL WINAPI DetourRestoreAfterWithEx(_In_reads_bytes_(cbData) PVOID pvData, CopyMemory(pder->pidh, &pder->idh, pder->cbidh); CopyMemory(pder->pinh, &pder->inh, pder->cbinh); - //Now, restoration is supported even if fUpdated32To64 is TRUE. - //Currently, only the clr.Flags field is actually restored. + // Now, restoration is supported even if fUpdated32To64 is TRUE. + // Currently, only the clr.Flags field is actually restored. if (pder->pclr != NULL) { if (DetourVirtualProtectSameExecute(pder->pclr, pder->cbclr, PAGE_EXECUTE_READWRITE, &dwPermClr)) { From 753d25354533943807e5d0faa59292398d04a15a Mon Sep 17 00:00:00 2001 From: sonyps5201314 Date: Tue, 9 Mar 2021 00:01:49 +0800 Subject: [PATCH 4/5] force use GetModuleHandleW --- src/creatwth.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/creatwth.cpp b/src/creatwth.cpp index 7583259a..0f01ea40 100644 --- a/src/creatwth.cpp +++ b/src/creatwth.cpp @@ -521,7 +521,7 @@ static BOOL UpdateFrom32To64(HANDLE hProcess, HMODULE hModule, WORD machine, static BOOL Is64BitOS() { BOOL bRet = FALSE; - HMODULE hModule = GetModuleHandle(TEXT("kernel32.dll")); + HMODULE hModule = GetModuleHandleW(L"kernel32.dll"); if (!hModule) { return bRet; } @@ -544,7 +544,7 @@ static BOOL Is64BitProcess(HANDLE hProcess) BOOL bRet = FALSE; if (hProcess) { if (Is64BitOS()) { - HMODULE hModule = GetModuleHandle(TEXT("kernel32.dll")); + HMODULE hModule = GetModuleHandleW(L"kernel32.dll"); if (hModule) { BOOL(WINAPI * _IsWow64Process)(IN HANDLE hProcess, OUT PBOOL Wow64Process) From 10d657f42efab337a91f1f9b1b62cf7a8ca1d1b8 Mon Sep 17 00:00:00 2001 From: sonyps5201314 Date: Thu, 5 Aug 2021 23:49:55 +0800 Subject: [PATCH 5/5] Fix a compilation warning when using a lower version of VC --- src/uimports.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/uimports.cpp b/src/uimports.cpp index ed43d659..a8d62cdf 100644 --- a/src/uimports.cpp +++ b/src/uimports.cpp @@ -114,7 +114,7 @@ static BOOL UPDATE_IMPORTS_XX(HANDLE hProcess, PIMAGE_IMPORT_DESCRIPTOR pImageImport = (PIMAGE_IMPORT_DESCRIPTOR)(pbModule + inh.IMPORT_DIRECTORY.VirtualAddress); - do { + for (; ; ) { IMAGE_IMPORT_DESCRIPTOR ImageImport; if (!ReadProcessMemory(hProcess, pImageImport, &ImageImport, sizeof(ImageImport), NULL)) { DETOUR_TRACE(("ReadProcessMemory failed: %lu\n", GetLastError())); @@ -125,7 +125,7 @@ static BOOL UPDATE_IMPORTS_XX(HANDLE hProcess, break; } ++pImageImport; - } while (TRUE); + } DWORD dwLastError = GetLastError(); OutputDebugString(TEXT("[This PE file has an import table, but the import table size is marked as 0. This is an error.")