implement HideDebugger

This commit is contained in:
Duncan Ogilvie 2017-12-11 21:11:55 +01:00
parent 4cb07be1f5
commit 8b4d39653e
No known key found for this signature in database
GPG Key ID: FC89E0AAA0C1AAD8
5 changed files with 326 additions and 1 deletions

View File

@ -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*);

129
TitanEngineEmulator/PEB.h Normal file
View File

@ -0,0 +1,129 @@
#pragma once
#include <windows.h>
///////////////////////////////////////////////////////////////////////////////////////
//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 <class T>
struct LIST_ENTRY_T
{
T Flink;
T Blink;
};
template <class T>
struct UNICODE_STRING_T
{
union
{
struct
{
WORD Length;
WORD MaximumLength;
};
T dummy;
};
T _Buffer;
};
template <class T, class NGF, int A>
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<T> CSDVersion;
T ActivationContextData;
T ProcessAssemblyStorageMap;
T SystemDefaultActivationContextData;
T SystemAssemblyStorageMap;
T MinimumStackCommit;*/
};
typedef _PEB_T<DWORD, DWORD64, 34> PEB32;
typedef _PEB_T<DWORD64, DWORD, 30> PEB64;
#ifdef _WIN64
typedef PEB64 PEB_CURRENT;
#else
typedef PEB32 PEB_CURRENT;
#endif

View File

@ -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);

View File

@ -155,6 +155,7 @@
<ItemGroup>
<ClInclude Include="Emulator.h" />
<ClInclude Include="FileMap.h" />
<ClInclude Include="PEB.h" />
<ClInclude Include="TitanEngine.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

View File

@ -25,5 +25,8 @@
<ClInclude Include="FileMap.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="PEB.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>