There are various flags in the PEB associated with a specific process such as the CrossProcessFlags, the BitField (4th member of the PEB), AppCompatFlags, and so forth. I’d always tried looking for differences in the flags when operating in a standard runtime environment vs. a debugged runtime environment and after many failed attempts to find any sort of variance in the flags, I moved on to a different part of the PEB – the ProcessParameters.
For anyone curious, these tests were performed on Windows 10 Pro x64. I will post the updated PEB structure at the end of this post as well for those interested in reproducing the results.
If you’re familiar with the ProcessParameters member of the PEB you’ll know that it has 4 different flag members associated with the RTL_USER_PROCESS_PARAMETERS structure. The Flags member is the MOI (member of interest.) I noticed when running in a standard runtime environment the 0th bit of the Flags member is 1, the 13th is 1, and the 14th bit is set as well. Nothing unusual until I debugged the application in WinDbg x64 and noticed that the 14th bit of the Flags becomes 0. I had some skepticism as to if this was just a coincidence, so I placed the application in my VM (Windows 10 Enterprise x64) and tested it and the 14th bit was set to 1. When a debugger was attached, the 14th bit was 0.
The values of the Flags member as an integer when a debugger is not attached is equivalent to 24577, and 8193 when a debugger is attached – just to make things easier.
I looked everywhere wondering if I had found some undocumented method of debugger detection and it seems only one other blog had information about.
That information can be found here. After reading his post it is clear that the creation flags affect this bit. See the link to get a few other details.
The application of this is simple, check the 14th bit of the ProcessParameters->Flags member to see if it is 0, if so – RtlSetProcessIsCritical and ExitProcess ;p
Use this information wisely, I’m sure many beginner reverse engineers wouldn’t think much of flag queries.
PPEB pPeb = reinterpret_cast< PPEB >( __readgsqword( 0x60 ) );
pPeb->ProcessParameters->Flags & ( 1 << 13 );
Link to Win10 PEB (Updated July, 2016): http://pastebin.com/am5RNncE