跳转至

NtQueryInformationProcess

NTSTATUS WINAPI NtQueryInformationProcess(
  _In_      HANDLE           ProcessHandle,
  _In_      PROCESSINFOCLASS ProcessInformationClass,
  _Out_     PVOID            ProcessInformation,
  _In_      ULONG            ProcessInformationLength,
  _Out_opt_ PULONG           ReturnLength
);

ProcessDebugPort

未公开的ntdllNtQueryInformationProcess()函数接受一个信息类的参数用于查询. ProcessDebugPort(7)是其中的一个信息类. kernel32CheckRemoteDebuggerPresent()函数内部通过调用NtQueryInformationProcess()来检测调试, 而NtQueryInformationProcess内部则是查询EPROCESS结构体的DebugPort字段, 当进程正在被调试时, 返回值为0xffffffff.

可以用以下32位代码在32位环境进行检测:

push eax
mov eax, esp
push 0
push 4 ;ProcessInformationLength
push eax
push 7 ;ProcessDebugPort
push -1 ;GetCurrentProcess()
call NtQueryInformationProcess
pop eax
inc eax
je being_debugged

用以下64位代码在64位环境进行检测:

xor ebp, ebp
enter 20h, 0
push 8 ;ProcessInformationLength
pop r9
push rbp
pop r8
push 7 ;ProcessDebugPort
pop rdx
or rcx, -1 ;GetCurrentProcess()
call NtQueryInformationProcess
leave
test ebp, ebp
jne being_debugged

由于信息传自内核, 所以在用户模式下的代码没有轻松的方法阻止该函数检测调试器.

ProcessDebugObjectHandle

Windows XP引入了debug对象, 当一个调试会话启动, 会同时创建一个debug对象以及与之关联的句柄. 我们可以使用ProcessDebugObjectHandle (0x1e)类来查询这个句柄的值

可以用以下32位代码在32位环境进行检测:

push 0
mov eax, esp
push 0
push 4 ;ProcessInformationLength
push eax
push 1eh ;ProcessDebugObjectHandle
push -1 ;GetCurrentProcess()
call NtQueryInformationProcess
pop eax
test eax, eax
jne being_debugged

用以下64位代码在64位环境进行检测:

xor ebp, ebp
enter 20h, 0
push 8 ;ProcessInformationLength
pop r9
push rbp
pop r8
push 1eh ;ProcessDebugObjectHandle
pop rdx
or rcx, -1 ;GetCurrentProcess()
call NtQueryInformationProcess
leave
test ebp, ebp
jne being_debugged

ProcessDebugFlags

ProcessDebugFlags (0x1f)类返回EPROCESS结构体的NoDebugInherit的相反数. 意思是, 当调试器存在时, 返回值为0, 不存在时则返回1.

可以用以下32位代码在32位环境进行检测:

push eax
mov eax, esp
push 0
push 4 ;ProcessInformationLength
push eax
push 1fh ;ProcessDebugFlags
push -1 ;GetCurrentProcess()
call NtQueryInformationProcess
pop eax
test eax, eax
je being_debugged

用以下64位代码在64位环境进行检测:

xor ebp, ebp
enter 20h, 0
push 4 ;ProcessInformationLength
pop r9
push rbp
pop r8
push 1fh ;ProcessDebugFlags
pop rdx
or rcx, -1 ;GetCurrentProcess()
call NtQueryInformationProcess
leave
test ebp, ebp
je being_debugged