windbg學(xué)習(xí)筆記 FOR 內(nèi)核調(diào)試(三) --進(jìn)程句柄表HANDLE_TABLE
??????????????????????????????????????
想當(dāng)年
初學(xué)核編
,
閱讀第三章的內(nèi)核對(duì)象的時(shí)候跟看天書(shū)沒(méi)什么感覺(jué)
死命在想到底內(nèi)核對(duì)象
,
句柄是個(gè)什么東西
干嘛用的
于是我們工作室的老大就對(duì)我說(shuō)
這篇看過(guò)就過(guò)了
學(xué)到后面你自然會(huì)明白的
???
我想也是
,
很多時(shí)候感覺(jué)學(xué)東西的確是這樣
暫時(shí)看不懂的先放著
過(guò)段時(shí)間再看回來(lái)就恍然大悟了
.
我前段時(shí)間又看了下核編的第三章
唯一的收獲就是能夠大概了解到
hanle
這個(gè)所謂的索引的作用了
.
我也跟工作室的小學(xué)弟講過(guò)我理解的句柄
(
但是講完看到他們茫然的表情
~
郁悶了
~
沒(méi)辦法
可能知識(shí)面
實(shí)踐經(jīng)驗(yàn)等還不足以理解我說(shuō)的東西吧
或者是被我們可愛(ài)的鼠仙傳染了
也開(kāi)始學(xué)著他講天書(shū)了
~)
? ?
以下講的都是我所理解的東東
,
有錯(cuò)誤的話也在所難免了
???
首先說(shuō)說(shuō)
HANDLE
這個(gè)是個(gè)什么東西
在
WinNT.h
里面查到其定義如下
typedef
void *HANDLE;
哈
~
這下子明白了
原來(lái)
HANDLE
就是一個(gè)無(wú)類(lèi)型指針
,
只是充當(dāng)內(nèi)核對(duì)象在進(jìn)程句柄表里面的索引
,
相當(dāng)于在進(jìn)程句柄表內(nèi)的一個(gè)
ID
號(hào)
.
進(jìn)程句柄表
個(gè)人理解就是存放這個(gè)進(jìn)程所創(chuàng)建的內(nèi)核對(duì)象在內(nèi)核地址空間位置的一個(gè)表
(
你可以理解為數(shù)組
),
那么什么是內(nèi)核對(duì)象呢
?
內(nèi)核對(duì)象只不過(guò)是系統(tǒng)資源的一種抽象
,
我新建了個(gè)進(jìn)程
,
那么系統(tǒng)內(nèi)部就會(huì)為這個(gè)進(jìn)程分配資源
,
然后創(chuàng)建一個(gè)內(nèi)核對(duì)象
,
返回一個(gè)句柄
通過(guò)這個(gè)句柄我們可以找到進(jìn)程在內(nèi)核空間的位置
,
其實(shí)也就是進(jìn)程對(duì)應(yīng)的內(nèi)核對(duì)象的位置
,
在內(nèi)核里面
,
內(nèi)核對(duì)象就是一堆數(shù)據(jù)結(jié)構(gòu)
,
只不過(guò)數(shù)據(jù)結(jié)構(gòu)很大
,
里面存放著這個(gè)進(jìn)程的信息
,
這樣系統(tǒng)只要改變這個(gè)結(jié)構(gòu)里面的數(shù)值就能操作進(jìn)程
,
如此而已
~
嘿嘿
消化一下上面說(shuō)的
接下來(lái)就說(shuō)進(jìn)程句柄表了
,
進(jìn)程句柄表是保存在進(jìn)程的內(nèi)核對(duì)象里面的
進(jìn)程的內(nèi)核對(duì)象就是個(gè)
EPROCESS
的結(jié)構(gòu)
結(jié)構(gòu)原型如下
:
kd> dt _EPROCESS
ntdll!_EPROCESS
?? +0x000
Pcb????????????? : _KPROCESS
?? +0x
?? +0x070
CreateTime?????? : _LARGE_INTEGER
?? +0x078
ExitTime???????? : _LARGE_INTEGER
?? +0x080
RundownProtect?? : _EX_RUNDOWN_REF
?? +0x084
UniqueProcessId? : Ptr32 Void
?? +0x088
ActiveProcessLinks : _LIST_ENTRY
?? +0x090
QuotaUsage?????? : [3] Uint4B
?? +0x
?? +0x
?? +0x
?? +0x0b0
VirtualSize????? : Uint4B
?? +0x0b4
SessionProcessLinks : _LIST_ENTRY
?? +0x0bc
DebugPort??????? : Ptr32 Void
?? +0x
??
+0x
?? +0x
?? +0x0cc
WorkingSetLock?? : _FAST_MUTEX
?? +0x0ec
WorkingSetPage?? : Uint4B
?? +0x
?? +0x110
HyperSpaceLock?? : Uint4B
?? +0x114
ForkInProgress?? : Ptr32 _ETHREAD
?? +0x118
HardwareTrigger? : Uint4B
??
+0x
?? +0x120 VadHint????????? : Ptr32 Void
??
+0x124 CloneRoot??????? : Ptr32 Void
?? +0x128
NumberOfPrivatePages : Uint4B
?? +0x
?? +0x130
Win32Process???? : Ptr32 Void
?? +0x134
Job????????????? : Ptr32 _EJOB
?? +0x138
SectionObject??? : Ptr32 Void
?? +0x
?? +0x140
QuotaBlock?????? : Ptr32
_EPROCESS_QUOTA_BLOCK
?? +0x144
WorkingSetWatch? : Ptr32
_PAGEFAULT_HISTORY
?? +0x148
Win32WindowStation : Ptr32 Void
?? +0x
?? +0x150
LdtInformation?? : Ptr32 Void
?? +0x154
VadFreeHint????? : Ptr32 Void
?? +0x158
VdmObjects?????? : Ptr32 Void
?? +0x
?? +0x160
PhysicalVadList? : _LIST_ENTRY
?? +0x168
PageDirectoryPte : _HARDWARE_PTE_X86
?? +0x168
Filler?????????? : Uint8B
?? +0x170
Session????????? : Ptr32 Void
?? +0x174
ImageFileName??? : [16] UChar
?? +0x184
JobLinks???????? : _LIST_ENTRY
?? +0x
?? +0x190
ThreadListHead?? : _LIST_ENTRY
?? +0x198
SecurityPort???? : Ptr32 Void
?? +0x
?? +0x
?? +0x
?? +0x
?? +0x
?? +0x1b0
Peb????????????? : Ptr32 _PEB
?? +0x1b4
PrefetchTrace??? : _EX_FAST_REF
?? +0x1b8
ReadOperationCount : _LARGE_INTEGER
?? +0x
?? +0x
?? +0x1d0
ReadTransferCount : _LARGE_INTEGER
?? +0x1d8
WriteTransferCount : _LARGE_INTEGER
?? +0x1e0
OtherTransferCount : _LARGE_INTEGER
?? +0x1e8
CommitChargeLimit : Uint4B
?? +0x1ec
CommitChargePeak : Uint4B
?? +0x
?? +0x
?? +0x
?? +0x238
LastFaultCount?? : Uint4B
?? +0x
?? +0x240
NumberOfVads???? : Uint4B
?? +0x244
JobStatus??????? : Uint4B
?? +0x248
Flags??????????? : Uint4B
?? +0x248
CreateReported?? : Pos 0, 1 Bit
?? +0x248
NoDebugInherit?? : Pos 1, 1 Bit
?? +0x248
ProcessExiting?? : Pos 2, 1 Bit
?? +0x248
ProcessDelete??? : Pos 3, 1 Bit
?? +0x248
Wow64SplitPages? : Pos 4, 1 Bit
?? +0x248
VmDeleted??????? : Pos 5, 1 Bit
?? +0x248
OutswapEnabled?? : Pos 6, 1 Bit
?? +0x248
Outswapped?????? : Pos 7, 1 Bit
?? +0x248
ForkFailed?????? : Pos 8, 1 Bit
?? +0x248
HasPhysicalVad?? : Pos 9, 1 Bit
?? +0x248
AddressSpaceInitialized : Pos 10, 2 Bits
?? +0x248
SetTimerResolution : Pos 12, 1 Bit
?? +0x248
BreakOnTermination : Pos 13, 1 Bit
?? +0x248
SessionCreationUnderway : Pos 14, 1 Bit
?? +0x248
WriteWatch?????? : Pos 15, 1 Bit
?? +0x248
ProcessInSession : Pos 16, 1 Bit
?? +0x248
OverrideAddressSpace : Pos 17, 1 Bit
?? +0x248
HasAddressSpace? : Pos 18, 1 Bit
?? +0x248
LaunchPrefetched : Pos 19, 1 Bit
?? +0x248
InjectInpageErrors : Pos 20, 1 Bit
?? +0x248
VmTopDown??????? : Pos 21, 1 Bit
?? +0x248
Unused3????????? : Pos 22, 1 Bit
?? +0x248
Unused4????????? : Pos 23, 1 Bit
?? +0x248
VdmAllowed?????? : Pos 24, 1 Bit
?? +0x248
Unused?????????? : Pos 25, 5 Bits
?? +0x248
Unused1????????? : Pos 30, 1 Bit
?? +0x248
Unused2????????? : Pos 31, 1 Bit
?? +0x
?? +0x250
NextPageColor??? : Uint2B
?? +0x252
SubSystemMinorVersion : UChar
?
? +0x253 SubSystemMajorVersion : UChar
?? +0x252
SubSystemVersion : Uint2B
?? +0x254
PriorityClass??? : UChar
?? +0x255
WorkingSetAcquiredUnsafe : UChar
?? +0x258
Cookie?????????? : Uint4B
????
看
~
變態(tài)的長(zhǎng)
~
我們可以看到紅色標(biāo)注的那個(gè)結(jié)構(gòu)成員
,
這個(gè)就是進(jìn)程句柄表的地址了
,
它是一個(gè)
handle_table
結(jié)構(gòu)的東東
~HOHO~
看看這個(gè)是什么結(jié)構(gòu)
?
kd> dt _handle_table
ntdll!_HANDLE_TABLE
?? +0x000
TableCode??????? : Uint4B
?? +0x004
QuotaProcess???? : Ptr32 _EPROCESS
?? +0x008
UniqueProcessId? : Ptr32 Void
?? +0x
?? +0x
?? +0x024
HandleContentionEvent : _EX_PUSH_LOCK
?? +0x028
DebugInfo??????? : Ptr32
_HANDLE_TRACE_DEBUG_INFO
?? +0x
?? +0x030
FirstFree??????? : Uint4B
?? +0x034
LastFree???????? : Uint4B
?? +0x038
NextHandleNeedingPool : Uint4B
?? +0x
?? +0x040
Flags??????????? : Uint4B
?? +0x040
StrictFIFO?????? : Pos 0, 1 Bit
呵呵
結(jié)構(gòu)大小尚可接受
~
那么在這個(gè)句柄表內(nèi)
~
我們的句柄信息到底藏在哪里咧
?
就是在結(jié)構(gòu)變量
TableCode
這里找
,
怎么找咧
?
看了下網(wǎng)上的
WRK
代碼
大概明白他們的思路
原來(lái)
TableCode
是個(gè)
4
字節(jié)的數(shù)值
,
這個(gè)數(shù)值的低
2
位記錄著句柄表的級(jí)數(shù)
,
什么意思咧
?
一會(huì)下面會(huì)講到
,
通過(guò)句柄值我們就可以在句柄表內(nèi)查到所謂的內(nèi)核對(duì)象了
不過(guò)這里面又有好多細(xì)節(jié)的東西
~
句柄需要轉(zhuǎn)換才能查到內(nèi)核對(duì)象地址
,
那么我們就邊說(shuō)邊做的
涉及到的東西我在補(bǔ)充
我們先用
windbg
來(lái)看看進(jìn)程信息
(
以下涉及到的
WINDBG
命令請(qǐng)到學(xué)習(xí)筆記
一
二
文章去看
~)
kd> !handle 0 2 6e8
processor number 0, process 000006e8
Searching for Process with Cid == 6e8
PROCESS 812e9408?
SessionId: 0? Cid: 06e8??? Peb: 7ffd5000? ParentCid: 05e0
???
DirBase:
Image:
ctfmon.exe
Handle table at e
………………….
0114
:
Object: e1688498? GrantedAccess: 00000002
Entry: e
Object: e1688498?
Type: (81592560) Section
ObjectHeader:
e1688480 (old version)
………………….
嘿嘿
6e8
是這個(gè)進(jìn)程的
PID ?
內(nèi)核對(duì)象的句柄值是
0114?
其他參數(shù)不說(shuō)明了
自己看幫助吧
我們可以看到
PID
為
6e8
的進(jìn)程的一些詳細(xì)信息
還有這個(gè)進(jìn)程下的
n
多內(nèi)核對(duì)象
我就顯示了
1
個(gè)
,
省的看的眼花
那么我們就開(kāi)始用
windbg
研究這個(gè)句柄表吧
?
首先
我們從上面信息知道
ctfmon.exe
這個(gè)進(jìn)程的內(nèi)核對(duì)象地址是在
812e9408
kd> dt _eprocess 812e9408
ntdll!_EPROCESS
……
?? +0x
……
?? +0x174
ImageFileName??? : [16]? "ctfmon.exe"
……
????
省略了
N
多內(nèi)容
只把重要內(nèi)容顯示出來(lái)了
可以看到
這個(gè)進(jìn)程名的確是
ctfmon.exe
那么它所對(duì)應(yīng)的句柄表的位置在這里
:0xe190e928??
走到這里瞧下
kd>
dt _handle_table 0xe190e928
ntdll!_HANDLE_TABLE
?? +0x000 TableCode??????? : 0xe
?? +0x004 QuotaProcess???? : 0x812e9408 _EPROCESS
?? +0x008 UniqueProcessId? : 0x000006e8
?? +0x
?? +0x
?? +0x024 HandleContentionEvent : _EX_PUSH_LOCK
?? +0x028 DebugInfo??????? : (null)
?? +0x
?? +0x030 FirstFree??????? : 0x118
?? +0x034 LastFree???????? : 0
?? +0x038 NextHandleNeedingPool : 0x800
?? +0x
?? +0x040 Flags??????????? : 0
?? +0x040 StrictFIFO?????? : 0y0
可以看到
TableCode
的地址在
0xe
這里就得說(shuō)明下句柄表
,
句柄表分三層
頂層句柄表大小
1K
可存放
256
個(gè)元素
,
每個(gè)元素占
4bit ,
中層表大小
1K
可存放
256
個(gè)元素
,
每個(gè)元素占
4bit ,
下層表大小
2K
可放
256
個(gè)元素
每個(gè)元素
8bit .
我們可以看到
TableCode
的低
2
位是
0
表示這個(gè)句柄表只有
1
級(jí)
,
那么只要句柄值的低
10
位乘以
2
就是該內(nèi)核對(duì)象的指針在句柄表里面的位置了
.
kd> dd e
e
e
看到
e1688481
了吧
?
這個(gè)就是內(nèi)核對(duì)象頭的地址
,
由于對(duì)象頭和對(duì)象體偏移量是
0x18,
所以加上
0x18
就可以找到對(duì)應(yīng)的內(nèi)核對(duì)象了
kd> !object e1688481+17
Object: e1688498?
Type: (81592560) Section
???
ObjectHeader: e1688480 (old version)
???
HandleCount: 9? PointerCount: 10
Directory
Object: e1432248? Name: ShimSharedMemory
呃
….
這個(gè)是系統(tǒng)是
sp3
的
,
好像跟
sp2
的有點(diǎn)出入
.
偏移量加
0x17
才是真正的對(duì)象頭
,
而不是加
0x18…..
麻煩哪位高手解釋一下
對(duì)比剛才上面那個(gè)對(duì)象信息
0114
:
Object: e1688498? GrantedAccess: 00000002
Entry: e
Object: e1688498?
Type: (81592560) Section
ObjectHeader:
e1688480 (old version)
一樣的
?
呵呵
~~
剛才大概把用內(nèi)核句柄查找內(nèi)核對(duì)象的過(guò)程演示了一下
,
反正大概操作系統(tǒng)也是這么利用句柄找內(nèi)核對(duì)象的
,
但是
…..
巨多的疑問(wèn)隨之產(chǎn)生
….
1.???
對(duì)象頭跟對(duì)象體到底是個(gè)什么結(jié)構(gòu)什么東西?
?
2.???
咋個(gè)
sp3
下
,
對(duì)象頭和對(duì)象體的偏移確實(shí)是
0x17
但是我根據(jù)句柄找到的對(duì)象頭的地址跟實(shí)際內(nèi)核的對(duì)象頭的地址竟然相差
1?
到底是我哪里做錯(cuò)了
?(解決 ^_^)
3.???
其實(shí)剛才只是演示了句柄表級(jí)數(shù)為
0
時(shí)的情況
,
還有句柄表為
1
級(jí)
(TableCode
低
2
位為
01),2
級(jí)的
(TableCode
低
3
位為
10)
的情況
,
但是這個(gè)我倒是疑惑不少
,
到底系統(tǒng)是怎么管理這張系統(tǒng)表的
?
個(gè)人理解是這樣的
,
如果剛開(kāi)始分配的的是
0
級(jí)表
,
那么可以存放
512
個(gè)對(duì)象指針
,
但是如果內(nèi)核對(duì)象多出了
512
系統(tǒng)會(huì)分配個(gè)中層表
,
但是我看到的中層表計(jì)算偏移的公式是這樣的
TableCode
地址
+
中層偏移
*4+
低層偏移
*2??
那么當(dāng)內(nèi)核對(duì)象多出
512
的時(shí)候內(nèi)存有是如何分配的呢
?
貌似跟
2k
的分配方式不同了
~
望高人指點(diǎn)
~
參考文獻(xiàn):
句柄啊,3層表啊,ExpLookupHandleTableEntry啊...
JIURL玩玩Win2k進(jìn)程線程篇 HANDLE_TABLE
補(bǔ)充:? 09-1-26 18:30
對(duì)于第二個(gè)問(wèn)題? 大概有個(gè)了解了? 哈哈~~? 在此多謝實(shí)驗(yàn)室大牛指點(diǎn)~!
原來(lái)是這樣的? 在句柄這個(gè)32位數(shù)中 10~2位這九位是0級(jí)表的索引,11~20位是1級(jí)表的索引,21~30是2級(jí)表的索引,
第三十一位是無(wú)效的 為0 但是第0位和第1位不暫時(shí)不知道干嘛的 暫且放著? 計(jì)算索引的時(shí)候先將句柄除以四(也就是左移2位的作用)然后在取對(duì)以級(jí)層的索引
知道了這個(gè)關(guān)系就好了 我們重新看看我們的句柄是0x114 而且是在0級(jí)表做索引
所以先左移兩位在乘以8(因?yàn)?級(jí)表中每個(gè)元素占8字節(jié)) 0x114/4*8 = 0x114*2
那么我們的句柄在0級(jí)表中的地址就應(yīng)該是
e
所以有
??????
kd> dd e
??????
e
我們可以看到對(duì)應(yīng)的_HANDLE_TABLE_ENTRY地址應(yīng)該是
e1688481 但是還要做一些處理才行? 由于為了內(nèi)存對(duì)齊(到現(xiàn)在我也不知道這個(gè)跟內(nèi)存對(duì)齊有什么關(guān)系~) 所以內(nèi)核對(duì)象真實(shí)地址的低2位得為0,最高位得為1 那么我們最后一步要做的事情就是把地址規(guī)格化
地址 | 0x80000000 & 0xFFFFFFF8? (將最高位置1 低2位置0)
所以真實(shí)的地址應(yīng)該是
e1688481? | 0x80000000 & 0xFFFFFFF8 = e1688480
這個(gè)就是對(duì)象頭的地址 由于對(duì)象頭的地址大小為0x18? 所以加上偏移量18就是對(duì)象體的地址
所以對(duì)象體的地址就是
e1688480 + 0x18 = e1688498
可以看到 我最后拿!object指令看的那個(gè)對(duì)象體地址就是e1688498 跟原句柄對(duì)應(yīng)的對(duì)象體是一樣的~~哈哈??
附上_HANDLE_TABLE_ENTRY結(jié)構(gòu)
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
還有個(gè)EXHANDLE結(jié)構(gòu)
typedef?struct?_EXHANDLE
{
????union
????{
????????struct
????????{
????????????ULONG?TagBits:2;
????????????ULONG?Index:30;
????????};
????????HANDLE?GenericHandleOverlay;
????????ULONG_PTR?Value;(2k下沒(méi)這個(gè)成員~)
????};
}?EXHANDLE,?*PEXHANDLE;
???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? ?? __ay.字
posted on 2009-01-25 17:43 __ay 閱讀(3046) 評(píng)論(1) 編輯 收藏 引用 所屬分類(lèi): 操作系統(tǒng)&&內(nèi)核