创建线程就能发现调试器

SYSTEM_HANDLE_INFORMATION SYSTEM_HANDLE_INFORMATION_EX

Baklib
狐白 最后一次编辑 接近 3 年前
291
在windows调试体系中当被调试进程创建线程时, 内核会用DbgkpOpenHandles来打开线程句柄
这样一来调试器句柄表里就会有创建的线程句柄,那么如何来检测呢
NTSTATUS ZwQuerySystemInformation ( SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, ULONG *ReturnLength);
ZwQuerySystemInformation这个函数具有枚举系统所有进程句柄表的功能 
SystemHandleInformation (0x10) 以及 SystemExtendedHandleInformation (0x40)
typedef struct _SYSTEM_HANDLE_INFORMATION_OBJECT { ULONG ProcessId; UCHAR ObjectTypeNumber; UCHAR Flags; USHORT Handle; PVOID Object; ACCESS_MASK GrantedAccess; }SYSTEM_HANDLE_INFORMATION_OBJECT, * PSYSTEM_HANDLE_INFORMATION_OBJECT;
所以检测思路,第一步拿到创建线程的句柄 在使用SystemHandleInformation  判断 HandleInfo->Information[i].ProcessId == 自身PID 
为什么要判断呢, 因为我们要拿到线程标志,去判断这个线程句柄是否是我们创建的线程
在判断 HandleInfo->Information[i].ObjectTypeNumber == 8 
ObjectTypeNumber 是对象类型  8就是Thread 7是Process
之后判断 Handle == 线程句柄 拿到Object 这个就是内核对象,我们判断也是判断这个
  过滤system进程是必要的  
然后重复操作 只要判断Object是否是自身线程的即可,新创建的线程 系统进程是不会去打开的 除了system
完事后NtClose 结束线程.
调试器如何应对呢  断链内核句柄表 和 虚拟句柄 只要线程进程无句柄就行