首页
论坛
课程
招聘
[原创]Windows Xp句柄表结构 笔记
2009-10-30 13:58 15310

[原创]Windows Xp句柄表结构 笔记

2009-10-30 13:58
15310
Windows Xp句柄表结构
学习了一下Windows XP的句柄表结构,和windows internal中描述的win2000结构还是有很大不同的。
简单记录一下。

1. winXP的句柄还是三层结构,每一层的大小为PAGE_SIZE。对于X86系统就是4KB。
   并且每一层的最后一个元素用作统计。
   因此,第2、1层可以存储4KB/4 - 1 = 1023项地址。
   第0层可以存储4KB / 8 - 1 = 511项。

2. 句柄信息储存在第0层,每一项8字节。
结构如下
lkd> dt _HANDLE_TABLE_ENTRY 
nt!_HANDLE_TABLE_ENTRY 
+0x000 Object : Ptr32 Void 
+0x000 ObAttributes : Uint4B 
+0x000 InfoTable : Ptr32 _HANDLE_TABLE_ENTRY_INFO 
+0x000 Value : Uint4B 
+0x004 GrantedAccess : Uint4B 
+0x004 GrantedAccessIndex : Uint2B 
+0x006 CreatorBackTraceIndex : Uint2B 
+0x004 NextFreeTableEntry : Int4B 
其中第1个成员需要说明:windows能保证对象头的分配地址总是8的倍数,所以这32位的对象头的指针低3位肯定都为0,windows将这低3位用作其他用途;因为内核对象分配都在0x80000000以上,所以最高位必须为1,window把这位当作锁位。因此,其实把最低3位置0,最高位置1才是真正指向对象头部。(这句话不是我说的。。。忘了出自哪篇文章了,作者看到不要怪罪)

3. 对于X86系统,句柄意义如下


4. 句柄表的寻找
kd> dt _EPROCESS 81c458f0 
ntdll!_EPROCESS
......
   +0x0bc DebugPort        : (null) 
   +0x0c0 ExceptionPort    : (null) 
[COLOR="Red"]   +0x0c4 ObjectTable      : 0xe1500820 _HANDLE_TABLE[/COLOR]
......

kd> dt _HANDLE_TABLE 0xe1500820
ntdll!_HANDLE_TABLE
[COLOR="Red"]   +0x000 TableCode        : 0xe1739000[/COLOR]
   +0x004 QuotaProcess     : 0x81c458f0 _EPROCESS
   +0x008 UniqueProcessId : 0x00000298 
   +0x00c HandleTableLock : [4] _EX_PUSH_LOCK
   +0x01c HandleTableList : _LIST_ENTRY [ 0xe14f0874 - 0xe147842c ]
   +0x024 HandleContentionEvent : _EX_PUSH_LOCK
   +0x028 DebugInfo        : (null) 
   +0x02c ExtraInfoPages   : 0
   +0x030 FirstFree        : 0x4dc
   +0x034 LastFree         : 0
   +0x038 NextHandleNeedingPool : 0x800
   +0x03c HandleCount      : 443
   +0x040 Flags            : 0
   +0x040 StrictFIFO       : 0y0


TableCode是句柄表的地址,由于句柄表肯定是以2字节对齐的,所以winXP中TableCode后两位指出它指向的是哪一层。
真正的句柄表地址为 TableCode & 0xFFFFFFFC, 它指向第TableCode & 0x00000003层

4. 小测试
kd> !process 0 0 csrss.exe
[COLOR="red"]PROCESS 81c458f0[/COLOR] SessionId: 0 [COLOR="red"]Cid: 0298[/COLOR]    Peb: 7ffd3000 ParentCid: 01ac
    DirBase: 09d40040 ObjectTable: e1500820 HandleCount: 443.
    Image: csrss.exe


我们以074C号句柄为例查看
kd> !handle 0 7 298
processor number 0, process 00000298
Searching for Process with Cid == 298
PROCESS 81c458f0 SessionId: 0 Cid: 0298    Peb: 7ffd3000 ParentCid: 01ac
    DirBase: 09d40040 ObjectTable: e1500820 HandleCount: 443.
    Image: csrss.exe
........
[COLOR="red"]074c: Object: 81db0b30[/COLOR] GrantedAccess: 001f03ff Entry: e1739e98
Object: 81db0b30 Type: (821b9ca0) Thread
    ObjectHeader: 81db0b18 (old version)
        HandleCount: 2 PointerCount: 3
      ........


获得句柄表位置
kd> dt _EPROCESS 81c458f0 
ntdll!_EPROCESS
......
   +0x0bc DebugPort        : (null) 
   +0x0c0 ExceptionPort    : (null) 
[COLOR="red"]   +0x0c4 ObjectTable      : 0xe1500820 _HANDLE_TABLE[/COLOR]
......

kd> dt _HANDLE_TABLE 0xe1500820
ntdll!_HANDLE_TABLE
[COLOR="red"]   +0x000 TableCode        : 0xe1739000[/COLOR]
   +0x004 QuotaProcess     : 0x81c458f0 _EPROCESS
   +0x008 UniqueProcessId : 0x00000298 
   +0x00c HandleTableLock : [4] _EX_PUSH_LOCK
   +0x01c HandleTableList : _LIST_ENTRY [ 0xe14f0874 - 0xe147842c ]
   +0x024 HandleContentionEvent : _EX_PUSH_LOCK
   +0x028 DebugInfo        : (null) 
   +0x02c ExtraInfoPages   : 0
   +0x030 FirstFree        : 0x4dc
   +0x034 LastFree         : 0
   +0x038 NextHandleNeedingPool : 0x800
   +0x03c HandleCount      : 443
   +0x040 Flags            : 0
   +0x040 StrictFIFO       : 0y0


0xe1739000&0xFFFFFFFC = 0xe1739000(句柄表指针)
0xe1739000&0x00000003 = 0x00(第0层句柄表)

刚才的句柄是 0x074C >>2 == 00000111010011
所以2级表和1级表索引均为0
0级表索引为 111010011b = 0x01d3 (只有一级)

kd> dd (e1739000 + 1d3 * 8)
e1739e98 [COLOR="red"]81db0b19 [/COLOR]001f03ff 00000000 00000754
e1739ea8 00000000 00000758 00000000 0000075c
e1739eb8 00000000 00000760 00000000 00000764
e1739ec8 00000000 00000768 00000000 0000076c
e1739ed8 00000000 00000770 00000000 00000774
e1739ee8 00000000 00000778 00000000 0000077c
e1739ef8 00000000 00000780 00000000 00000784
e1739f08 00000000 00000788 00000000 0000078c


0x81db0b19 & 0xFFFFFFF8 | 0x80000000 = 0x81db0b18 (真正的头地址)

查看对象头
kd> dt _OBJECT_HEADER 0x81db0b18


对象体 = 对象头 + 0x18
kd> !object 0x81db0b18 + 0x18
Object: 81db0b30 Type: (821b9ca0) Thread
    ObjectHeader: 81db0b18 (old version)
    HandleCount: 2 PointerCount: 3


欢迎指正、拍砖
http://hi.baidu.com/index09

【看雪培训】《Adroid高级研修班》2022年夏季班招生中!

上传的附件:
收藏
点赞0
打赏
分享
最新回复 (16)
雪    币: 32
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
jordanpz 活跃值 2009-10-30 14:56
2
0
此帖必火 ,赶紧坐个沙发
雪    币: 200
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
hahaaj 活跃值 2009-10-30 17:00
3
0
冒个泡,占个座
雪    币: 291
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
leking 活跃值 2009-10-30 17:05
4
0
强帖必顶!!
雪    币: 209
活跃值: 活跃值 (19)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Jeller 活跃值 2009-11-1 14:04
5
0
所有的系统结构尽管去ReactOS源代码里找好了。
雪    币: 202
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
litandy 活跃值 2009-11-5 13:10
6
0
学习了,站个位.
雪    币: 3
活跃值: 活跃值 (205)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
bboyiori 活跃值 1 2010-5-17 22:37
7
0
补充一点句柄表项结构:
kd> dt _HANDLE_TABLE_ENTRY
nt!_HANDLE_TABLE_ENTRY
   +0x000 Object           : Ptr32 Void
   +0x000 ObAttributes     : Uint4B
   +0x000 InfoTable        : Ptr32 _HANDLE_TABLE_ENTRY_INFO
   +0x000 Value            : Uint4B
   +0x004 GrantedAccess    : Uint4B
   +0x004 GrantedAccessIndex : Uint2B
   +0x006 CreatorBackTraceIndex : Uint2B
   +0x004 NextFreeTableEntry : Int4B

typedef struct _HANDLE_TABLE_ENTRY {

    //
    //  The pointer to the object overloaded with three ob attributes bits in
    //  the lower order and the high bit to denote locked or unlocked entries
    //

    union {

        PVOID Object;

        ULONG ObAttributes;

        PHANDLE_TABLE_ENTRY_INFO InfoTable;

        ULONG_PTR Value;
    };

    //
    //  This field either contains the granted access mask for the handle or an
    //  ob variation that also stores the same information.  Or in the case of
    //  a free entry the field stores the index for the next free entry in the
    //  free list.  This is like a FAT chain, and is used instead of pointers
    //  to make table duplication easier, because the entries can just be
    //  copied without needing to modify pointers.
    //

    union {

        union {

            ACCESS_MASK GrantedAccess;

            struct {

                USHORT GrantedAccessIndex;
                USHORT CreatorBackTraceIndex;
            };
        };

        LONG NextFreeTableEntry;
    };

} HANDLE_TABLE_ENTRY, *PHANDLE_TABLE_ENTRY;
雪    币: 226
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wanarenese 活跃值 2010-5-24 11:31
8
0
感谢您的分享。

一开始看不太懂,现在懂了,补充一下自己的理解笔记于下

==

今天如果我们有一个 HANDLE hd1 = 0x074C;

想要解读他,去读出他真正的内容,最终都是要找到 hd1 所对应的 Handle Table,然后查表。这个 Handle Table 假设叫 arrHTE,则其资料型态为 HANDLE_TABLE_ENTRY arrHTE[511];

对任一个 Process 来说,这种 Handle Table 至少有一个,最多可以有 1023 * 1023 个。

[已知] 某个 Process 的 EPROCESS.ObjectTable 内记录的位址,只是用来找出 TableCode。

[已知] 如果告诉你 Handle Table 只有一层,那代表 Handle Table 的数目只有一个;有两层时,其数目有 1023 个;当然有三层时,其数目就是之前说的 1023*1023 个。

[已知] 最多有三层 Handle Table,从 TableCode 的 bit31~bit2 可取出一个位址,姑且叫他为 HADDR,其资料型态要视情况而定。

==

如果只有一个 Handle Table,我们说:
只有一层句柄表、只有一个第零层句柄表、只有最底层句柄表。

此时 HADDR 必然等于 arrHTE。

从 hd1 的 bit2~bit10 这 9 个位元去读出索引值 0x1D3 = 467; 则由 arrHTE[467] 取出的 HANDLE_TABLE_ENTRY 结构,就能找到 hd1 的真正内容。

==

如果有两层句柄表,那其实是说 Handle Tables 的数量,总共有 1023 个,也就是可以找到 1023 个 arrHTE 这种表。

此时 HADDR 的资料型态为:L1HT [1023];
其中 L1HT 的资料型态又为:
typedef HANDLE_TABLE_ENTRY (*)[511] L1HT;

换言之,假设 hd1 的 bit11~bit20 这 10 个位元去读出索引值,假设是3,则 *(HADDR+3) 得到的位址就是 1023 个 Handle Table 中,真正记载 hd1 资料的那个 arrHTE 所在处。

同理,当有第三层索引时,HADDR 的资料型态为:
L2HT [1023];
其中 L2HT 的资料型态为:
typedef L1HT (*)[1023];

参考:
http://www.phate.tw/viewthread.php?tid=8584
雪    币: 36
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
秋实 活跃值 2010-5-24 14:12
9
0
学习了,过来看看又有新的收获,谢谢楼主!
雪    币: 1192
活跃值: 活跃值 (469)
能力值: ( LV8,RANK:150 )
在线值:
发帖
回帖
粉丝
freakish 活跃值 1 2010-12-31 13:54
10
0
我的问题 还是删了吧,太白了
雪    币: 1192
活跃值: 活跃值 (469)
能力值: ( LV8,RANK:150 )
在线值:
发帖
回帖
粉丝
freakish 活跃值 1 2010-12-31 14:01
11
0
。。。。。。
雪    币: 412
活跃值: 活跃值 (13)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Mike1234567890 活跃值 2010-12-31 16:37
12
0
这个现在还看不懂
用到了再回来找吧
雪    币: 197
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
licyong 活跃值 2010-12-31 16:48
13
0
好安逸的资料!!!谢谢楼主啊!
雪    币: 262
活跃值: 活跃值 (16)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
yunfeng 活跃值 1 2011-1-1 09:48
14
0
新年第一贴,新年快乐!!!!
雪    币: 39
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
dahaione 活跃值 2011-1-1 22:10
15
0
mark
雪    币: 232
活跃值: 活跃值 (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
dlmu 活跃值 1 2011-1-1 22:25
16
0
句柄貌似很重要
雪    币: 232
活跃值: 活跃值 (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
dlmu 活跃值 1 2011-1-4 12:00
17
0
学习句柄~~~必看
游客
登录 | 注册 方可回帖
返回