一.PEB.BeingDebugged
BeingDebugged成员是一个标志(Flag),用来标识进程是否处于被调试状态。
进程处于调试状态时,PEB.BeingDebugged成员(+0x2)的值被设为1(TRUE);进程在非调试状态下运行时,值被设置为0(FALSE).
IsDebuggerPresent()API获取PEB.BeingDebugged的值来判断进程是否处于被调试状态,
IsDebuggerPresent()函数就是先获取TEB结构地址,再通过TEB.ProcessEnvironmentBlock成员(+0x30)获取PEB的地址,然后访问PEB.BeingDebugged成员.
二.NtQuerylnformationProcess()
函数原型:
__kernel_entry NTSTATUS NtQueryInformationProcess(
[in] HANDLE ProcessHandle,
[in] PROCESSINFOCLASS ProcessInformationClass,
[out] PVOID ProcessInformation,
[in] ULONG ProcessInformationLength,
[out, optional] PULONG ReturnLength );
通过这个API可以获得与进程调试相关的信息,ProcessInformationClass参数是一个枚举类型,其与调试器探测有关的成员为
ProcessDebugPort(0x7),ProcessDebugObjectHandle(0x1e),ProcessDebugFlags(0x1f)
ProcessDebugPort:
进程处于被调试状态时,系统会为它分配1个调试端口,当ProcessInformationClass设置为ProcessDebugPort时,就能获取调试端口,若进程处于调试状态,其获取的值为0xffffffff,反之则为0。
CheckRemoteDebuggerPresent()API与IsDebuggerPresent相似,但CheckRemoteDebuggerPresent还可以用来检测其他进程是否处于被调试状态,在CheckRemoteDebuggerPresent函数里,则是调用了NtQuerylnformationProcess,其第二个参数正是ProcessDebugPort。
ProcessDebugObjectHandle:
调试进程时会生成调试对象,当ProcessInformationClass设置为ProcessDebugObjectHandle时,就能获取到调试对象句柄,进程处于调试状态时,调试对象句柄就存在,反之则为NULL.
ProcessDebugFlags:
检测Debug Flags(调试标志)的值也可以判断进程是否处于被调试状态,当ProcessInformationClass设置为ProcessDebugFlags时,就能获取调试标志的值,为0则处于调试状态,反之则为1。