跳转至

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