內(nèi)核句柄表與創(chuàng)建句柄_第1頁(yè)
內(nèi)核句柄表與創(chuàng)建句柄_第2頁(yè)
內(nèi)核句柄表與創(chuàng)建句柄_第3頁(yè)
內(nèi)核句柄表與創(chuàng)建句柄_第4頁(yè)
已閱讀5頁(yè),還剩6頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、進(jìn)程句柄表與創(chuàng)建句柄表我們編寫 Windows程序中經(jīng)常使用到內(nèi)核對(duì)象, 特別是句柄這個(gè)概念, 通過句柄可以對(duì)內(nèi)核對(duì)象進(jìn)行訪問,那句柄到底是什么 ?本文將會(huì)從內(nèi)核來(lái)說明這個(gè)概念。Windows 采取了面向?qū)ο笤O(shè)計(jì) , 內(nèi)核中有一個(gè)的模塊來(lái)管理內(nèi)核對(duì)象 , 有很多資料都是說是“對(duì)象管理器” ,本文也采用這個(gè)概念。對(duì)象管理器用來(lái)管理內(nèi)核對(duì)象信息和記錄內(nèi)核對(duì)象的使用情況,包括引用計(jì)數(shù)。每個(gè)進(jìn)程都要?jiǎng)?chuàng)建一個(gè)句柄列表, 這些句柄指向各種系統(tǒng)資源, 比如信號(hào)量,線程,和文件等,進(jìn)程中的所有線程都可以訪問這些資源性 ) ,如下圖所示,進(jìn)程和資源:1.進(jìn)程與句柄表數(shù)據(jù)關(guān)系在用戶模式下如果調(diào)用 CloseHan

2、ele( )表示不再使用這個(gè)對(duì)象, 在內(nèi)核中進(jìn)程便會(huì)刪除句柄 (釋放對(duì)象引用 );對(duì)象管理器也會(huì)將內(nèi)核對(duì)象的引用計(jì)數(shù)也會(huì)減一 ,當(dāng)對(duì)象的句柄引用為 0 時(shí),對(duì)象管理器便會(huì)釋放這個(gè)對(duì)象。句柄表最基本作用就是句柄與目標(biāo)對(duì)象之間的映射表 ,下圖是進(jìn)程與句柄的簡(jiǎn)化模型圖 (有些數(shù)據(jù)域要經(jīng)過處理 ):_HANDLE_TABLE 是句柄表的信息的結(jié)構(gòu)體 ,在內(nèi)核中 句柄是句柄表中表項(xiàng)的索引 ,在這里可以簡(jiǎn)單的理解 ,由索引 ( 句柄 )在句柄表中查找到進(jìn)程引用的內(nèi)核對(duì)象 .在 Windbg 中查看 _HANDLE_TABLE( 這里例出部分有意義的項(xiàng) )kd> dt _HANDLE_TABLEnt!

3、_HANDLE_TABLE+0x000 TableCode: Uint4B/指向第一層局部表 ,并記錄層數(shù)+0x004 QuotaProcess: Ptr32 _EPROCESS /指向進(jìn)程 _EPROCESS塊+0x008 UniqueProcessId : Ptr32 Void/進(jìn)程 ID+0x03c HandleCount: Int4B/句柄計(jì)數(shù) ,當(dāng)前使用句柄個(gè)數(shù)kd> dt _EPROCESS/進(jìn)程 _EPROCESS塊信息nt!_EPROCESS+0x084 UniqueProcessId : Ptr32 Void/進(jìn)程 ID+0x0c4 ObjectTable : Ptr3

4、2 _HANDLE_TABLE/指向 _HANDLE_TABLE 結(jié)構(gòu)2.句柄的數(shù)據(jù)結(jié)構(gòu)內(nèi)核與 SDK 中定義句柄都為 :typedef void *HANDLE;表明句柄是一個(gè)無(wú)符號(hào)整數(shù) ,實(shí)際上有效句柄的值時(shí)有范圍的 ,大家想想如果采用數(shù)組來(lái)存儲(chǔ)句柄需要耗費(fèi)很大的內(nèi)存 ,Windows 句柄表使用了稀疏數(shù)組 .2.1XP/2003 句柄表項(xiàng) :先看下句柄表中存放的是什么?句柄表主要是存放的是對(duì)象的地址與屬性信息 ,當(dāng)然還要存放句柄表相關(guān)一些信息(審計(jì),空閑項(xiàng)),每個(gè)句柄表項(xiàng)是由_HANDLE_TABLE_ENTRY描述的, _HANDLE_TABLE_ENTRY占 8 字節(jié),定義如下:kd

5、> dt _HANDLE_TABLE_ENTRYnt!_HANDLE_TABLE_ENTRY+0x000 Object: Ptr32 Void/對(duì)象指針+0x000 ObAttributes: Uint4B+0x000 InfoTable: Ptr32 _HANDLE_TABLE_ENTRY_INFO+0x000 Value: Uint4B+0x004GrantedAccess: Uint4B+0x004GrantedAccessIndex : Uint2B+0x006CreatorBackTraceIndex : Uint2B+0x004NextFreeTableEntry : Int

6、4B由于 _HANDLE_TABLE_ENTRY有些聯(lián)合體 ,不好理解 ,源碼定義如下typedef struct _HANDLE_TABLE_ENTRY union PVOID Object;/對(duì)象指針ULONG ObAttributes;/對(duì)象屬性PHANDLE_TABLE_ENTRY_INFO InfoTable;ULONG_PTR Value;/值;:union union ACCESS_MASK GrantedAccess;/訪問掩碼struct USHORT GrantedAccessIndex;USHORT CreatorBackTraceIndex;LONG NextFreeT

7、ableEntry;/下一個(gè)空閑的句柄表項(xiàng) ,空閑鏈表索引; HANDLE_TABLE_ENTRY , *PHANDLE_TABLE_ENTRY;表示的意義 :1.對(duì)象指針 Object 有效則第二個(gè)域?yàn)樵L問掩碼GrantedAccess2. 第一個(gè)域?yàn)?0,第二個(gè)域可能是 NextFreeTableEntry,也可能為審計(jì) ,后面會(huì)有相關(guān)算法用到這個(gè)域 ,要根據(jù)上下文來(lái)判斷。這里的 Object 并不是“真正”的對(duì)象指針,而是包括了對(duì)象的指針域?qū)ο蟮膶傩杂颍?由于在內(nèi)核中對(duì)象總是 8 字節(jié)對(duì)齊的,那么指向?qū)ο蟮闹羔樧畹?3 位總是 0,微軟把這 3 位也利用上, Object 的最低 3 位

8、做為對(duì)象的屬性,看下面的一組宏定義:#define OBJ_HANDLE_ATTRIBUTES (OBJ_PROTECT_CLOSE | OBJ_INHERIT | OBJ_AUDIT_OBJECT_CLOSE)第 0 位 OBJ_PROTECT_CLOSE:句柄表項(xiàng)是否被鎖定 ,1 鎖定, 0 未鎖定第 1 位 OBJ_INHERIT: 指向該進(jìn)程所創(chuàng)建的子進(jìn)程是否可以繼承該句柄,既是否將該句柄項(xiàng) 拷貝到它的句柄表中第 2 位 OBJ_AUDIT_OBJECT_CLOSE: 關(guān)閉該對(duì)象時(shí)是否產(chǎn)生一個(gè)審計(jì)事件2.2XP/2003 句柄表項(xiàng) :Windows 為了節(jié)省空間采用動(dòng)態(tài)擴(kuò)展結(jié)構(gòu), 類似

9、于頁(yè)表結(jié)構(gòu) , 最大可擴(kuò)展3層表 ._HANDLE_TABLE.TableCode存放了第一層局部表的基址指針和層數(shù), 微軟在這里設(shè)計(jì)很精妙 , 由于效率32 位地址都以4 對(duì)齊 , 最低 2 位為 0,微軟把_HANDLE_TABLE. TableCode的最低兩位作為句柄表層數(shù)的紀(jì)錄, 即 00 一層表 ,01 二層表10三層表 . 句柄表的結(jié)構(gòu)圖如下:一層表 :兩層表時(shí) :_HANDLE_TABLE_ENTRY_HANDLE_TABLE_ENTRY_HANDLE_TABLE_ENTRY三層表時(shí) :_HANDLE_TABLE_ENTRY_HANDLE_TABLE_ENTRY_HANDLE_

10、TABLE_ENTRY有上圖所示 ,最低層局部表都是是存放著 _HANDLE_TABLE_ENTTY 結(jié)構(gòu) ,中間層和最高層都是存放著頁(yè)表指針 ,當(dāng)句柄增加時(shí) ,便會(huì)判斷是否需要擴(kuò)展。2.3XP/2003 句柄表表項(xiàng)計(jì)數(shù):句柄表是動(dòng)態(tài)擴(kuò)展, 當(dāng)引用資源足夠多時(shí), 句柄的數(shù)目也在增加, 當(dāng)?shù)揭欢〝?shù)目時(shí),句柄表便會(huì)擴(kuò)展,擴(kuò)展的標(biāo)準(zhǔn)是什么?下面一系列宏給出了定義(1) 最低層存放句柄表項(xiàng)數(shù):每個(gè)最底層頁(yè)表存放的是 _HANDLE_TABLE_ENTRY 結(jié)構(gòu) , 即 4096/8 = 512,其中第一項(xiàng)做審計(jì)用 ,最多有 511 個(gè)有效項(xiàng)#define LOWLEVEL_COUNT (TABLE_P

11、AGE_SIZE / sizeof(HANDLE_TABLE_ENTRY)(2) 中間層可以存放的項(xiàng)數(shù)中間層存放的頁(yè)表指針 ,最多有 4028 / 4 =1024#define MIDLEVEL_COUNT (PAGE_SIZE / sizeof(PHANDLE_TABLE_ENTRY)(3)可分配的最大句柄值 ,不是我們想象的無(wú)符號(hào)整數(shù)最大值#define MAX_HANDLES (1<<24)/224(4)最高層最大項(xiàng)數(shù) :#define HIGHLEVEL_COUNTMAX_HANDLES/(LOWLEVEL_COUNT*MIDLEVEL_COUNT)在句柄表結(jié)構(gòu)圖已經(jīng)說明層

12、表第一層表最大有項(xiàng)即 2245332/(1024*512) = 2=32,通過上面計(jì)算 :二級(jí)表最大可以存放 511 * 1024= 523264 個(gè)對(duì)象引用 ,沒有特殊情況一般來(lái)說已經(jīng)夠了 ,所以我們一般只能觀察到一層 ,兩層句柄表3. nt!PspCreateProcess中創(chuàng)建進(jìn)程句柄表3.1 在創(chuàng)建進(jìn)程時(shí)初始化進(jìn)程對(duì)象并創(chuàng)建進(jìn)程句柄表創(chuàng)建進(jìn)程時(shí)先創(chuàng)建進(jìn)程對(duì)象,再創(chuàng)建進(jìn)程句柄表,即nt!PspCreateProcess->nt!ObInitProcess->nt!ExCreateHandleTable,創(chuàng)建句柄表的核心流程圖如下 :分配進(jìn)程句柄表例程步驟:1.調(diào)用 ExpAl

13、locateHandleTable 分配句柄表及_HANDLE_TABLE結(jié)構(gòu)2. 插入到進(jìn)程句柄表鏈表函數(shù)描述 :; Routine Description:; This function allocate and initialize a new new handle table; 這個(gè)例程分配并初始化一個(gè)新的句柄表 (_HANDLE_TABLE); Arguments:; Process - Supplies an optional pointer to the process against which quota; will be charged.; 提供一個(gè)將要記錄相關(guān)信息 (對(duì)象

14、 )的進(jìn)程的指針; Return Value:; If a handle table is successfully created, then the address of the; handle table is returned as the function value. Otherwise, a value; NULL is returned.; 如果成功函數(shù)返回 handle table的地址 ,負(fù)責(zé)返回 0_HANDLE_TABLE *_stdcall ExCreateHandleTable(_EPROCESS *pProcess)核心算法分析 :由于進(jìn)程句柄表是一個(gè)雙向鏈表結(jié)構(gòu)

15、 ,是系統(tǒng)很重要的數(shù)據(jù)結(jié)構(gòu) ,所以必須考慮同步問題 ,只有在加鎖的情況下才能修改通過 ExpAllocateHandleTable 分配進(jìn)程句柄表 :push 1 ; DoInitpush ebp+pProcess ; pProcesscall _ExpAllocateHandleTable8 ; 創(chuàng)建句柄表例程 mov ebx, eaxtest ebx, ebx ; 判斷 ExpAllocateHandleTable 是否成功 jz short ALLOC_HANDLE_TABLE_UNSUCCESS句柄表是進(jìn)程句柄鏈表是內(nèi)核重要結(jié)構(gòu),有同步問題存在 ,這里給句柄表上鎖mov eax, 0;

16、 系統(tǒng)句柄鏈表的改變必須要實(shí)現(xiàn)同步操作 ,所以要使用鎖 mov ecx, offset _HandleTableListLocklock bts ecx, eax ; 加鎖加入進(jìn)程句柄表鏈表mov ecx, _HandleTableListHead.Blink;取_Handle_TABLE.HandleTableList 的 Flink 指針mov eax+_LIST_ENTRY.Flink, ecxmov dword ptr eax, offset _HandleTableListHead.Flink HandleTalbeListHead; 取得句柄表鏈表頭節(jié)點(diǎn)的頭指針地址 mov ecx

17、, eaxmov _HandleTableListHead.Blink, eax;設(shè)置nt!ExpAllocateHandleTable的核心流程 :ExpAllocateHandleTable 例程 :1. 分配 _HANDLE_TABLE 內(nèi)存池與分配一頁(yè)內(nèi)存池作為第一層句柄表2. 初始化句柄表3. 建立進(jìn)程與句柄表的映射關(guān)系函數(shù)描述 :; Routine Description:; This worker routine will allocate and initialize a new handle table; structure. The new structure consis

18、ts of the basic handle table; struct plus the first allocation needed to store handles. This is; really one page divided up into the top level node, the first mid; level node, and one bottom level node.; 例程分配并初始化一個(gè)新的句柄表結(jié)構(gòu) ,加入一些存儲(chǔ)句柄的必要的基本結(jié)構(gòu)信息; 到新分配的句柄表結(jié)構(gòu)中 .這里準(zhǔn)備一個(gè)頁(yè)內(nèi)存分割給高層節(jié)點(diǎn) ,第一個(gè)中間層節(jié)點(diǎn)和一個(gè); 低層節(jié)點(diǎn); Argumen

19、ts:; Process - Optionally supplies the process to charge quota for the;handle table;提供審計(jì)配額信息的進(jìn)程(并不是指當(dāng)前進(jìn)程 )的指針; DoInit - If FALSE then we are being called by duplicate and we don't need;the free list built for the caller; 如果 FALSE(copy)時(shí)同樣會(huì)被調(diào)用 ,并且調(diào)用者不需要釋放創(chuàng)建建的表; Return Value:; A pointer to the new

20、 handle table or NULL if unsuccessful at getting; pool.; 一個(gè)指向句柄表 (HANDLE_TABLE) 的指針 ,如果 NULL 表示獲取內(nèi)核內(nèi)存池失敗; _HANDLE_TABLE *_stdcall ExpAllocateHandleTable(_EPROCESS *pProcess, char DoInit)核心算法分析 :分配 _HANDLE_TABLE結(jié)構(gòu)內(nèi)存池 :push6274624Fh; Tagpush44h; sizeof(_HANDLE_TABLE)push1; PoolTypecall_ExAllocatePoolW

21、ithTag12 ; 分配一個(gè)大小為sizeof(HANDLE_TABLE) 的內(nèi)核內(nèi)存;池movesi, eaxxorebx, ebxcmpesi, ebx; 判斷內(nèi)存池是否分配成功jzshort AllOC_POOL_UNSUCCESS分配一頁(yè)內(nèi)存池作為第一層句柄表pushedipush11hpopecxpush1000h; 一個(gè)頁(yè)表大小pushebp+pProcess ; _ERPOCESS 指針xoreax, eaxmovedi, esirep stosd; 分配一頁(yè)內(nèi)存call_ExpAllocateTablePagedPoolNoZero8 ; 分配一頁(yè)內(nèi)存池 ,作為第一級(jí)句柄表c

22、mpeax, ebx; 判斷是否分配成功jnzshort AllOC_PAGE_SUCCESS ; 判斷 DoInit參數(shù)是否為 FALSEpushebx; TagToFreepushesi; Pcall_ExFreePoolWithTag8 ; 釋放內(nèi)存分配的內(nèi)存池cmpebp+DoInit, bl ;判斷DoInit參數(shù)是否為FALSEmovesi+_HANDLE_TABLE.TableCode, eax ;HANDLT_TABLE第一項(xiàng)將分配的頁(yè)表基地址賦值給TableCode,建立一級(jí)表的映射關(guān)系初始句柄表,設(shè)置空閑句柄鏈表:movdword ptr eax+_HANDLE_TABLE

23、_ENTRY.NextFreeTableEntry, 0FFFFFFFEhmovmovjzpushpoppushaddpop; 句柄頁(yè)表的第一個(gè)句柄項(xiàng)作為審計(jì)用,; NextFreeTableEntry 設(shè)置為 EX_ADDITIONAL_INFO_SIGNATURE設(shè)置第一項(xiàng)Value 為 0edx, 800hshort DOINIT_FALSE8ecx; ecx = 84eax, 8; 指向第二項(xiàng)HANDLE_TABLE_ENTRY指針edi; 記錄空閑項(xiàng)鏈表,當(dāng)前為第二項(xiàng)HANDLE_TABLE_ENTRY值為標(biāo)志4END_LOOP:; 設(shè)置當(dāng)前項(xiàng)的下一個(gè)空閑句柄索引moveax+_HANDLE_TABLE_ENTRY ._u1.NextFreeTableEntry, ecxmoveax+_HANDLE_TABLE_ENTRY ._u0.Value,

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論