cpluse

落雪的时候,鸟都不飞,云也不飘

 

Basic debugger detection techniques in Windows (转载)

Today, I would like to present some of the basic debugger detection techniques in Windows NT systems. Detecting if an application runs under the debugger is a crucial step to prevent reverse engineering of application. Keep in mind, whatever you do to hide a debugger, there is always a method or methods to detect it. The techniques I will show here assuming that the debugger is ring 3 debugger (debugger running in user mode) like OllyDbg or WinDbg.

 

1. Kernel32.IsDebuggerPresent
The most basic funtion to debugger detection (and bypass) is calling IsDebuggerPresent method from Kernel32 library. The function itself just read BeingDebugged flag from PEB structure.

1
2
3
call IsDebuggerPresent
test eax, eax
jne @DebuggerHasBeenDetected ; debugger detection

The next two techniques are using PEB structure to detect if programs runs under debugger control. PEB structure is definied as below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
typedef struct _PEB {
 BYTE Reserved1[2];
 BYTE BeingDebugged;
 BYTE Reserved2[1];
 PVOID Reserved3[2];
 PPEB_LDR_DATA Ldr;
 PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
 BYTE Reserved4[104];
 PVOID Reserved5[52];
 PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
 BYTE Reserved6[128];
 PVOID Reserved7[1];
 ULONG SessionId;
} PEB, *PPEB;

2. PEB.BeingDebugged
This technique works almost in the same way as the one above, but PEB structure is accessed directly.

1
2
3
4
mov eax, fs:[0x30]
mov eax, byte [eax + 2]
test eax, eax
jne @DebuggerHasBeenDetected ; debugger detection

3. PEB.NtGlobalFlags 

 

As soon as the process is created, the system will set some flags in PEB structure (at offset 0×68) to determine, how some of APIs will behave. We can use this information to debugger detection – if process has been launched by debugger we must check some flags (FLG_HEAP_ENABLE_FREE_CHECK, FLG_HEAP_ENABLE_TAIL_CHECK and FLG_HEAP_VALIDATE_PARAMETERS).

 

1
2
3
4
5
mov eax, fs:[0x30]
mov eax, [eax+0x68]
and eax, 0×70
test eax, eax
jne @DebuggerHasBeenDetected ; debugger detection

4. Ntdll.NtQueryInformationProcess
NtQueryInformationProcess method is used to retrieve information about process. Below is the method signature:

1
2
3
4
5
6
7
NTSTATUS WINAPI NtQueryInformationProcess(
 _In_ HANDLE ProcessHandle,
 _In_ PROCESSINFOCLASS ProcessInformationClass,
 _Out_ PVOID ProcessInformation,
 _In_ ULONG ProcessInformationLength,
 _Out_opt_ PULONG ReturnLength
);

When the NtQueryInformationProcess is called with ProcessInformationClass set to 7, the system will set ProcessInformation to -1 if the process is debugged. It’s very powerful technique, since there is no easy way to bypass it (you can bypass it by modifing ProcessInformation when the syscall returns).

1
2
3
4
5
6
7
8
9
10
push 0
push 4
push offset IsDebugged
push 7
push -1
call NtQueryInformationProcess
test eax, eax
jne @ExitError
cmp IsDebugged, 0
jne @DebuggerHasBeenDetected

5. kernel32.CheckRemoteDebuggerPresent
This method is using technique described above to detect if program is running under debugger control. The function CheckRemoteDebuggerPresent takes two arguments: a handle to process, and a pointer to variable which funtion sets to true if the debugger has been detected. Below function signature and example usage.

1
2
3
4
BOOL WINAPI CheckRemoteDebuggerPresent(
 _In_ HANDLE hProcess,
 _Inout_ PBOOL pbDebuggerPresent
);
1
2
3
4
5
push offset IsDebugged
push -1
call CheckRemoteDebuggerPresent
test eax, eax
jne @DebuggerHasBeenDetected

Resources:

http://en.wikipedia.org/wiki/Process_Environment_Block

posted on 2014-03-18 20:57  cpluse  阅读(177)  评论(0)    收藏  举报

导航