首页
社区
课程
招聘
[旧帖] [原创]从句柄表中获取的对象头地址竟然不是真实对象头地址 0.00雪花
发表于: 2009-8-19 03:29 1230

[旧帖] [原创]从句柄表中获取的对象头地址竟然不是真实对象头地址 0.00雪花

2009-8-19 03:29
1230
小弟最近在windbg调试,在网上看到了篇用windbg来获取进程句柄表,从而来得到进程对象地址的一篇文章《windbg学习笔记 FOR 内核调试(三) --进程句柄表HANDLE_TABLE 》
作者首先用!handle,!object等命令来直接获取一个对象信息。然后再通过获取句柄表的方法间接获取一个对象信息,从而做出比较。但作者也在调试的过程中发现了个问题,就是在句柄表中获取的对象头地址比用!handle命令获取的对象头地址少1。我于是做了个同样的实验:
首先同作者一样,我也以ctfmon这个进程为实验对象:!handle 0 2 708
同样以句柄值为114的对象为例,下面是这个句柄的信息:
                    ........
                              .......
  0114: Object: 81f56cb8  GrantedAccess: 001f0003 Entry: e1c45228
   Object: 81f56cb8  Type: (825b6270) Event
   ObjectHeader: 81f56ca0 (old version)
                            .........
                            .........
下面我就找句柄表了,刚才使用!handle命令显示这个进程结构体的基址为81f28950.那么使用
dt _eprocess 81f28950命令观察这个结构体,在里面找到ObjectTable这项的值:
ObjectTable      : 0xe1835ca8 _HANDLE_TABLE
接下来使用dt _handle_table 0xe1835ca8命令观察此进程的_handle_table结构体:
0: kd> dt _handle_table 0xe1835ca8 
nt!_HANDLE_TABLE
   +0x000 TableCode        : 0xe1c45000
   +0x004 QuotaProcess     : 0x81f28950 _EPROCESS
   +0x008 UniqueProcessId  : 0x00000708 
   +0x00c HandleTableLock  : [4] _EX_PUSH_LOCK
   +0x01c HandleTableList  : _LIST_ENTRY [ 0xe13e8954 - 0xe14d3754 ]
   +0x024 HandleContentionEvent : _EX_PUSH_LOCK
   +0x028 DebugInfo        : (null) 
   +0x02c ExtraInfoPages   : 0
   +0x030 FirstFree        : 0x1ac
   +0x034 LastFree         : 0
   +0x038 NextHandleNeedingPool : 0x800
   +0x03c HandleCount      : 118
   +0x040 Flags            : 0
   +0x040 StrictFIFO       : 0y0
看到第一项TableCode的值了,由于后两位是00,所以这个句柄表只有一层,那么可以计算出句柄值为114的句柄所对应的对象头的地址所在位置0xe1c45000+114*2(这个计算出来的值可不是对象头的地址,它里面记录的值才是对象头的地址,我开始学句柄表时候也容易搞混),我们可以用dd 0xe1c45000+114*2命令:
e1c45228  81f56ca1 001f0003 81f56c71 001f0003
e1c45238  81f56c41 001f0003 82078d91 001f03ff
e1c45248  820881c1 001f0003 81f56bf9 001f0003
e1c45258  820881c1 001f0003 820881c1 001f0003
e1c45268  820881c1 001f0003 81f220c9 001f0001
e1c45278  81f6c931 001f0003 81f48ab1 001f0001
e1c45288  e188fd73 00000006 81f1f569 001f0001
e1c45298  e1a320e3 00000006 820810d9 001f0001
。。。
。。。
第一个值为81f56ca1。而上面用!handle命令得到的对象头地址为81f56ca0,也就是1的差距。这和原作者的实验结果完全一样。为什么会这样呢:
我想了很久,想到内存对象头地址是以32字节对齐的,所以说这个地址的后两位应该改为0,这样两个结果就一样了。而至于为什么系统不把这个值直接设置成对象头指针,这大概是应为对象头最后两位必定是0,那么可以在句柄表中把这一位当做特殊的标志位,来记录别的信息(纯属个人猜测)。

[课程]FART 脱壳王!加量不加价!FART作者讲授!

收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 522
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
是的 最初也奇怪了半天
驱动直接读是正常的  拿windbg dd对象地址会多出1来  哈哈
2009-8-19 04:59
0
雪    币: 251
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
#define EXHANDLE_TABLE_ENTRY_LOCK_BIT    1
用于同步对HANDLE_TABLE_ENTRY的读写,为1表明 handle 没有被锁住,为0表明已上锁
参看wrk的Ex/Handle.c
2009-8-19 08:53
0
雪    币: 27
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
谢谢了,能再讲解得详细点吗
2009-8-19 15:54
0
游客
登录 | 注册 方可回帖
返回
//