Windows核心編程(第五版)筆記 第三章 內(nèi)核對象(Kernel Objects)第三章 內(nèi)核對象(Kernel objects)
1.什么是內(nèi)核對象
內(nèi)核對象是由內(nèi)核分配的一塊內(nèi)存,它只能被內(nèi)核訪問。
這塊內(nèi)存存儲著一個保存著內(nèi)核對象信息的數(shù)據(jù)結構。
2.如何訪問內(nèi)核對象
應用程序不能直接訪問內(nèi)核對象,只能通過Windows API間接訪問和操作內(nèi)核對象。
那些用于操作內(nèi)核對象的API會返回一個標識內(nèi)核對象的句柄,應用程序通過該句柄和API函數(shù)來操作和訪問內(nèi)核對象。
3.內(nèi)核對象的數(shù)據(jù)成員
既然內(nèi)核對象是數(shù)據(jù)結構,那么它一定相應的數(shù)據(jù)成員。
(1) 引用計數(shù):
它用來記錄有多少個應用程序在使用該內(nèi)核對象,它該值為0時系統(tǒng)會銷毀該內(nèi)核對象。
內(nèi)核對象是由內(nèi)核所有,換句話說即使創(chuàng)建內(nèi)核對象的進程已經(jīng)結束了,所創(chuàng)建的內(nèi)核對象仍可能存在。
(2) 安全:
它用來描述誰擁有這個對象(通常是創(chuàng)建者),以及哪些用戶和組可以訪問或不可訪問該對象
在操作對象前進程必須先提交操作請求,該請求能否成功是則“安全”來控制的。
對象的創(chuàng)建都可以通過“安全”來阻止那些未授權的用戶訪問該對象。
3.判斷一個對象是否是內(nèi)核對象
判斷一個對象是否是內(nèi)核對象的最簡單方法是查看創(chuàng)建該對象的函數(shù)
幾乎所有的內(nèi)核對象的創(chuàng)建函數(shù)都有一個 用于描述安全屬性的“安全描述符”作為參數(shù)。如下:
HANDLE CreateFileMapping(
HANDLE hFile,
PSECURITY_ATTRIBUTES psa,
DWORD flProtect,
DWORD dwMaximumSizeHigh,
DWORD dwMaximumSizeLow,
PCTSTR pszName);
4.進程的句柄表(A Process' Kernel Object Handle Table)
進程在初始化后,系統(tǒng)會為它分配一個句柄表,記錄它所用到的內(nèi)核對象
Index
Pointer to Kernel Object Memory Block
Access Mask
(DWORD of Flag Bits)
Flags
1
0x????????
0x????????
0x????????
2
0x????????
0x????????
0x????????
…
…
…
…
句柄可能理解為上圖中的Index,在進程句柄表中它相當于內(nèi)核對象的指針的索引。
句柄是進程相關的不同的進程不能簡單的傳遞句柄來共享內(nèi)核對象,因為句柄它只是一個索引,它的值在不同進程中所索引的內(nèi)核對象不同 所以不是簡單的通過傳遞句柄來共享內(nèi)核對象。
5.關閉內(nèi)核對象
無論你是不是你創(chuàng)建的內(nèi)核對象,當你使用完該對象后都應該通過CloseHandle來關閉內(nèi)核對象
BOOL CloseHandle(HANDLE hobject);
Set handle to NULL after CloseHandle().
CloseHandle 會對對象的引用計數(shù)減1 然后清空進程句柄表中相應的項。
當引用計數(shù)減到0時系統(tǒng)會銷毀該內(nèi)核對象。
6.不關閉內(nèi)核對象?
如果不關閉內(nèi)核對象則內(nèi)核對象的引用計數(shù)不會減少,也就不會被系統(tǒng)銷毀,從而會產(chǎn)生內(nèi)存泄露。
幸好當程序結束后系統(tǒng)會保證釋放程序所占用的所有資源,系統(tǒng)遍歷當前進程的句柄表,然后對句柄表中的逐個項調(diào)用CloseHandle