NtQueryObject 获得内核对象使用计数

一个内核对象有两个计数器:一个是句柄计数,句柄是给用户态用的;另一个是指针计数,也叫引用计数,因为核心态也常常用到内核对象,为了方便,在核心态的代码用指针直接访问对象,所以Object   Manager维护了这个指针引用计数。只有在句柄计数和引用计数都为0时,对象才被释放。一般而言,指针引用计数值比句柄计数值大。

再进一步,实际上,在用户态其实是可以查询一个内核对象的句柄计数和引用计数的。Ntdll.dll里导出的NtQueryObject函数可以查询内核对象的当前状态,只不过它没有被文档化。

函数声明如下:
DWORD   WINAPI   NtQueryObject(   HANDLE   handle,   DWORD   nQueryIndex,   VOID*   pOutBuffer,   DWORD   cbInBufferSize,   VOID*   cbOutBufferSize);

handle   --   待查询的句柄
nQueryIndex   --   0为查询对象的当前状态,包括句柄计数,引用计数等等。
pOutBuffer   --   存放查询结果
cbInBufferSize   --   pOutBuffer的大小,注意,如果nQueryIndex为0,这里一定得是0x38
cbOutBufferSize   --   实际大小。

返回值:如果成功则返回0

pOutBuffer里返回的数据结构如下:
typedef   struct   _SYSTEM_HANDLE_STATE   {
DWORD   r1;
DWORD   GrantedAccess;
DWORD   HandleCount;   //   减1为句柄计数
DWORD   ReferenceCount;   //   减1为指针引用计数
DWORD   r5;
DWORD   r6;
DWORD   r7;
DWORD   r8;
DWORD   r9;
DWORD   r10;  
DWORD   r11;  
DWORD   r12;  
DWORD   r13;  
DWORD   r14;  
}SYSTEM_HANDLE_STATE,   *PSYSTEM_HANDLE_STATE;

你可能感兴趣的:(C/C++)