内核对象
1.内核对象相关概念
- 内核对象只是内核分配的一个内存块,这个内存块位于操作系统的内核地址空间,因此应用程序不能直接操作内核对象,需要用系统给定的函数来操作,不同的内核对象由不同的函数窗口。。该内存块是一种数据结构,它的成员负责维护该对象的各种信息。有些数据成员(如安全性描述符、使用计数等)在所有对象类型中是相同的,但大多数数据成员属于特定的对象类型。例如,进程对象有一个进程I D 、一个基本优先级和一个退出代码,而文件对象则拥有一个字节位移、一个共享模式和一个打开模式。
- 内核对象的数据结构只能被内核访问,因此应用程序无法在内存中找到这些数据结构并直接改变它们的内容。Microsoft 规定了这个限制条件,目的是为了确保内核对象结构保持状态的一致。这个限制也使Microsoft能够在不破坏任何应用程序的情况下在这些结构中添加、 删除和修改数据成员。
- 当调用一个用于创建内核对象的函数时,该函数就返回一个用于标识该对象的句柄。为了使操作系统变得更加健壮,这些句柄值是与进程密切相关的。因此,如果将该句柄值传递给另一个进程中的一个线程,那么这另一个进程使用你的进程的句柄值所作的调用就会失败。如果想在多个进程中共享内核对象,要通过一定的机制。如对象句柄的继承性,命名对象,复制对象句柄。
- 除了内核对象外,你的应用程序也可以使用其他类型的对象,如菜单、窗口、鼠标光标、刷子和字体等。这些对象属于用户对象或图形设备接口(GDI)对象,而不是内核对象。
2.内核对象
内 核 对 象 |
进程 Process |
线程 Thread |
访问令牌 Token |
文件对象 File |
文件映射 Mapping_File |
---|---|---|---|---|---|
I/O 完成端口 Completion port |
邮槽 Mailslot |
管道 Pipe |
互斥体 Mutex |
信号量 Semaphore |
|
事件 Event |
计时器 Timer |
线程池 ThreadPool |
工作对象 Job |
3.进程内核对象列表
- 由上图可以分析出不同进程之间的句柄不可以互相引用,引用会出问题,一般进程句柄相当于进程句柄对象列表中的索引位置,所以不同进程之间不可以用。
4.内核对象相关函数
4.1创建内核对象
需要用到相关的系统API,举例
HANDLE CreateThread(
PSECURITY_ATTRIBUTES psa,
size_t dwStackSize,
LPTHREAD_START_ROUTINE pfnStartAddress,
PVOID pvParam,
DWORD dwCreationFlags,
PDWORD pdwThreadId);
4.2关闭内核对象
// hObject:代表一个已打开的对象handle
BOOL CloseHandle(HANDLE hObject);
返回值:
TRUE::代表成功
FALSE:代表失败,可以用GetLastError函数获取错误码
内核对象使用引用计数技术,可以增加和减少引用计数来确定内核对象有效和无效
4.3 设置和获取内核对象的信息
BOOL SetHandleInformation(
HANDLE hObject,
DWORD dwMask,
DWORD dwFlags);
BOOL WINAPI GetHandleInformation(
_In_ HANDLE hObject,
_Out_ LPDWORD lpdwFlags
);
4.4命名内核对象
创建内核对象的函数中,如果有pszName参数,说明这个内核对象可以被命名,可以机床及命名内核对象。命名内核对象可以在不同进程中使用。
匿名内核对象不能在进程间共享。