0x01 NtQueryInformationProcess ()
一、NtQueryInformationProcess ()
函数原型:
NTSYSAPI NTSTATUS NTAPI NtQueryInformationProcess (
IN HANDLE ProcessHandle, // 进程句柄
IN PROCESSINFOCLASS InformationClass, // 信息类型
OUT PVOID ProcessInformation, // 缓冲指针
IN ULONG ProcessInformationLength, // 以字节为单位的缓冲大小
OUT PULONG ReturnLength OPTIONAL // 写入缓冲的字节数
);
第二个参数是一个枚举类型,其中与反调试有关的成员有ProcessDebugPort(0x7)、ProcessDebugObjectHandle(0x1E)和ProcessDebugFlags(0x1F)三种
ProcessDebugPort(0x7)
进程处于调试状态时,操作系统会为他分配1个调试端口(debug port) , InformationClass设为ProcessDebugPort(0x07) 时,调用NtQueryInformationProcess()函数就可以获取调试端口。若处于调试状态 , 第三个参数会被置为0xFFFFFFFF(-1);若处于非调试状态,第三个参数值会被设置为0ProcessDebugObjectHandle(0x1E)
调试进程时,会生成一个调试对象(Debug Obiect)。 NtQueryInformationProcess() 第二个参数值为0x1E时 , 函数的第三个参数就能获取到调试对象句柄 ,进程处于调试状态->调试句柄存在->返回值不为 NULL ;处于非调试状态 , 返回值为 NULL。ProcessDebugFlags(0x1F)
调试标志:Debug Flags 。检测调试标志的值也可以判断进程是否处于被调试状态。当 NtQueryInformationProcess() 第二个参数为0x1F时,第三个参数:调试状态:0;非调试状态:1破解方法:直接 HOOK API;修改返回值;利用 OD 插件 strong OD 中 KernelMode 可以绕过。
二、CheckRemoteDebuggerPresent()
该函数可以与 IsdebuggerPresent()类似,可以检测进程是否处于调试状态,且其不仅仅可以检测自身是否处于调试状态,还可以检测其他程序是否处于调试状态。如果调试器存在 (通常是检测自己是否正在被调试),该函数会将pbDebuggerPresent
指向的值设为0xffffffff
。其函数实际上是利用了前面的 NtQueryInformationProcess () 函数中的 ProcessDebugPort 实现的。函数原型为:
BOOL WINAPI CheckRemoteDebuggerPresent(
_In_ HANDLE hProcess,
_Inout_ PBOOL pbDebuggerPresent
);
破解方法:利用 NtQueryInformationProcess () 的破解方法即可。