}
/*NextHandleNeedingPool是HANDLE_TABLE的数据成员,表示本句柄表句柄的最大值(即
最多保存的句柄项),由于要我们这里遍历句柄表,所以当传入的句柄值大于
NextHandleNeedingPool的时候,返回0,表示遍历结束*/
if((ULONG)handle>=handletable->NextHandleNeedingPool)
{
return 0;
}
/*获得句柄表的地址,和级别*/
tablebase=*(PULONG) &handletable->TableCode;
DbgPrint("handle_table address is %X\n",tablebase);
leave=tablebase & 3;
tablebase=tablebase-leave;
switch(leave)
{
/*一级表的索引*/
case 0:
{
entry=(PHANDLE_TABLE_ENTRY)((ULONG)tablebase+(ULONG)handle/4*8);
break;
}
case 1:
{
/*二级表的索引,先得到一级表的地址,在得到handle_table_entry*/
i=*(PULONG)((ULONG)tablebase+(ULONG)((ULONG)handle>>11 &
0x3ff)*4);
entry=(PHANDLE_TABLE_ENTRY)(i+((ULONG)handle>>2 & 0x1ff)*8);
break;
}
case 3:
{
/*三级表的索引:先得到二级表的地址,再得到一级表的地址,最后得到
handle_table_entry*/
j=*(PULONG)((ULONG)tablebase+((ULONG)handle>>21 & 0x1ff )*4);
i=*(PULONG)(i+((ULONG)handle>>11 & 0x3ff)*4);
entry=(PHANDLE_TABLE_ENTRY)(i+((ULONG)handle>>2 & 0x1ff)*8);
break;
}
default:
{
break;
}
}
return entry;
[/code]
现在得到了PHANDLE_TABLE_ENTRY,让我们来看看HANDLE_TABLE_ENTRY的结构。

我们关心的是Object数据成员,这个数据的低三位表示该对象的一些性质,如继承性等等。
低三位置0后指向OBJECT_HEADER结构。任何内核对象的数据结构都有两个不可缺少的部分,
即 OBJECT_HEADER和具体对象的数据结构。例如文件对象,则是object_header数据结构和
file_object数据结构组成。
其中object_header在 file_object的前面。
内存中如图:

其中的 object_header_xxxx_info则是该对象的一些附件信息。
我们来看看object_header结构:

在看看 object_type结构,在后面会用到:

现在,我们来输出对象的一些重要信息。所欲的对象,我们关心 PointerCount 和
HandleCount 和对象的类型。PointerrCount 和 HandleCount 很简单就可以得到,但是对于
对象的类型,我们要从Type指向的object_type 结构中得到,该结构中有个unicode_string
结构,保存对象类型的名字,如File,Reg,Thread,Event等等。对于有些有名字的对象,
我们还要输出的它的名字和 Directory 目录,这些信息保存在 object_header_name_info
结构中,在 object_header 中的 NameInfoOffset 是一个 UCHAR 类型的数据,表示
object_header_name_info相对于 object_header结构的偏移。而对于File和 Reg的对象,
我们还要输出的它的绝对路径,对于获得绝对路径,object_type 结构中有个
object_type_initializer结构。
我们来看看object_type_initializer结构:

其中的 QueryNameProcedure数据成员,指向一个函数,提供路径解析功能,对于File 对象,
找个函数是:IopQueryName:对于Reg对象,找个函数是 CmpQueryKeyName,都是未导出的
函数。好歹,我们在WRK中可以找到他们的声明,这样我们就可以调用了。而且这两个函数
的调用参数都一样
NTSTATUS
NTAPI
(IopQueryName(
IN PVOID Object,
IN BOOLEAN HasObjectName,
OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
IN ULONG Length,
OUT PULONG ReturnLength,
IN KPROCESSOR_MODE Mode
);
由于 Pipe 对象也被定义为 File 对象,而在调用路径解析函数的时候,如果是 Pipe 对象, |