Windows句柄表格式(1) – 2000句柄表格式
科大的牛人,出手就是不同凡响。不过居然工作后做Web方面的开发,也算是有才了。饭碗和爱好还是不能兼得的。by lonkil
发信人: ftofficer(0210|别了,科大), 信区: Kernel
标 题: Windows句柄表格式(1) – 2000句柄表格式
发信站: 瀚海星云 (2006年11月26日01:50:44 星期天), 站内信件
版大暗示我需要交一篇原创了。工作以后天天搞一些Web上面的开发,很久没有研究内核
了。翻翻以前自己的手记,拼凑了一篇,简单写些Windows当中的句柄表格式好了。
今天比较晚了,先写2000下面的,明天再整理一个XP的好了。两者之间差异巨大,几乎
是完全重写的。
句柄表是Windows Object Manager维护的一个进程范围有效的表,用来管理Windows的内
核对象。关于Object Manager和句柄表的基础可以参见《Windows Internal》,讲的很
清楚。但是一旦涉及到了句柄表的实际格式,《Windows Internal》就讳莫如深了,对
于2000的句柄表还说了一些,但是对于XP/2003就基本上没有说什么了。
我们对句柄表的探索是从EPROCESS开始的,EPROCESS结构当中有一个指向_HANDLE_TABLE
结构的指针,名字叫做 ObjectTable,2000在0×128处,XP在0xC4处。这个结构在2000和
XP当中是完全不同的。2000当中定义很简单:
kd> dt nt!_handle_table
nt!_HANDLE_TABLE
+0×000 Flags : Uint4B
+0×004 HandleCount : Int4B
+0×008 Table : Ptr32 Ptr32 Ptr32 _HANDLE_TABLE_ENTRY
+0x00c QuotaProcess : Ptr32 _EPROCESS
+0×010 UniqueProcessId : Ptr32 Void
+0×014 FirstFreeTableEntry : Int4B
+0×018 NextIndexNeedingPool : Int4B
+0x01c HandleTableLock : _ERESOURCE
+0×054 HandleTableList : _LIST_ENTRY
+0x05c HandleContentionEvent : _KEVENT
真正指向Handle table entry的就是那个Table指针了,这是一个类型为_HANDLE_TABLE_
ENTRY***的东西,所以从2000的句柄表当中查东西出来就是分三次查表就好了。在WI当
中也有讲,Windows 2000将句柄值除以4之后,把结果的后24位当作三个8位索引来看待
,每个都是在对应级别的索引表当中的索引,前两个是Ptr表,最后一级是
_HANDLE_TABLE_ENTRY表。(这一点Windows Internal说的不清楚,容易让人认为说不用
除以4)。
举个例子来说吧。随便找个handle比较多的进程,就拿Winlogon好了。
kd> !handle 0628 7 b8
processor number 0
Searching for Process with Cid == b8
PROCESS fd779820 SessionId: 0 Cid: 00b8 Peb: 7ffdf000 ParentCid: 008c
DirBase: 035bf000 ObjectTable: fd7806a8 TableSize: 372.
Image: WINLOGON.EXE
Handle Table at e1cc9000 with 372 Entries in use
0628: Object: fd670488 GrantedAccess: 0012019f
Object: fd670488 Type: (fd90b840) File
ObjectHeader: fd670470
HandleCount: 1 PointerCount: 1
Directory Object: 00000000 Name: \SfcApi {NamedPipe}
记着这个Handle 0×0628。下面我们手动来查查看。先看这个Handle的值,除以4之后是0
x18A,低三个字节分别代表三个索引:0×00,0×01,0x8A。下面从进程的EPROCESS开始
:
kd> dt nt!_eprocess fd779820
nt!_EPROCESS
+0×000 Pcb : _KPROCESS
…
+0×128 ObjectTable : 0xfd7806a8 _HANDLE_TABLE
kd> dt nt!_handle_table 0xfd7806a8
nt!_HANDLE_TABLE
+0×000 Flags : 0
+0×004 HandleCount : 372
+0×008 Table : 0xe1cc9000 -> 0xe1cc9400 -> 0xe1cc9800
_HANDLE_TABLE_ENTRY
…
第一级索引表在e1cc9000,索引为0,故:
kd> dd 0xe1cc9000
e1cc9000 e1cc9400 00000000 00000000 00000000
…
故第二级索引表在e1cc9400,索引为0×01,注意每个索引项为4字节:
kd> dd e1cc9400+0×01*4
e1cc9404 e1eb3000 e1eb3800 00000000 00000000
…
故sub handle table地址为e1eb3000,索引为0x8A,注意这时候表中存储的已经是_HAND
LE_TABLE_ENTRY了,故而每个大小为8字节:
kd> dd e1eb3000+0x8A*8
e1eb3450 7d670470 0012019f 7d6701e8 001f03ff
…
可见该对象的_OBJECT_HEADER结构位置在(7d670470 & FFFFFFF8) | 80000000 =
Fd670470,_OBJECT_HEADER当中的结构是0×18字节,之后就是各种对象的data了。所以
对象所在的位置就是fd670488
kd> !object Fd670488
Object: fd670488 Type: (fd90b840) File
ObjectHeader: fd670470
HandleCount: 1 PointerCount: 1
Directory Object: 00000000 Name: \SfcApi {NamedPipe}
这正与2000的句柄表格式相符。
–
Doing a little bit at a time, and an oyster makes a pearl.
※ 来源:·瀚海星云 bbs.ustc.edu.cn·[FROM: 222.95.168.191]