Skip to content

Anti Debugging Tricks

Noteworthy edited this page Jan 11, 2019 · 5 revisions

This page describes the technical details of anti-debug checks that are performed by Al-Khaser.

IsDebuggerPresent

Calls the IsDebuggerPresent() API. This function is part of the Win32 Debugging API and it returns TRUE if a user mode debugger is present. Internally, it simply returns the value of the PEB->BeingDebugged flag.

CheckRemoteDebuggerPresent

CheckRemoteDebuggerPresent() is another Win32 Debugging API function; it can be used to check if a remote process is being debugged. However, we can also use this as another method for checking if our own process is being debugged. This API internally calls the NTDLL export NtQueryInformationProcess function with the SYSTEM_INFORMATION_CLASS set to 7 (ProcessDebugPort).

BeingDebugged

Checks if the BeingDebugged flag is set in the Process Environment Block (PEB). This is effectively the same code that IsDebuggerPresent() executes internally. The PEB pointer is fetched from DWORD FS:[0x30] on x86_32 and QWORD GS:[0x60] on x86_64.

NtGlobalFlag

NtGlobalFlag is a DWORD value inside the process PEB. This value contains many flags set by the OS that affects the way the process runs. When a process is being debugged, the flags FLG_HEAP_ENABLE_TAIL_CHECK (0x10), FLG_HEAP_ENABLE_FREE_CHECK (0x20), and FLG_HEAP_VALIDATE_PARAMETERS(0x40) are set for the process

If the 32-bit executable is being run on a 64-bit system, both the 32-bit and 64-bit PEBs are checked. The WoW64 PEB address is fetched via the WoW64 Thread Environment Block (TEB) at FS:[0x18]-0x2000.

ProcessHeap (Flags)

Check if the Flags field of the ProcessHeap structure in the PEB has a value greater than 2.

ProcessHeap (ForceFlags)

Check if the ForceFlags field of the ProcessHeap structure in the PEB has a value greater than 0.

NtQueryInformationProcess (ProcessDebugPort)

Calls the NtQueryInformationProcess API with ProcessDebugPort (0x07) information class.

The test returns true if the operation succeeds and the returned value is nonzero.

NtQueryInformationProcess (ProcessDebugObject)

Calls the NtQueryInformationProcess API with ProcessDebugObjectHandle (0x1E) information class.

The test returns true if the operation succeeds and the returned value is nonzero.

NtQueryInformationProcess (ProcessDebugFlags)

Calls the NtQueryInformationProcess API with ProcessDebugFlags (0x1F) information class.

The test returns true if the operation succeeds and the returned value is nonzero.

NtSetInformationThread (HideThreadFromDebugger)

Calls the NtSetInformationThread API with the ThreadHideFromDebugger (0x11) information class.

The API is first called with a bogus class length value to catch out hooks that ignore the information data and length - if the call succeeds we know it is hooked. Next it is called with a bogus thread handle - if the call succeeds we know it is hooked. Finally the API is called properly, and on Windows Vista and later the flag is checked using the NtQueryInformationThread API.

NtQueryObject (ObjectTypeInformation)

TODO: Description

NtQueryObject (ObjectAllTypesInformation)

TODO: Description

CloseHanlde (NtClose) Invalide Handle

TODO: Description

SetHandleInformation (Protected Handle)

TODO: Description

UnhandledExceptionFilter

TODO: Description

OutputDebugString (GetLastError())

TODO: Description

Hardware Breakpoints (SEH / GetThreadContext)

TODO: Description

Software Breakpoints (INT3 / 0xCC)

TODO: Description

Memory Breakpoints (PAGE_GUARD)

TODO: Description

Interrupt 0x2d

TODO: Description

Interrupt 1

TODO: Description

Parent Process (Explorer.exe)

TODO: Description

SeDebugPrivilege (Csrss.exe)

TODO: Description

NtYieldExecution / SwitchToThread

TODO: Description

TLS callbacks

TODO: Description

Process jobs

TODO: Description

Memory write watching

TODO: Description

Clone this wiki locally