void ReadPebToBuffer(HANDLE hProcess, unsigned char * buffer, int bufferSize) { void * AddressOfPEB = GetPEBLocation(hProcess); if (AddressOfPEB) { if (!ReadProcessMemory(hProcess, AddressOfPEB, (void*)buffer, bufferSize, 0)) { LogError("ReadPebToBuffer->ReadProcessMemory failed"); } } else { LogErrorBox("ReadPebToBuffer->GetPEBLocation returns NULL"); } }
void* GetPEBLocation64(HANDLE hProcess) { #ifndef _WIN64 if (IsThisProcessWow64()) { //Only WOW64 processes have 2 PEBs DWORD peb32 = (DWORD)GetPEBLocation(hProcess); if (peb32) { peb32 += 0x1000; //PEB64 after PEB32 return (void *)peb32; } else { LogDebug("GetPEBLocation64->GetPEBLocation returns NULL"); } } #endif //_WIN64 return 0; }
bool FixIsDebuggerPresent(HANDLE hProcess, bool hide) { if(!hProcess) return false; unsigned int peb_addr=(unsigned int)GetPEBLocation(hProcess); if(!peb_addr) return false; NTPEB myPeb= {0}; if(!ReadProcessMemory(hProcess, (void*)peb_addr, &myPeb, sizeof(NTPEB), 0)) return false; if(hide) { myPeb.BeingDebugged=false; myPeb.NtGlobalFlag=0; } else myPeb.BeingDebugged=true; if(!WriteProcessMemory(hProcess, (void*)peb_addr, &myPeb, sizeof(NTPEB), 0)) return false; return true; }
void FixPebBeingDebugged(HANDLE hProcess, bool SetToNull) { PEB_CURRENT myPEB = { 0 }; #ifndef _WIN64 PEB64 myPEB64 = { 0 }; void * AddressOfPEB64 = GetPEBLocation64(hProcess); #endif void * AddressOfPEB = GetPEBLocation(hProcess); ReadProcessMemory(hProcess, AddressOfPEB, (void*)&myPEB, 0x10, 0); #ifndef _WIN64 if (AddressOfPEB64) { ReadProcessMemory(hProcess, AddressOfPEB64, (void*)&myPEB64, 0x10, 0); } #endif if (SetToNull) { myPEB.BeingDebugged = FALSE; #ifndef _WIN64 myPEB64.BeingDebugged = FALSE; #endif } else { myPEB.BeingDebugged = TRUE; #ifndef _WIN64 myPEB64.BeingDebugged = TRUE; #endif } WriteProcessMemory(hProcess, AddressOfPEB, (void*)&myPEB, 0x10, 0); #ifndef _WIN64 if (AddressOfPEB64) { WriteProcessMemory(hProcess, AddressOfPEB64, (void*)&myPEB64, 0x10, 0); } #endif }
bool FixPebInProcess(HANDLE hProcess, DWORD EnableFlags) { 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 (EnableFlags & PEB_PATCH_StartUpInfo) FixStartUpInfo(&myPEB, hProcess); if (EnableFlags & PEB_PATCH_BeingDebugged) myPEB.BeingDebugged = FALSE; if (EnableFlags & PEB_PATCH_NtGlobalFlag) myPEB.NtGlobalFlag &= ~0x70; #ifndef _WIN64 if (EnableFlags & PEB_PATCH_BeingDebugged) myPEB64.BeingDebugged = FALSE; if (EnableFlags & PEB_PATCH_NtGlobalFlag) myPEB64.NtGlobalFlag &= ~0x70; #endif if (EnableFlags & PEB_PATCH_HeapFlags) { //handle to the default heap of the calling process FixHeapFlag(hProcess, myPEB.ProcessHeap, true); if (myPEB.NumberOfHeaps > 1) //first is always default heap -> myPEB.ProcessHeap { PVOID * heapArray = (PVOID *)calloc(myPEB.NumberOfHeaps, sizeof(PVOID)); if (heapArray) { ReadProcessMemory(hProcess, (PVOID)myPEB.ProcessHeaps, heapArray, myPEB.NumberOfHeaps*sizeof(PVOID), 0); //skip index 0 same as default heap myPEB.ProcessHeap for (DWORD i = 1; i < myPEB.NumberOfHeaps; i++) { FixHeapFlag(hProcess, (DWORD_PTR)heapArray[i], false); } } free(heapArray); } } 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; }