ExpLookupHandleTableEntry
2011-04-18 17:09
1001 查看
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)];
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)];
相关文章推荐
- pid的后2位是无效的 在查询pspcidtable的时候 ExpLookupHandleTableEntry 函数会自动把pid的后两位置成0(Handle.TagBits = 0;就是这句!!)
- Map.Entry 类使用简介
- OBJECT_ENTRY_AUTO
- 【收藏】本周ASP.NET英文技术文章推荐[01/27 - 02/02]:负载均衡、State Server、Web Deployment、Data Entry Suite、GridView、Access、SQL Server、MSDE
- DbEntry.net使用时出现System.Data.SqlTypes.SqlNullValueException解决办法
- Missing classpath entry ..../server/default/lib/mail.jar(类似问题同解)
- WPF error: does not contain a static 'Main' method suitable for an entry point
- __rt_entry, __rt_exit(), __rt_lib_init(), __rt_lib_shutdown(), --strict, --no_strict
- 设置GtkEntry的背景颜色
- build path entry is missing
- Entity Framework 学习初级篇2--ObjectContext、ObjectQuery、ObjectStateEntry、ObjectStateManager类的介绍
- list_entry
- glib命令行解析库简单使用--GOptionEntry 命令行参数
- J2ME 打包出错:Illegal Manifest Entry Key or Value "MIDlet-Version"
- No manual entry for fork
- tortoisesvn 出现异常Bogus date :Error at entry 870 in entries file for ' '的解决方案
- GRUB2 General menuentry Construction Rules(from ubuntu docs)
- 如何在窗口程序中使用控制台(/subsystem /entry)
- 内核双向链表list.h中的list_entry
- Could not create JarEntryRevision