From 8efc8a4b5b4df0a7a055b188f4ea45fcf55da85c Mon Sep 17 00:00:00 2001 From: G36KV Date: Tue, 4 Mar 2014 18:58:59 +0100 Subject: [PATCH] better hidedebugger code, new exported function GetPEBLocation64 --- TitanEngine/Global.Engine.Hider.cpp | 214 ++++++++++++++++------------ TitanEngine/TitanEngine.Hider.cpp | 67 ++++++--- TitanEngine/definitions.h | 3 + TitanEngine/stdafx.h | 182 +++++++++++++++-------- 4 files changed, 302 insertions(+), 164 deletions(-) diff --git a/TitanEngine/Global.Engine.Hider.cpp b/TitanEngine/Global.Engine.Hider.cpp index 3edc97a..a5d6ddb 100644 --- a/TitanEngine/Global.Engine.Hider.cpp +++ b/TitanEngine/Global.Engine.Hider.cpp @@ -7,101 +7,131 @@ // Global.Engine.Hider.functions: 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; + 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; +} + +void FixAntidebugApiInProcess(HANDLE hProcess, bool Hide) +{ + const BYTE patchCheckRemoteDebuggerPresent[5] = {0x33, 0xC0, 0xC2, 0x08, 0x00}; + const BYTE patchGetTickCount[3] = {0x33, 0xC0, 0xC3}; + ULONG_PTR APIPatchAddress = NULL; + DWORD OldProtect; + SIZE_T ueNumberOfBytesRead = 0; + + if(Hide) + { + APIPatchAddress = (ULONG_PTR)EngineGlobalAPIHandler(hProcess, NULL, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"),"CheckRemoteDebuggerPresent"), NULL, UE_OPTION_IMPORTER_REALIGN_APIADDRESS); + + VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)APIPatchAddress, sizeof(patchCheckRemoteDebuggerPresent), PAGE_EXECUTE_READWRITE, &OldProtect); + WriteProcessMemory(hProcess, (LPVOID)(APIPatchAddress), &patchCheckRemoteDebuggerPresent, sizeof(patchCheckRemoteDebuggerPresent), &ueNumberOfBytesRead); + VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)APIPatchAddress, sizeof(patchCheckRemoteDebuggerPresent), OldProtect, &OldProtect); + + APIPatchAddress = (ULONG_PTR)EngineGlobalAPIHandler(hProcess, NULL, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"),"GetTickCount"), NULL, UE_OPTION_IMPORTER_REALIGN_APIADDRESS); + + VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)APIPatchAddress, sizeof(patchGetTickCount), PAGE_EXECUTE_READWRITE, &OldProtect); + WriteProcessMemory(hProcess, (LPVOID)(APIPatchAddress), &patchGetTickCount, sizeof(patchGetTickCount), &ueNumberOfBytesRead); + VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)APIPatchAddress, sizeof(patchGetTickCount), OldProtect, &OldProtect); + } + else + { + APIPatchAddress = (ULONG_PTR)EngineGlobalAPIHandler(hProcess, NULL, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"),"CheckRemoteDebuggerPresent"), NULL, UE_OPTION_IMPORTER_REALIGN_APIADDRESS); + + VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)APIPatchAddress, sizeof(patchCheckRemoteDebuggerPresent), PAGE_EXECUTE_READWRITE, &OldProtect); + WriteProcessMemory(hProcess, (LPVOID)(APIPatchAddress), (void*)GetProcAddress(GetModuleHandleA("kernel32.dll"),"CheckRemoteDebuggerPresent"), sizeof(patchCheckRemoteDebuggerPresent), &ueNumberOfBytesRead); + VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)APIPatchAddress, sizeof(patchCheckRemoteDebuggerPresent), OldProtect, &OldProtect); + + APIPatchAddress = (ULONG_PTR)EngineGlobalAPIHandler(hProcess, NULL, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"),"GetTickCount"), NULL, UE_OPTION_IMPORTER_REALIGN_APIADDRESS); + + VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)APIPatchAddress, sizeof(patchGetTickCount), PAGE_EXECUTE_READWRITE, &OldProtect); + WriteProcessMemory(hProcess, (LPVOID)(APIPatchAddress), (void*)GetProcAddress(GetModuleHandleA("kernel32.dll"),"GetTickCount"), sizeof(patchGetTickCount), &ueNumberOfBytesRead); + VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)APIPatchAddress, sizeof(patchGetTickCount), OldProtect, &OldProtect); + } +} + +bool FixPebInProcess(HANDLE hProcess, bool Hide) +{ + PEB_CURRENT myPEB = {0}; + SIZE_T ueNumberOfBytesRead = 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 + + if(Hide) + { + myPEB.BeingDebugged = FALSE; + myPEB.NtGlobalFlag &= ~0x70; + +#ifndef _WIN64 + myPEB64.BeingDebugged = FALSE; + myPEB64.NtGlobalFlag &= ~0x70; +#endif + + //Fix heap flags: https://github.com/eschweiler/ProReversing + //BYTE* Heap = (BYTE*)myPEB.ProcessHeap; + } + else + { + myPEB.BeingDebugged = TRUE; +#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 + + return true; + } + } + + return false; } bool ChangeHideDebuggerState(HANDLE hProcess, DWORD PatchAPILevel, bool Hide) { - static ULONG OldHeapFlags=0; - static ULONG OldForceFlag=0; - ULONG_PTR AddressOfPEB = NULL; - ULONG_PTR ueNumberOfBytesRead = NULL; - BYTE patchCheckRemoteDebuggerPresent[5] = {0x33, 0xC0, 0xC2, 0x08, 0x00}; - BYTE patchGetTickCount[3] = {0x33, 0xC0, 0xC3}; - MEMORY_BASIC_INFORMATION MemInfo; - ULONG_PTR APIPatchAddress = NULL; - DWORD OldProtect; - NTPEB myPEB = {}; + if(hProcess) + { + if (FixPebInProcess(hProcess, Hide)) + { + if(PatchAPILevel == UE_HIDE_BASIC) + { + FixAntidebugApiInProcess(hProcess, Hide); + } - if(hProcess != NULL) - { - AddressOfPEB = (ULONG_PTR)GetPEBLocation(hProcess); - if(ReadProcessMemory(hProcess, (void*)AddressOfPEB, (void*)&myPEB, sizeof NTPEB, &ueNumberOfBytesRead)) - { - if(Hide) - { - myPEB.BeingDebugged = false; - myPEB.NtGlobalFlag = NULL; - //Fix heap flags: https://github.com/eschweiler/ProReversing - BYTE* Heap=(BYTE*)myPEB.ProcessHeap; + return true; + } + } - if(WriteProcessMemory(hProcess, (void*)AddressOfPEB, (void*)&myPEB, sizeof NTPEB, &ueNumberOfBytesRead)) - { - if(PatchAPILevel == UE_HIDE_BASIC) - { - APIPatchAddress = (ULONG_PTR)EngineGlobalAPIHandler(hProcess, NULL, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"),"CheckRemoteDebuggerPresent"), NULL, UE_OPTION_IMPORTER_REALIGN_APIADDRESS); - VirtualQueryEx(dbgProcessInformation.hProcess, (LPVOID)APIPatchAddress, &MemInfo, sizeof MEMORY_BASIC_INFORMATION); - OldProtect = MemInfo.Protect; - VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)APIPatchAddress, 5, PAGE_EXECUTE_READWRITE, &OldProtect); - WriteProcessMemory(hProcess, (LPVOID)(APIPatchAddress), &patchCheckRemoteDebuggerPresent, 5, &ueNumberOfBytesRead); - - APIPatchAddress = (ULONG_PTR)EngineGlobalAPIHandler(hProcess, NULL, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"),"GetTickCount"), NULL, UE_OPTION_IMPORTER_REALIGN_APIADDRESS); - VirtualQueryEx(dbgProcessInformation.hProcess, (LPVOID)APIPatchAddress, &MemInfo, sizeof MEMORY_BASIC_INFORMATION); - OldProtect = MemInfo.Protect; - VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)APIPatchAddress, 3, PAGE_EXECUTE_READWRITE, &OldProtect); - WriteProcessMemory(hProcess, (LPVOID)(APIPatchAddress), &patchGetTickCount, 3, &ueNumberOfBytesRead); - } - return(true); - } - else - { - return(false); - } - } - else - { - myPEB.BeingDebugged = true; - if(WriteProcessMemory(hProcess, (void*)AddressOfPEB, (void*)&myPEB, sizeof NTPEB, &ueNumberOfBytesRead)) - { - if(PatchAPILevel == UE_HIDE_BASIC) - { - APIPatchAddress = (ULONG_PTR)EngineGlobalAPIHandler(hProcess, NULL, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"),"CheckRemoteDebuggerPresent"), NULL, UE_OPTION_IMPORTER_REALIGN_APIADDRESS); - VirtualQueryEx(dbgProcessInformation.hProcess, (LPVOID)APIPatchAddress, &MemInfo, sizeof MEMORY_BASIC_INFORMATION); - OldProtect = MemInfo.Protect; - VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)APIPatchAddress, 5, PAGE_EXECUTE_READWRITE, &OldProtect); - WriteProcessMemory(hProcess, (LPVOID)(APIPatchAddress), (void*)GetProcAddress(GetModuleHandleA("kernel32.dll"),"CheckRemoteDebuggerPresent"), 5, &ueNumberOfBytesRead); - - APIPatchAddress = (ULONG_PTR)EngineGlobalAPIHandler(hProcess, NULL, (ULONG_PTR)GetProcAddress(GetModuleHandleA("kernel32.dll"),"GetTickCount"), NULL, UE_OPTION_IMPORTER_REALIGN_APIADDRESS); - VirtualQueryEx(dbgProcessInformation.hProcess, (LPVOID)APIPatchAddress, &MemInfo, sizeof MEMORY_BASIC_INFORMATION); - OldProtect = MemInfo.Protect; - VirtualProtectEx(dbgProcessInformation.hProcess, (LPVOID)APIPatchAddress, 3, PAGE_EXECUTE_READWRITE, &OldProtect); - WriteProcessMemory(hProcess, (LPVOID)(APIPatchAddress), (void*)GetProcAddress(GetModuleHandleA("kernel32.dll"),"GetTickCount"), 3, &ueNumberOfBytesRead); - } - return(true); - } - else - { - return(false); - } - } - } - else - { - return(false); - } - } - else - { - return(false); - } - return(false); -} \ No newline at end of file + return false; +} diff --git a/TitanEngine/TitanEngine.Hider.cpp b/TitanEngine/TitanEngine.Hider.cpp index 3b56e1e..dadc90d 100644 --- a/TitanEngine/TitanEngine.Hider.cpp +++ b/TitanEngine/TitanEngine.Hider.cpp @@ -5,35 +5,70 @@ // TitanEngine.Hider.functions: __declspec(dllexport) void* TITCALL GetPEBLocation(HANDLE hProcess) { - ULONG RequiredLen = NULL; - PPROCESS_BASIC_INFORMATION myProcessBasicInformation = (PPROCESS_BASIC_INFORMATION)VirtualAlloc(NULL, 0x1000, MEM_COMMIT, PAGE_READWRITE); + ULONG RequiredLen = 0; + void * PebAddress = 0; + PPROCESS_BASIC_INFORMATION myProcessBasicInformation = (PPROCESS_BASIC_INFORMATION)VirtualAlloc(NULL, sizeof(PROCESS_BASIC_INFORMATION) * 4, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE); if(!myProcessBasicInformation) return 0; -#if !defined(_WIN64) - typedef NTSTATUS(WINAPI *fZwQueryInformationProcess)(HANDLE ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength); -#else - typedef NTSTATUS(__fastcall *fZwQueryInformationProcess)(HANDLE ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength); -#endif - LPVOID ZwQueryInformationProcess = (LPVOID)GetProcAddress(GetModuleHandleA("ntdll.dll"),"ZwQueryInformationProcess"); - fZwQueryInformationProcess cZwQueryInformationProcess = (fZwQueryInformationProcess)(ZwQueryInformationProcess); - if(cZwQueryInformationProcess != NULL) +#if !defined(_WIN64) + typedef NTSTATUS(WINAPI *fNtQueryInformationProcess)(HANDLE ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength); +#else + typedef NTSTATUS(__fastcall *fNtQueryInformationProcess)(HANDLE ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength); +#endif + + fNtQueryInformationProcess cNtQueryInformationProcess = (fNtQueryInformationProcess)GetProcAddress(GetModuleHandleA("ntdll.dll"),"NtQueryInformationProcess"); + + if(cNtQueryInformationProcess != NULL) { - if(cZwQueryInformationProcess(hProcess, ProcessBasicInformation, myProcessBasicInformation, sizeof PROCESS_BASIC_INFORMATION, &RequiredLen) == STATUS_SUCCESS) + if(cNtQueryInformationProcess(hProcess, ProcessBasicInformation, myProcessBasicInformation, sizeof(PROCESS_BASIC_INFORMATION), &RequiredLen) == STATUS_SUCCESS) { - return (void*)myProcessBasicInformation->PebBaseAddress; + PebAddress = (void*)myProcessBasicInformation->PebBaseAddress; } else { - if(cZwQueryInformationProcess(hProcess, ProcessBasicInformation, myProcessBasicInformation, RequiredLen, &RequiredLen) == STATUS_SUCCESS) + if(cNtQueryInformationProcess(hProcess, ProcessBasicInformation, myProcessBasicInformation, RequiredLen, &RequiredLen) == STATUS_SUCCESS) { - return (void*)myProcessBasicInformation->PebBaseAddress; + PebAddress = (void*)myProcessBasicInformation->PebBaseAddress; } } - } - return NULL; + } + + VirtualFree(myProcessBasicInformation, 0, MEM_RELEASE); + return PebAddress; } +#ifndef _WIN64 +typedef BOOL (WINAPI * tIsWow64Process)(HANDLE hProcess,PBOOL Wow64Process); + +static bool IsThisProcessWow64() +{ + BOOL bIsWow64 = FALSE; + tIsWow64Process fnIsWow64Process = (tIsWow64Process)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsWow64Process"); + + if (fnIsWow64Process) + { + fnIsWow64Process(GetCurrentProcess(), &bIsWow64); + } + + return (bIsWow64 != FALSE); +} + +__declspec(dllexport) void* TITCALL GetPEBLocation64(HANDLE hProcess) +{ + if (IsThisProcessWow64()) + { + //Only WOW64 processes have 2 PEBs + DWORD peb32 = (DWORD)GetPEBLocation(hProcess); + peb32 += 0x1000; //PEB64 after PEB32 + return (void *)peb32; + } + + return 0; +} + +#endif + __declspec(dllexport) bool TITCALL HideDebugger(HANDLE hProcess, DWORD PatchAPILevel) { return ChangeHideDebuggerState(hProcess, PatchAPILevel, true); diff --git a/TitanEngine/definitions.h b/TitanEngine/definitions.h index 656ff57..ecd271f 100644 --- a/TitanEngine/definitions.h +++ b/TitanEngine/definitions.h @@ -89,6 +89,9 @@ __declspec(dllexport) bool TITCALL IsFileDLL(char* szFileName, ULONG_PTR FileMap __declspec(dllexport) bool TITCALL IsFileDLLW(wchar_t* szFileName, ULONG_PTR FileMapVA); // TitanEngine.Hider.functions: __declspec(dllexport) void* TITCALL GetPEBLocation(HANDLE hProcess); +#ifndef _WIN64 +__declspec(dllexport) void* TITCALL GetPEBLocation64(HANDLE hProcess); +#endif __declspec(dllexport) bool TITCALL HideDebugger(HANDLE hProcess, DWORD PatchAPILevel); __declspec(dllexport) bool TITCALL UnHideDebugger(HANDLE hProcess, DWORD PatchAPILevel); // TitanEngine.Relocater.functions: diff --git a/TitanEngine/stdafx.h b/TitanEngine/stdafx.h index c70da1b..3cdd0c4 100644 --- a/TitanEngine/stdafx.h +++ b/TitanEngine/stdafx.h @@ -869,60 +869,130 @@ typedef struct _RTL_USER_PROCESS_PARAMETERS { RTL_DRIVE_LETTER_CURDIR DLCurrentDirectory[0x20]; } RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;*/ -typedef struct _NTPEB + + +/////////////////////////////////////////////////////////////////////////////////////// +//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 / + +#pragma pack(push) +#pragma pack(1) +template +struct LIST_ENTRY_T { - BOOLEAN InheritedAddressSpace; - BOOLEAN ReadImageFileExecOptions; - BOOLEAN BeingDebugged; - BOOLEAN Spare; - HANDLE Mutant; - PVOID ImageBaseAddress; - PPEB_LDR_DATA LoaderData; - PRTL_USER_PROCESS_PARAMETERS ProcessParameters; - PVOID SubSystemData; - PVOID ProcessHeap; - PVOID FastPebLock; - void* FastPebLockRoutine; - void* FastPebUnlockRoutine; - ULONG EnvironmentUpdateCount; - PVOID* KernelCallbackTable; - PVOID EventLogSection; - PVOID EventLog; - void* FreeList; - ULONG TlsExpansionCounter; - PVOID TlsBitmap; - ULONG TlsBitmapBits[0x2]; - PVOID ReadOnlySharedMemoryBase; - PVOID ReadOnlySharedMemoryHeap; - PVOID* ReadOnlyStaticServerData; - PVOID AnsiCodePageData; - PVOID OemCodePageData; - PVOID UnicodeCaseTableData; - ULONG NumberOfProcessors; - ULONG NtGlobalFlag; - BYTE Spare2[0x4]; - LARGE_INTEGER CriticalSectionTimeout; - ULONG HeapSegmentReserve; - ULONG HeapSegmentCommit; - ULONG HeapDeCommitTotalFreeThreshold; - ULONG HeapDeCommitFreeBlockThreshold; - ULONG NumberOfHeaps; - ULONG MaximumNumberOfHeaps; - PVOID* *ProcessHeaps; - PVOID GdiSharedHandleTable; - PVOID ProcessStarterHelper; - PVOID GdiDCAttributeList; - PVOID LoaderLock; - ULONG OSMajorVersion; - ULONG OSMinorVersion; - ULONG OSBuildNumber; - ULONG OSPlatformId; - ULONG ImageSubSystem; - ULONG ImageSubSystemMajorVersion; - ULONG ImageSubSystemMinorVersion; - ULONG GdiHandleBuffer[0x22]; - ULONG PostProcessInitRoutine; - ULONG TlsExpansionBitmap; - BYTE TlsExpansionBitmapBits[0x80]; - ULONG SessionId; -} NTPEB, *PNTPEB; + 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; + 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