From e2abc789e94fbf60ff81345006535e06fbbbf30e Mon Sep 17 00:00:00 2001 From: mrexodia Date: Tue, 6 Jun 2017 21:35:54 +0200 Subject: [PATCH] fixed WOW64 PEB address retrival on Windows 10 --- TitanEngine/Global.Engine.Hider.cpp | 62 +++++++++++++---------------- TitanEngine/TitanEngine.Hider.cpp | 36 +++++++++++++---- 2 files changed, 57 insertions(+), 41 deletions(-) diff --git a/TitanEngine/Global.Engine.Hider.cpp b/TitanEngine/Global.Engine.Hider.cpp index a71217d..111a6e7 100644 --- a/TitanEngine/Global.Engine.Hider.cpp +++ b/TitanEngine/Global.Engine.Hider.cpp @@ -189,13 +189,10 @@ static bool FixPebInProcess(HANDLE hProcess, bool Hide) void* heapForceFlagsAddress = 0; DWORD heapForceFlags = 0; -// getting the PEB64 doesnt work anymore since WIN10 creators update as the PEB32+0x1000 offset doesnt seem to be correct anymore -// maybe earlier as some comments suggested. at least this code causes crashes of debuggee as of that update only -// in theory, we could get the PEB64 via TEB64 (TitanEngine.Hider GetTEBLocation64) or via ntdll.Wow64QueryInformationProcess64 -//#ifndef _WIN64 -// PEB64 myPEB64 = {0}; -// void* AddressOfPEB64 = GetPEBLocation64(hProcess); -//#endif +#ifndef _WIN64 + PEB64 myPEB64 = {0}; + void* AddressOfPEB64 = GetPEBLocation64(hProcess); +#endif void* AddressOfPEB = GetPEBLocation(hProcess); @@ -204,12 +201,12 @@ static bool FixPebInProcess(HANDLE hProcess, bool Hide) if(ReadProcessMemory(hProcess, AddressOfPEB, (void*)&myPEB, sizeof(PEB_CURRENT), &ueNumberOfBytesRead)) { -//#ifndef _WIN64 -// if(AddressOfPEB64) -// { -// ReadProcessMemory(hProcess, AddressOfPEB64, (void*)&myPEB64, sizeof(PEB64), &ueNumberOfBytesRead); -// } -//#endif +#ifndef _WIN64 + if(AddressOfPEB64) + { + ReadProcessMemory(hProcess, AddressOfPEB64, (void*)&myPEB64, sizeof(PEB64), &ueNumberOfBytesRead); + } +#endif if(Hide) { @@ -217,22 +214,19 @@ static bool FixPebInProcess(HANDLE hProcess, bool Hide) myPEB.BeingDebugged = FALSE; myPEB.NtGlobalFlag &= ~0x70; -//#ifndef _WIN64 -// myPEB64.BeingDebugged = FALSE; -// myPEB64.NtGlobalFlag &= ~0x70; -//#endif +#ifndef _WIN64 + myPEB64.BeingDebugged = FALSE; + myPEB64.NtGlobalFlag &= ~0x70; +#endif //TODO: backup heap flags -//#ifdef _WIN64 -// heapFlagsAddress = (void*)((LONG_PTR)myPEB.ProcessHeap + getHeapFlagsOffset(true)); -// heapForceFlagsAddress = (void*)((LONG_PTR)myPEB.ProcessHeap + getHeapForceFlagsOffset(true)); -//#else -// heapFlagsAddress = (void*)((LONG_PTR)myPEB.ProcessHeap + getHeapFlagsOffset(false)); -// heapForceFlagsAddress = (void*)((LONG_PTR)myPEB.ProcessHeap + getHeapForceFlagsOffset(false)); -//#endif //_WIN64 +#ifdef _WIN64 + heapFlagsAddress = (void*)((LONG_PTR)myPEB.ProcessHeap + getHeapFlagsOffset(true)); + heapForceFlagsAddress = (void*)((LONG_PTR)myPEB.ProcessHeap + getHeapForceFlagsOffset(true)); +#else heapFlagsAddress = (void*)((LONG_PTR)myPEB.ProcessHeap + getHeapFlagsOffset(false)); heapForceFlagsAddress = (void*)((LONG_PTR)myPEB.ProcessHeap + getHeapForceFlagsOffset(false)); - +#endif //_WIN64 ReadProcessMemory(hProcess, heapFlagsAddress, &heapFlags, sizeof(DWORD), 0); ReadProcessMemory(hProcess, heapForceFlagsAddress, &heapForceFlags, sizeof(DWORD), 0); @@ -245,19 +239,19 @@ static bool FixPebInProcess(HANDLE hProcess, bool Hide) else { myPEB.BeingDebugged = TRUE; -//#ifndef _WIN64 -// myPEB64.BeingDebugged = TRUE; -//#endif +#ifndef _WIN64 + myPEB64.BeingDebugged = TRUE; +#endif } if(WriteProcessMemory(hProcess, AddressOfPEB, (void*)&myPEB, sizeof(PEB_CURRENT), &ueNumberOfBytesRead)) { -//#ifndef _WIN64 -// if(AddressOfPEB64) -// { -// WriteProcessMemory(hProcess, AddressOfPEB64, (void*)&myPEB64, sizeof(PEB64), &ueNumberOfBytesRead); -// } -//#endif +#ifndef _WIN64 + if(AddressOfPEB64) + { + WriteProcessMemory(hProcess, AddressOfPEB64, (void*)&myPEB64, sizeof(PEB64), &ueNumberOfBytesRead); + } +#endif return true; } } diff --git a/TitanEngine/TitanEngine.Hider.cpp b/TitanEngine/TitanEngine.Hider.cpp index cb6b188..1c1d099 100644 --- a/TitanEngine/TitanEngine.Hider.cpp +++ b/TitanEngine/TitanEngine.Hider.cpp @@ -47,6 +47,7 @@ __declspec(dllexport) void* TITCALL GetTEBLocation(HANDLE hThread) __declspec(dllexport) void* TITCALL GetTEBLocation64(HANDLE hThread) { + //TODO: this might return garbage on Windows 10 #ifndef _WIN64 if(IsThisProcessWow64()) { @@ -64,20 +65,41 @@ __declspec(dllexport) void* TITCALL GetTEBLocation64(HANDLE hThread) __declspec(dllexport) void* TITCALL GetPEBLocation64(HANDLE hProcess) { + void* PebAddress = 0; #ifndef _WIN64 if(IsThisProcessWow64()) { - //Only WOW64 processes have 2 PEBs - DWORD peb32 = (DWORD)GetPEBLocation(hProcess); - if(peb32) + typedef NTSTATUS(WINAPI * t_NtWow64QueryInformationProcess64)(HANDLE ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength); + static auto _NtWow64QueryInformationProcess64 = (t_NtWow64QueryInformationProcess64)GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "NtWow64QueryInformationProcess64"); + if(_NtWow64QueryInformationProcess64) { - // this offset is WRONG as of Win10 Creators Update.See comment in Global.Engine.Hider.cpp:192 - peb32 += 0x1000; //PEB64 after PEB32 - return (void*)peb32; + struct PROCESS_BASIC_INFORMATION64 + { + DWORD ExitStatus; + DWORD64 PebBaseAddress; + DWORD64 AffinityMask; + DWORD BasePriority; + DWORD64 UniqueProcessId; + DWORD64 InheritedFromUniqueProcessId; + } myProcessBasicInformation[5]; + + ULONG RequiredLen = 0; + + if(_NtWow64QueryInformationProcess64(hProcess, ProcessBasicInformation, myProcessBasicInformation, sizeof(PROCESS_BASIC_INFORMATION64), &RequiredLen) == STATUS_SUCCESS) + { + PebAddress = (void*)myProcessBasicInformation->PebBaseAddress; + } + else + { + if(_NtWow64QueryInformationProcess64(hProcess, ProcessBasicInformation, myProcessBasicInformation, RequiredLen, &RequiredLen) == STATUS_SUCCESS) + { + PebAddress = (void*)myProcessBasicInformation->PebBaseAddress; + } + } } } #endif //_WIN64 - return 0; + return PebAddress; } __declspec(dllexport) bool TITCALL HideDebugger(HANDLE hProcess, DWORD PatchAPILevel)