Debug flags in the PEB

A thread is the basic unit of execution.  The process itself is run as a thread entity that is capable of triggering multiple threads in the same process space. The information about the currently running thread is stored in the the Thread Environment Block (TEB).  The TEB is also called the Thread Information Block (TIB) and contains information such as the thread ID, structured error handling frame, stack base address and limit, and the address pointing to information about the process the thread is running under.  Information about the process is stored in the Process Environment Block (PEB).

The PEB contains information like pointer to tables that lists the loaded modules, command line parameters used to run the process, information taken from the PE header, and if it is being debugged.  The TIB and PEB structures are documented by Microsoft at https://docs.microsoft.com/en-us/windows/desktop/api/winternl/.

PEB has fields that can be used to identify whether a process is being debugged: the BeingDebugged and NtGlobalFlag flags. In PEB, these are located at the following locations:

Offset Information
0x02 BeingDebugged (1 for True) - BYTE
0x68 GlobalNTFlag (usually 0x70 when debugged) - DWORD

 

Internally, IsDebuggerPresent works with this code:

Let's check what is happening with the IsDebuggerPresent code:

mov eax, dword ptr fs:[18]

The preceding line retrieves the address of the Thread Environment Block (TEB) from the Thread Information Block (TIB). The FS segment contains TIB. TEB address is stored at offset 0x18 of TIB. TIB is stored in the eax register.

The following line retrieves PEB address and stores it in the eax register. The PEB address is located at offset 0x30 of TEB:

mov eax, dword ptr ds:[eax+30]

The byte at offset 2 of PEB contains a Boolean value of 1 or 0, indicating whether the process is being debugged or not:

movzx eax, byte ptr ds:[eax+2]

If we wanted to create our own function, but applied this with GlobalNTFlag, we can make the code look like this:

mov eax, dword ptr fs:[18]
mov eax, dword ptr ds:[eax+0x30]
mov eax, dword ptr ds:[eax+0x68]
cmp eax, 0x70
setz al
and eax, 1

The first three lines of the preceding block basically retrieve GlobalNTFlag at offset 0x68 of PEB

The following cmp instruction will set the zero flag to 1 if the value of eax is equal to 0x70:

cmp eax, 0x70

The setz instruction will set the al register with what ZF is, which should either be 0 or 1:

setz al

Finally, the and instruction will only retain the first bit for the eax register, which, as a result, clears the register, but retains a value of either 1 or 0, for true or false:

and eax, 1
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.220.16.184