ExpLookupHandleTableEntry

wrk1.2中
ExpLookupHandleTableEntry的内部流程
1) 取 Handle(EXHANDLE类型) 值为tHandle,并将TagBit(低两位)置0
2) 取 HandleTable->NextHandleNeedingPool为MaxHandle ,
   如果 tHandle大于等于MaxHandle,则返回NULL,查询失败
   (由此可见, NextHandleNeedingPool 应该是当前句柄表的最大句柄值+1
    或者说是下一个可用的句柄值)
3) 取 CapturedTable(ULONG_PTR类型)为HandleTable->TableCode
   取 TableLevel(ULONG)为(CapturedTable & LEVEL_CODE_MASK);
      (LEVEL_CODE_MASK=3,即由HandleTable->TableCode的低2位来指定句柄表的级数)
   CapturedTable 减去 TableLevel (即CapturedTable的低2位置0)
4) 根据 TableLevel 来进行不同方式的查找 

    令:
    PCHAR TableLevel1; 最低层的表指针
    PCHAR TableLevel2; 中间层的表指针
    PCHAR TableLevel3; 最上层的表指针
    ULONG_PTR i; 最低层的表索引
    ULONG_PTR j; 中间层的表索引
    ULONG_PTR k; 最上层的表索引
    PHANDLE_TABLE_ENTRY Entry 最后找到的句柄项目的指针

a) TableLeve = 0    句柄表只有1级,此时CapturedTable只是一个大小为512(4K/8=512)
     的HANDLE_TABLE_ENTRY数组,Handle的高30位即是索引.
     (当然,实际上因为一级表为512项,所以其实只有2~10 9位为有效索引,其中11~31位在
     第二步中被检查过,必为0).

     由于每个HANDLE_TABLE_ENTRY大小为8,所以对应的Entry相对于表起始地址的偏移
     为 Handle.Value>>2 * 8
  TableLevel1 = CapturedTable;
        Entry = TableLevel1 + (Handle.Value>>2) * 8
              = TableLevel1 + Handle.Index * 8
              = TableLevel1 + Handle.Value * 2 (因为第1步中已经将低2位置0了)

    wrk 1.2中代码如下

      Entry = (PHANDLE_TABLE_ENTRY) &TableLevel1[Handle.Value *
                               (sizeof (HANDLE_TABLE_ENTRY) / HANDLE_VALUE_INC)];

      其中HANDLE_VALUE_INC在EXHANDLE结构中定义,值是4

b) TableLeve = 1   句柄表有2级,
     第1层存储的是第2层表的指针(大小为4字节).
     第2层存储的是HANDLE_TABLE_ENTRY(大小为8个字节)
     
     句柄的2~10位为最底层表(第2层)的索引,11~N位为中间层表(第1层)索引
     (注:N的值从3层句柄表的情况看,应该为)

     wrk 1.2中的代码及分析如下
     +++++++++++++++++++++++++++++++++++++++++++++++
     i = Handle.Value % (LOWLEVEL_COUNT * HANDLE_VALUE_INC);
       /* 
       = Handle.Value % 0x800
       = Handle & 0x7FF 
       等效作用是取低11位 
       */

     Handle.Value -= i; 低11位置0

     j = Handle.Value / ((LOWLEVEL_COUNT * HANDLE_VALUE_INC) / sizeof (PHANDLE_TABLE_ENTRY));
       /* 
       = Handle.Value / (0x800 / 4)
       = (Handle.Value >> 11) * 4
       等效如下代码,实际上是取11~N为位为索引,并乘以4,得到中间表的表中偏移
       */

     TableLevel2 = (PUCHAR) CapturedTable;
     TableLevel1 =  *(PUCHAR)(TableLevel2 + j);
     Entry = TableLevel1+ (i * (sizeof (HANDLE_TABLE_ENTRY) / HANDLE_VALUE_INC));
           /*
           = TableLevel1+ (i*2)
           = TableLevel1+ ((i>>4) * 8)
           等效于最低层表索引(2~10位)乘以sizeof(HANDLE_TABLE_ENTRY),得到表中偏移.
           */
     ------------------------------------------------


c) TableLeve = 2  句柄表有3层 
     第1层存储的是第2层表的指针(大小为4字节).
     第2层存储的是第3层表的指针(大小为4字节).
     第3层存储的是HANDLE_TABLE_ENTRY(大小为8个字节)

     句柄的2~10位为最底层表(第3层)的索引,11~20位为中间层表(第2层)索引,
     20~N位为第一层索引(因为第1层最有4K/4个元素,索引应该也为10位,故推测
     N实际上应该为30)
     
     wrk 1.2中的代码及分析如下
     +++++++++++++++++++++++++++++++++++++++++++++++
     i = Handle.Value  % (LOWLEVEL_COUNT * HANDLE_VALUE_INC);

     Handle.Value -= i; 低11位清0

     k = Handle.Value / ((LOWLEVEL_COUNT * HANDLE_VALUE_INC) / sizeof (PHANDLE_TABLE_ENTRY));
       /*
       = Handle.Value / (0x800 / 4)
       = (Handle.Value >> 11) * 4 
       k取句柄的11~N为位,并乘以4
       */

     j = k % (MIDLEVEL_COUNT * sizeof (PHANDLE_TABLE_ENTRY));
       /*
       = k % (4K/4 * 4)
       = k % 0x1000
       = k & 0xFFF
       取k的低12位,实际上就是:句柄的11~20位为索引 * 4
       */

     k -= j; k的低12位清0

     k /= MIDLEVEL_COUNT;
       /*
       = k / (4k/4)
       = k / 0x1000
       = k >> 10
       取k的高10~N位,实际上就是句柄的21~N位为索引再乘以4
       */

     TableLevel3 = (PUCHAR) CapturedTable;
     TableLevel2 = (PUCHAR) *(PHANDLE_TABLE_ENTRY *) &TableLevel3[k];
     TableLevel1 = (PUCHAR) *(PHANDLE_TABLE_ENTRY *) &TableLevel2[j];
     Entry = (PHANDLE_TABLE_ENTRY) &TableLevel1[i * (sizeof (HANDLE_TABLE_ENTRY) / HANDLE_VALUE_INC)];

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值