windows編程以內核對象

      學好windows編程,理解內核對象仍是相當重要的(●'◡'●)。閒話很少說,下面先來了解一下關於內核對象的知識:編程

      內核對象(kernel object):內核對象是用於管理進程、線程和文件等諸多種類的大量資源。windows

      內核對象的分類:進程對象,線程對象,互斥量(mutex)對象,信號量(semaphore)對象,事件對象,做業對象,文件對象,文件映射對象,管道(pipe)對象,郵件槽(mailslot)對象,I/O完成端口對象,線程池工廠(thread pool  worker  factory)對象,令牌(access token)對象、可等待的計時器(waitable timer)對象等。安全

      內核對象的特性:數據結構

      每一個內核對象都只是一個內存塊,它由操做系統分配,並只能由操做系統內核訪問,這個內存塊是一個數據結構,其成員維護着與對象相關的信息。少數成員(安全描述符和使用計數等)是全部對象都有的,但其餘大多數成員都是不一樣類型的對象特有的。例如,進程對象有一個ID,一個基本的優先級和一個退出代碼;而文件對象有一個字節偏移量(byte offset)、一個共享模式和一個打開模式。app

      因爲內核對象的數據結構只能被操做系統訪問,故應用程序不能在內存中定位這些數據結構並更改其內容;函數

     當調用一個能夠建立內核對象的函數後,該函數會返回一個用於標識該對象的句柄。若是將該句柄值傳遞給另外一個進程中的一個線程,那麼這另外一個進程使用你的進程的句柄值所做的調用就會失敗。若是想在多個進程中共享內核對象,要經過必定的機制(如對象句柄的繼承性,命名對象,複製對象句柄)。學習

   

      下圖所示是一個能夠查看一個包含全部內核對象類型的列表的軟件(WinObj)界面。有興趣的能夠下載學習一下,加深一下對內核對象的認識。字體

      image

內核對象的安全性:內核對象能夠用一個安全描述符(security descriptor,SD)來保護。用於建立內核對象的全部函數幾乎都指向一個SECURITY_ATTRIBUTES結構的指針做爲參數:以下面的操作系統

                                                CreateFileMapping(線程

                                                                              HHANDLE hFile,

                                                                              PSECURITY_ATTRIBUTES  psa,

                                                                              DWORD flProtect,

                                                                              DWORD dwMaximumSizeHigh,  

                                                                              DWORD dwMaximumSiizelow,

                                                                              PCTSTR pszName              

                                                                           );

大多數應用程序只是爲這個參數傳入NULL,這樣建立的內核對象具備默認的安全性----具體包括哪些默認的安全性,要取決於當前進程的安全令牌(security token)。可是也能夠分配一個SECURITY_ATTRIBUTES結構,並對它進行初始化,再將它的地址傳給這個參數。SECURITY_ATTRIBUTES結構體以下所示:

                                                typedef struct   _SECURITY_ATTRIBUTES {

                                                                              DWORD nLength;

                                                                              LPVOID lpSecurityDescriptor;

                                                                              BOOL  bInheritHandle;

                                                                              } SECURITY_ATTRIBUTES;

雖然這個結構稱爲SECURITY_ATTRIBUTES,但它實際上只包含一個和安全性有關的成員,即lpSecurityDescriptor。若是相對建立的內核對象加以訪問限制,就必須建立一個安全描述符,而後按下面所示初始化其結構:

                                                                             SECURITY_ATTRIBUTES  sa;

                                                                             sa.nLength = sizeof(sa);

                                                                             sa.lpSecrityDeccriptor = pSD;

                                                                             sa.bInheritHandle = FALSE;

                                                                             HANDLE hFileMApping = CreateFileMapping(INVALID_HANDLE_VALUE,

                                                                                                                                         &sa,

                                                                                                                                         P0AGE_READWRITE,

                                                                                                                                         0,

                                                                                                                                         1024,

                                                                                                                                         TEXT(「MyFileMapping」));

若想訪問一個現有的文件映射對象,以便從中讀取數據,能夠以下下述方式調用:

                                                                             HANDLE hFileMapping = OpenFileMapping(

                                                                                                                                         FILE_MAP_READ,FALSE,

                                                                                                                                         FALSE,

                                                                                                                                         TEXT(「MyFileMapping」));

若想判斷一個對象是否是內核對象,最簡單的方式是查看建立這個對象的函數。幾乎全部建立內核對象的函數都有一個指定安全屬性信息的參數,就像上述的CreateFileMapping函數同樣。相反,用於建立用戶對象或GDI對象的函數都沒有PSECURITY_ATTRIBUTES參數。以下所示的CreateIcon函數

                                                                       HICON CreateIcon(

                                                                                                             HINSTANCE  hinst,

                                                                                                             int  nWidth,

                                                                                                             int nHight,

                                                                                                             BYTE cPlanes,

                                                                                                             BYTE cBitsPixel,

                                                                                                             CONST BYTE *pbANDbits,

                                                                                                             CONST BYTE *pbXORbits);

ps:像菜單、窗口、鼠標光標、畫刷和字體這樣的對象屬於用戶對象或GDI(Graphical Device  Interface)對象。 

       部分建立內核對象的函數:

                                                               HANDLE CraeateThread (

                                                                                                              PSECURITY_ATTRIBUTES  psa,

                                                                                                              size_t  dwStackSize,

                                                                                                              LPTHREAD_START_ROUTINE pfnstartAddress,

                                                                                                              PVOID pvParam,

                                                                                                              DWORD dwCreatinFlags,

                                                                                                              PDWORD pdwThread );

                                                                 HANDLE CraeateFile    (

                                                                                                              PCTSTR pszFileName

                                                                                                              DWORD  dwDesiredAccess,

                                                                                                              DWORD  dwShareMode,

                                                                                                              PSECURITY_ATTRIBUTES  psa,

                                                                                                              DWORD   daCreationDisposition,

                                                                                                              DWORD   dwFlagsAndAttributes,

                                                                                                              HANDLE   hTemplateFile );

                                                           HANDLE CreateSemaphore (

                                                                                                              PSECURITY_ATTRIBUTES  psa,

                                                                                                              LONG lInitialCount,

                                                                                                              LONG lMaxiumumCount,

                                                                                                              PCTSTR pszName);

                                                           ……

結束內核對象,需調用:BOOL CloseHandle(HANDLE  hobject);

相關文章
相關標籤/搜索