diff --git a/TitanEngineEmulator/Emulator.h b/TitanEngineEmulator/Emulator.h index 31bd5d8..d0fd614 100644 --- a/TitanEngineEmulator/Emulator.h +++ b/TitanEngineEmulator/Emulator.h @@ -4,6 +4,7 @@ #include "TitanEngine.h" #include "ntdll.h" #include "FileMap.h" +#include "PEB.h" using namespace GleeBug; @@ -183,6 +184,46 @@ public: return PebAddress; } + void* GetPEBLocation64(HANDLE hProcess) + { + void* PebAddress = 0; +#ifndef _WIN64 + if(isThisProcessWow64()) + { + 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) + { + 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) == 0) + { + PebAddress = (void*)myProcessBasicInformation->PebBaseAddress; + } + else + { + if(_NtWow64QueryInformationProcess64(hProcess, ProcessBasicInformation, myProcessBasicInformation, RequiredLen, &RequiredLen) == 0) + { + PebAddress = (void*)myProcessBasicInformation->PebBaseAddress; + } + } + } + } +#endif //_WIN64 + return PebAddress; + + } + static bool getThreadInfo(HANDLE hThread, THREAD_BASIC_INFORMATION & tbi) { ULONG RequiredLen = 0; @@ -211,7 +252,66 @@ public: bool HideDebugger(HANDLE hProcess, DWORD PatchAPILevel) { - //TODO + PEB_CURRENT myPEB = { 0 }; + SIZE_T ueNumberOfBytesRead = 0; + void* heapFlagsAddress = 0; + DWORD heapFlags = 0; + void* heapForceFlagsAddress = 0; + DWORD heapForceFlags = 0; + +#ifndef _WIN64 + PEB64 myPEB64 = { 0 }; + void* AddressOfPEB64 = GetPEBLocation64(hProcess); +#endif + + void* AddressOfPEB = GetPEBLocation(hProcess); + + if(!AddressOfPEB) + return false; + + if(ReadProcessMemory(hProcess, AddressOfPEB, (void*)&myPEB, sizeof(PEB_CURRENT), &ueNumberOfBytesRead)) + { +#ifndef _WIN64 + if(AddressOfPEB64) + { + ReadProcessMemory(hProcess, AddressOfPEB64, (void*)&myPEB64, sizeof(PEB64), &ueNumberOfBytesRead); + } +#endif + myPEB.BeingDebugged = FALSE; + myPEB.NtGlobalFlag &= ~0x70; + +#ifndef _WIN64 + myPEB64.BeingDebugged = FALSE; + myPEB64.NtGlobalFlag &= ~0x70; +#endif + +#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); + + heapFlags &= HEAP_GROWABLE; + heapForceFlags = 0; + + WriteProcessMemory(hProcess, heapFlagsAddress, &heapFlags, sizeof(DWORD), 0); + WriteProcessMemory(hProcess, heapForceFlagsAddress, &heapForceFlags, sizeof(DWORD), 0); + + if(WriteProcessMemory(hProcess, AddressOfPEB, (void*)&myPEB, sizeof(PEB_CURRENT), &ueNumberOfBytesRead)) + { +#ifndef _WIN64 + if(AddressOfPEB64) + { + WriteProcessMemory(hProcess, AddressOfPEB64, (void*)&myPEB64, sizeof(PEB64), &ueNumberOfBytesRead); + } +#endif + return true; + } + } return false; } @@ -891,6 +991,93 @@ private: //functions return dwLastError; } + static bool isAtleastVista() + { + static bool isAtleastVista = false; + static bool isSet = false; + if(isSet) + return isAtleastVista; + OSVERSIONINFO versionInfo = { 0 }; + versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&versionInfo); + isAtleastVista = versionInfo.dwMajorVersion >= 6; + isSet = true; + return isAtleastVista; + } + + //Quote from The Ultimate Anti-Debugging Reference by Peter Ferrie + //Flags field exists at offset 0x0C in the heap on the 32-bit versions of Windows NT, Windows 2000, and Windows XP; and at offset 0x40 on the 32-bit versions of Windows Vista and later. + //Flags field exists at offset 0x14 in the heap on the 64-bit versions of Windows XP, and at offset 0x70 in the heap on the 64-bit versions of Windows Vista and later. + //ForceFlags field exists at offset 0x10 in the heap on the 32-bit versions of Windows NT, Windows 2000, and Windows XP; and at offset 0x44 on the 32-bit versions of Windows Vista and later. + //ForceFlags field exists at offset 0x18 in the heap on the 64-bit versions of Windows XP, and at offset 0x74 in the heap on the 64-bit versions of Windows Vista and later. + static int getHeapFlagsOffset(bool x64) + { + if(x64) //x64 offsets + { + if(isAtleastVista()) + { + return 0x70; + } + else + { + return 0x14; + } + } + else //x86 offsets + { + if(isAtleastVista()) + { + return 0x40; + } + else + { + return 0x0C; + } + } + } + + static int getHeapForceFlagsOffset(bool x64) + { + if(x64) //x64 offsets + { + if(isAtleastVista()) + { + return 0x74; + } + else + { + return 0x18; + } + } + else //x86 offsets + { + if(isAtleastVista()) + { + return 0x44; + } + else + { + return 0x10; + } + } + } + +#ifndef _WIN64 + static bool isThisProcessWow64() + { + typedef BOOL(WINAPI * tIsWow64Process)(HANDLE hProcess, PBOOL Wow64Process); + BOOL bIsWow64 = FALSE; + static auto fnIsWow64Process = (tIsWow64Process)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsWow64Process"); + + if(fnIsWow64Process) + { + fnIsWow64Process(GetCurrentProcess(), &bIsWow64); + } + + return (bIsWow64 != FALSE); + } +#endif + private: //variables bool mSetDebugPrivilege = false; typedef void(*CUSTOMHANDLER)(const void*); diff --git a/TitanEngineEmulator/PEB.h b/TitanEngineEmulator/PEB.h new file mode 100644 index 0000000..71a4c17 --- /dev/null +++ b/TitanEngineEmulator/PEB.h @@ -0,0 +1,129 @@ +#pragma once + +#include + +/////////////////////////////////////////////////////////////////////////////////////// +//Evolution of Process Environment Block (PEB) http://blog.rewolf.pl/blog/?p=573 +//March 2, 2013 / ReWolf posted in programming, reverse engineering, source code, x64 / + +template +struct LIST_ENTRY_T +{ + T Flink; + T Blink; +}; + +template +struct UNICODE_STRING_T +{ + union + { + struct + { + WORD Length; + WORD MaximumLength; + }; + T dummy; + }; + T _Buffer; +}; + +template +struct _PEB_T +{ + union + { + struct + { + BYTE InheritedAddressSpace; + BYTE ReadImageFileExecOptions; + BYTE BeingDebugged; + BYTE _SYSTEM_DEPENDENT_01; + }; + T dummy01; + }; + T Mutant; + T ImageBaseAddress; + T Ldr; + T ProcessParameters; + T SubSystemData; + T ProcessHeap; + T FastPebLock; + T _SYSTEM_DEPENDENT_02; + T _SYSTEM_DEPENDENT_03; + T _SYSTEM_DEPENDENT_04; + union + { + T KernelCallbackTable; + T UserSharedInfoPtr; + }; + DWORD SystemReserved; + DWORD _SYSTEM_DEPENDENT_05; + T _SYSTEM_DEPENDENT_06; + T TlsExpansionCounter; + T TlsBitmap; + DWORD TlsBitmapBits[2]; + T ReadOnlySharedMemoryBase; + T _SYSTEM_DEPENDENT_07; + T ReadOnlyStaticServerData; + T AnsiCodePageData; + T OemCodePageData; + T UnicodeCaseTableData; + DWORD NumberOfProcessors; + union + { + DWORD NtGlobalFlag; + NGF dummy02; + }; + LARGE_INTEGER CriticalSectionTimeout; + T HeapSegmentReserve; + T HeapSegmentCommit; + T HeapDeCommitTotalFreeThreshold; + T HeapDeCommitFreeBlockThreshold; + DWORD NumberOfHeaps; + DWORD MaximumNumberOfHeaps; + T ProcessHeaps; + + //FULL PEB not needed + /* T GdiSharedHandleTable; + T ProcessStarterHelper; + T GdiDCAttributeList; + T LoaderLock; + DWORD OSMajorVersion; + DWORD OSMinorVersion; + WORD OSBuildNumber; + WORD OSCSDVersion; + DWORD OSPlatformId; + DWORD ImageSubsystem; + DWORD ImageSubsystemMajorVersion; + T ImageSubsystemMinorVersion; + union + { + T ImageProcessAffinityMask; + T ActiveProcessAffinityMask; + }; + T GdiHandleBuffer[A]; + T PostProcessInitRoutine; + T TlsExpansionBitmap; + DWORD TlsExpansionBitmapBits[32]; + T SessionId; + ULARGE_INTEGER AppCompatFlags; + ULARGE_INTEGER AppCompatFlagsUser; + T pShimData; + T AppCompatInfo; + UNICODE_STRING_T CSDVersion; + T ActivationContextData; + T ProcessAssemblyStorageMap; + T SystemDefaultActivationContextData; + T SystemAssemblyStorageMap; + T MinimumStackCommit;*/ +}; + +typedef _PEB_T PEB32; +typedef _PEB_T PEB64; + +#ifdef _WIN64 +typedef PEB64 PEB_CURRENT; +#else +typedef PEB32 PEB_CURRENT; +#endif \ No newline at end of file diff --git a/TitanEngineEmulator/TitanEngineEmulator.cpp b/TitanEngineEmulator/TitanEngineEmulator.cpp index fdf8021..7f5295d 100644 --- a/TitanEngineEmulator/TitanEngineEmulator.cpp +++ b/TitanEngineEmulator/TitanEngineEmulator.cpp @@ -97,6 +97,11 @@ __declspec(dllexport) void* TITCALL GetPEBLocation(HANDLE hProcess) return emu.GetPEBLocation(hProcess); } +__declspec(dllexport) void* TITCALL GetPEBLocation64(HANDLE hProcess) +{ + return emu.GetPEBLocation64(hProcess); +} + __declspec(dllexport) void* TITCALL GetTEBLocation(HANDLE hThread) { return emu.GetTEBLocation(hThread); diff --git a/TitanEngineEmulator/TitanEngineEmulator.vcxproj b/TitanEngineEmulator/TitanEngineEmulator.vcxproj index 9b85c59..395cd50 100644 --- a/TitanEngineEmulator/TitanEngineEmulator.vcxproj +++ b/TitanEngineEmulator/TitanEngineEmulator.vcxproj @@ -155,6 +155,7 @@ + diff --git a/TitanEngineEmulator/TitanEngineEmulator.vcxproj.filters b/TitanEngineEmulator/TitanEngineEmulator.vcxproj.filters index e973e70..56208f4 100644 --- a/TitanEngineEmulator/TitanEngineEmulator.vcxproj.filters +++ b/TitanEngineEmulator/TitanEngineEmulator.vcxproj.filters @@ -25,5 +25,8 @@ Header Files + + Header Files + \ No newline at end of file