全局句柄表

1.全局句柄表

句柄介绍

句柄一共有3种

  1. 全局句柄表 进程 线程 句柄表
  2. 私有句柄表 进程私有的
  3. 窗口句柄

全局句柄表

在全局句柄表种只有进程线程对象

OpenProcess/OpenThread 权限 是否继承和 id

获取创建进程的handle的流程:

获取到进程id 取全局句柄表种找到进程对象,把进程对象插到进程的私有句柄表中,从而返回一个索引号,返回3环,这就是三环获得的句柄

无论是线程id还是进程id都是全局句柄表的索引号

在windows只有进程和线程有id,其他的只有对象名字

当全局句柄表地址后面是0,那么代表的是句柄表,3096一个页的大小,每一项8个字节,也就是一个id索引号就是8字节,当空间耗尽后,会把表里面的数据移到一个新的申请的内存,将原来的表清空,这时候全局句柄表地址后面是1,4个字节1项,再满了后就存放到新的开辟的内存中

句柄表地址后面的0,1,2代表层级

地址分成两部分,高字节存放属性低字节存放地址和几个小属性

举例

拿DebugView举例,进程pid是2792

在ida中可以看到名字是PspCidtable交叉引用查看一下,注意这个函数不是导出函数

可以看到都是和线程和进程有关的

可以看到PsLookupProcessByProcessId函数在这个位置使用了这个函数,俺么就可以通过这个函数定位到这个PspCidtable函数的运行地址

也就是说我们要获取到这个地址就是PspCidtable函数的地址

windbg中dd一下就可以看到全局句柄表

DT一下就可以看到对应的结构

kd> dt _HANDLE_TABLE 8d2010a0 
ntdll!_HANDLE_TABLE
   +0x000 TableCode        : 0xa7982001//这个尾数代表有几层0是1层,1是2层
   +0x004 QuotaProcess     : (null) 
   +0x008 UniqueProcessId  : (null) 
   +0x00c HandleLock       : _EX_PUSH_LOCK
   +0x010 HandleTableList  : _LIST_ENTRY [ 0x8d2010b0 - 0x8d2010b0 ]
   +0x018 HandleContentionEvent : _EX_PUSH_LOCK
   +0x01c DebugInfo        : (null) 
   +0x020 ExtraInfoPages   : 0n0
   +0x024 Flags            : 1
   +0x024 StrictFIFO       : 0y1
   +0x028 FirstFreeHandle  : 0xf48
   +0x02c LastFreeHandleEntry : 0xa7980d40 _HANDLE_TABLE_ENTRY
   +0x030 HandleCount      : 0x1ed
   +0x034 NextHandleNeedingPool : 0x1000
   +0x038 HandleCountHighWatermark : 0x29b

dd一下查看一下哦表中的值(注意把TableCode尾数改成0)

kd> dd 0xa7982000
a7982000  8d205000 a7980000 00000000 00000000
a7982010  00000000 00000000 00000000 00000000
a7982020  00000000 00000000 00000000 00000000
a7982030  00000000 00000000 00000000 00000000
a7982040  00000000 00000000 00000000 00000000
a7982050  00000000 00000000 00000000 00000000
a7982060  00000000 00000000 00000000 00000000
a7982070  00000000 00000000 00000000 00000000

这里每一项代表了一张表

这里我们DebugView的pid是2792需要除以4,因为步长是4,也就是698(注意是10进制)

每一张表中有512个元素

所以用之前获得的698除以512可以知道在哪张表,这里就在第1张表,也就是编号为0

也就是上图中的那张表

之后再拿698取模余512(就是%),也就是186取出表中的索引号

接下来用windbg查看

但是因为windbg自动是16进制的,所以我们上面取到的索引号要转成16进制,也就是BA,最后还要*8(因为8字节)才可以获取到句柄表中的地址

kd> DQ 8d205000+BA*8
8d2055d0  00000000`88d736b9 00000000`88aae751
8d2055e0  00000000`88aa3a81 00000000`88aaf541
8d2055f0  00000000`88aa51f1 00000f64`00000000
8d205600  00000000`88aadd21 00000000`88ac7d49
8d205610  00000000`88ab8a59 00000000`88ac3591
8d205620  00000000`88102341 00000000`88ac9031
8d205630  000007a4`00000000 00000000`881029d9
8d205640  00000000`88aca2a9 00000000`88ace639

可以发现有些地址尾号仍然有一个1这个1是一把

posted @ 2024-05-18 17:25  MuRKuo  阅读(33)  评论(0编辑  收藏  举报