-
-
[原创]Windows句柄表分配算法分析 (实验部分)
-
发表于: 2009-3-29 14:43 6819
-
本文是《Windows句柄表分配算法分析》的随文实验
回顾:
TableLevle=HandleTable->TableCode&3;
CapturedTable=HandleTable->TableCode&~3;
句柄表的结构根据TableLevel来确定:
TableLevel为0时,CapturedTable是一级表
TableLevel为1时,CapturedTable是二级表,CapturedTable[i]是一级表
TableLevel为2时,CapturedTable是三级表,CapturedTable[i]是二级表,CapturedTable[i][j]是一级表
三级表的内容是二级表指针,二级表的内容是一级表指针,一级表中放的才是对象及访问属性(HANDLE_TABLE_ETNRY结构)
实验目的:以实验的方式观察PspCidTable的变化,从中了解Windows句柄表的分配过程.
实验器材:Windbg,RunIt(一个可控的不断创建线程的程序,见附件)
准备工作:获取PspCidTable的基本信息
此时可以观察到PspCidTable=e1001810,当前TableCode为0xe1003000,低两位表明是一级表,表地址为0xe1003000
这时可以看到一级表存放的进线程对象了
实验一:观察句柄表的升级
由于二级表升级为三级表需要极大的句柄容量,因此我们通常只能观察到句柄表由一级表升为二级表的过程
运行RunIt.exe,按回车不断创建线程,直至新线程的ThreadId大于当前句柄表的上限0x800.
此时再观察PspCidTable:
这时的TableCode低两位表时现在是二级表,掩去低两位就是二级表的地址0xe11a4000了
可以看到,原来的一级表e1003000已经成为了二级表中的第一个元素.同时新分配了一个一级表为e11b5000.这样,句柄表的升级就完成了
实验二:观察新分配的句柄表是如何填充的
前面已经分析过,新分配的句柄表被填充成一个有序的FreeHandle序列.
观察新分配的这个二级表:
由图可知,最后一个ThreadId=0x83c,那么它在第二个表中的偏移是e11b5000+(0x83c-0x800)*2=e11b5078
从e11b5080到e11b50c0这部分的内容表明该范围内的部分句柄已经被使用过且又释放了(如果想避免该问题,你可以使用livekd的方式进行本实验,这样中断到调试器时就不会有其它动作来干扰我们的观察),但是尚未影响到e11b50c0之后的部分.
来观察这里:
e11b50c0 00000000 00000864 00000000 00000868
e11b50d0 00000000 0000086c 00000000 00000870
e11b50e0 00000000 00000874 00000000 00000878
e11b50f0 00000000 0000087c 00000000 00000880
e11b50c0作为二级表中的第二个一级表,它所对应的句柄为:
(e11b50c0-e11b5000)/2+0x800*(2-1)=0x860 //如果了解了句柄表的基本结构,这个计算很容易理解
而它的NextFreeHadleTableEntry则指向它紧挨着的下一个HANDLE_TABLE_ENTRY的所对应的句柄0x864
而且很容易看出0x864,0x868,0x86c,0x870...构成一个等差数列,这个结果可以与前面对ExpAllocateLowLevelTable函数的分析对比,两者是完全一致的.
实验到此结束.希望在句柄表知识的学习上给别人起到一些帮助作用,也希望我的学习过程对某些人有一定启示.
回顾:
TableLevle=HandleTable->TableCode&3;
CapturedTable=HandleTable->TableCode&~3;
句柄表的结构根据TableLevel来确定:
TableLevel为0时,CapturedTable是一级表
TableLevel为1时,CapturedTable是二级表,CapturedTable[i]是一级表
TableLevel为2时,CapturedTable是三级表,CapturedTable[i]是二级表,CapturedTable[i][j]是一级表
三级表的内容是二级表指针,二级表的内容是一级表指针,一级表中放的才是对象及访问属性(HANDLE_TABLE_ETNRY结构)
实验目的:以实验的方式观察PspCidTable的变化,从中了解Windows句柄表的分配过程.
实验器材:Windbg,RunIt(一个可控的不断创建线程的程序,见附件)
准备工作:获取PspCidTable的基本信息
lkd> dd PspCidTable l1 8055a360 e1001810 //获取PspCidTable的地址 lkd> dt _HANDLE_TABLE e1001810 nt!_HANDLE_TABLE +0x000 TableCode : 0xe1003000 //表基址为0xe1003000,一级表 +0x004 QuotaProcess : (null) +0x008 UniqueProcessId : (null) +0x00c HandleTableLock : [4] _EX_PUSH_LOCK +0x01c HandleTableList : _LIST_ENTRY [ 0xe100182c - 0xe100182c ] +0x024 HandleContentionEvent : _EX_PUSH_LOCK +0x028 DebugInfo : (null) +0x02c ExtraInfoPages : 0 +0x030 FirstFree : 0x308 +0x034 LastFree : 0x34c +0x038 NextHandleNeedingPool : 0x800 //当前的句柄上限 +0x03c HandleCount : 329 +0x040 Flags : 1 +0x040 StrictFIFO : 0y1
此时可以观察到PspCidTable=e1001810,当前TableCode为0xe1003000,低两位表明是一级表,表地址为0xe1003000
lkd> dd 0xe1003000 e1003000 00000000 fffffffe 821bb661 00000000 e1003010 821bb3e9 00000000 821ba021 00000000 e1003020 821bad21 00000000 821baaa9 00000000 e1003030 821ba831 00000000 821ba5b9 00000000 e1003040 821ba341 00000000 821b9021 00000000 e1003050 821b9da9 00000000 821b9b31 00000000 e1003060 821b98b9 00000000 821b9641 00000000 e1003070 821b93c9 00000000 821b8021 00000000
这时可以看到一级表存放的进线程对象了
实验一:观察句柄表的升级
由于二级表升级为三级表需要极大的句柄容量,因此我们通常只能观察到句柄表由一级表升为二级表的过程
运行RunIt.exe,按回车不断创建线程,直至新线程的ThreadId大于当前句柄表的上限0x800.
此时再观察PspCidTable:
lkd> dt _HANDLE_TABLE e1001810 nt!_HANDLE_TABLE +0x000 TableCode : 0xe11a4001 //这时已经为二级表了 +0x004 QuotaProcess : (null) +0x008 UniqueProcessId : (null) +0x00c HandleTableLock : [4] _EX_PUSH_LOCK +0x01c HandleTableList : _LIST_ENTRY [ 0xe100182c - 0xe100182c ] +0x024 HandleContentionEvent : _EX_PUSH_LOCK +0x028 DebugInfo : (null) +0x02c ExtraInfoPages : 0 +0x030 FirstFree : 0x860 +0x034 LastFree : 0x38c +0x038 NextHandleNeedingPool : 0x1000 //句柄上限达到了0x800*2=0x1000 +0x03c HandleCount : 529 +0x040 Flags : 1 +0x040 StrictFIFO : 0y1
这时的TableCode低两位表时现在是二级表,掩去低两位就是二级表的地址0xe11a4000了
lkd> dd 0xe11a4000 //观察二级表的内容 e11a4000 e1003000 e11b5000 00000000 00000000 e11a4010 00000000 00000000 00000000 00000000 e11a4020 00000000 00000000 00000000 00000000 e11a4030 00000000 00000000 00000000 00000000 e11a4040 00000000 00000000 00000000 00000000 e11a4050 00000000 00000000 00000000 00000000 e11a4060 00000000 00000000 00000000 00000000 e11a4070 00000000 00000000 00000000 00000000
可以看到,原来的一级表e1003000已经成为了二级表中的第一个元素.同时新分配了一个一级表为e11b5000.这样,句柄表的升级就完成了
实验二:观察新分配的句柄表是如何填充的
前面已经分析过,新分配的句柄表被填充成一个有序的FreeHandle序列.
观察新分配的这个二级表:
lkd> dd e11b5000 e11b5000 00000000 fffffffe 81f008b9 00000000 e11b5010 81f00641 00000000 81f003c9 00000000 e11b5020 81f5d021 00000000 81f5dda9 00000000 e11b5030 81f5db31 00000000 81f5d8b9 00000000 e11b5040 81f5d641 00000000 81f5d3c9 00000000 e11b5050 81eff021 00000000 81effda9 00000000 e11b5060 81effb31 00000000 81eff8b9 00000000 e11b5070 81eff641 00000000 81eff3c9 00000000 //RunIt创建的最后一个线程的ETHREAD在e11b5078处 lkd> dd e11b5080 82012921 00000000 00000000 00000220 //这里的一部分句柄也被使用过了,因为可能别的进程也创建了线程 e11b5090 00000000 00000000 00000000 00000478 e11b50a0 00000000 0000038c 81f5cda9 00000000 e11b50b0 00000000 00000850 00000000 0000084c e11b50c0 00000000 00000864 00000000 00000868 e11b50d0 00000000 0000086c 00000000 00000870 e11b50e0 00000000 00000874 00000000 00000878 e11b50f0 00000000 0000087c 00000000 00000880 lkd> e11b5100 00000000 00000884 00000000 00000888 e11b5110 00000000 0000088c 00000000 00000890 e11b5120 00000000 00000894 00000000 00000898 e11b5130 00000000 0000089c 00000000 000008a0 e11b5140 00000000 000008a4 00000000 000008a8 e11b5150 00000000 000008ac 00000000 000008b0 e11b5160 00000000 000008b4 00000000 000008b8 e11b5170 00000000 000008bc 00000000 000008c0
由图可知,最后一个ThreadId=0x83c,那么它在第二个表中的偏移是e11b5000+(0x83c-0x800)*2=e11b5078
从e11b5080到e11b50c0这部分的内容表明该范围内的部分句柄已经被使用过且又释放了(如果想避免该问题,你可以使用livekd的方式进行本实验,这样中断到调试器时就不会有其它动作来干扰我们的观察),但是尚未影响到e11b50c0之后的部分.
来观察这里:
e11b50c0 00000000 00000864 00000000 00000868
e11b50d0 00000000 0000086c 00000000 00000870
e11b50e0 00000000 00000874 00000000 00000878
e11b50f0 00000000 0000087c 00000000 00000880
e11b50c0作为二级表中的第二个一级表,它所对应的句柄为:
(e11b50c0-e11b5000)/2+0x800*(2-1)=0x860 //如果了解了句柄表的基本结构,这个计算很容易理解
而它的NextFreeHadleTableEntry则指向它紧挨着的下一个HANDLE_TABLE_ENTRY的所对应的句柄0x864
而且很容易看出0x864,0x868,0x86c,0x870...构成一个等差数列,这个结果可以与前面对ExpAllocateLowLevelTable函数的分析对比,两者是完全一致的.
实验到此结束.希望在句柄表知识的学习上给别人起到一些帮助作用,也希望我的学习过程对某些人有一定启示.
赞赏记录
参与人
雪币
留言
时间
Youlor
为你点赞~
2024-1-25 00:04
伟叔叔
为你点赞~
2023-12-28 00:10
QinBeast
为你点赞~
2023-10-8 00:29
一笑人间万事
为你点赞~
2023-9-9 03:26
shinratensei
为你点赞~
2023-9-7 00:16
心游尘世外
为你点赞~
2023-8-29 00:29
飘零丶
为你点赞~
2023-8-18 00:33
赞赏
他的文章
- [讨论]吐槽下物流的包装。。。 9468
- [原创]真假Rockey2完整源码 18570
- [原创]一张360的对比图 9833
- [原创]VC6插件FileTool的一点改进 10220
谁下载
xingbing
Xacs
yhtchf
lmsoft
amdey
qqeleven
Nanika
RuShi
Caten
muyen
haifengjl
info
Eter
joewy
注定飞翔
大可
啤酒肚
coolwxd
李敬利
thatman
zhtjia
JohnsonGuo
Sitar
vipsehll
哈哈在世
bboyiori
yingthesky
haras
jinjing
ytfsse
spartaman
nbrblich
yangly
tmdwoaini
Feline
gpaul
reynoldta
zhangzdzzd
rerefrancd
jackozoo
donself
rechine
ToBeNerd
tksfbz
tydef
alalal
ROC威鹏
户大
sanerersan
iytbcel
Seven的怀念
shineYao
dagangwood
谁下载
kanxue
cache
thk
海风月影
xingbing
Ivanov
cxjnet
kuang110
Xacs
ysoni
cater
vofcrlfopt
xzchina
option
ueoboy
eunt
trialversion
you_known
17521
lovenuo
amdey
linxer
qqeleven
EricAzhe
Nanika
lendy
RuShi
流行咒
starz
zhzhtst
jinghua
muyen
断血疯
网络游侠
qqkking
niuhacker
夜山鹰
haifengjl
longfoot
takile
info
小子贼野
abomber
rocketming
sudami
yzldll
Eter
creakerzgz
joewy
注定飞翔
mufasa
alexy
dkaw
要学会编
flyliying
lookzo
deletex
azy
大可
wowzjj
SongLei
啤酒肚
ruffy
千里之外
jasonnbfan
cryingtree
蚊香
Pat
yutu
coolwxd
Nukou
wzsy
李敬利
华哥huage
zyxisbg
combojiang
arsionkx
bmwz
wolfhome
mooncrack
speeches
bozer
udknight
profmit
achillis
zhtjia
halfsoul
easystone
bobowu
abvarghui
知不道z
梦中忆梦
huangkez
joshuki
songshilia
jesterjy
fancily
JohnsonGuo
晓枫木木
谁下载
kanxue
cache
thk
海风月影
xingbing
Ivanov
cxjnet
kuang110
Xacs
ysoni
cater
vofcrlfopt
xzchina
option
ueoboy
eunt
trialversion
you_known
17521
lovenuo
amdey
linxer
qqeleven
EricAzhe
lendy
RuShi
流行咒
starz
zhzhtst
jinghua
muyen
断血疯
网络游侠
qqkking
niuhacker
夜山鹰
haifengjl
longfoot
takile
info
小子贼野
abomber
rocketming
sudami
yzldll
Eter
creakerzgz
joewy
注定飞翔
mufasa
alexy
dkaw
要学会编
flyliying
lookzo
deletex
azy
大可
wowzjj
SongLei
啤酒肚
ruffy
千里之外
jasonnbfan
cryingtree
蚊香
Pat
yutu
coolwxd
Nukou
wzsy
李敬利
华哥huage
zyxisbg
combojiang
arsionkx
bmwz
wolfhome
mooncrack
speeches
thatman
bozer
udknight
profmit
achillis
zhtjia
halfsoul
easystone
bobowu
abvarghui
知不道z
梦中忆梦
huangkez
joshuki
songshilia
jesterjy
fancily
JohnsonGuo
晓枫木木
看原图
赞赏
雪币:
留言: