chapter 3: 内核对象

本文介绍了Windows操作系统中的内核对象概念,包括访问令牌、事件、文件等类型,以及如何通过句柄进行管理和控制。探讨了句柄表的工作原理,内核对象的跨进程共享方法,如对象继承、命名和复制。

1.什么是内核对象

种类:访问令牌对象、事件对象、文件对象、文件映射对象、I/O完成端口对象、作业对象、信号量对象、线程对象、

   邮件槽对象、互斥量对象、管道对象、 可等待的计时器对象、线程池工厂。

句柄来控制内核对象,内核对象由windows维护。

使用内核对象查看工具:WinObj.exe

句柄(Handle)标识了内核对象,进程相关。

内核对象的计数及销毁:和java垃圾回收系统机制类似。

内核对象的安全性:安全描述符(SD),谁创建,谁能使用,谁不能使用。

    所有创建内核对象的函数几乎都有参数指向SECURITY_ATTRIBUTES结构:NULL默认安全性。[p35] 

        IpSecurityDescriptor:安全描述符

            检查:访问内核对象时,会先告知打算进行的操作。若返回NULL,可以用getLastError。

            错误:若告知的操作为KEY_ALL_ACCESS,会导致非管理员用户不能使用。要使用正确的安全访问标志。

    区分内核对象及用户对象、GDI对象:看创建对象时是否有PSECURITY_ATTRIBUTES参数。


2.进程内核对象句柄表

句柄表:进程初始化时分配,供内核使用。

    内存块指针:指向被分配的内核对象数据结构的地址。

访问掩码:权限。

句柄值:实际值=句柄值/4,从4开始。

创建内核对象:

    1. 会增加句柄项

    相关方法:CreateThread, CreatFile, CreateFileMapping, CreateSemaphore

        返回的句柄可供进程内所有线程使用。

关闭内核对象:

    1. BOOL CloseHandle(HANDLE hobject);

    2. 先检查权限,再使“使用计数”减一

    *需要将hobject置为NULL

    *使用Process Explorer检查泄露的handles


3.跨进程共享内核对象

文件映射对象:进程间共享数据

邮件槽和命名管道:网络中进程发送数据块

互斥量信号量和事件:允许不同进程中的线程同步执行

---方法1,使用对象句柄继承---

1.父进程创建内核对象时,指出对象的句柄是可继承的(对象本身不可继承)。[p42]

    父进程分配并初始化一个SECURITY_ATTRIBUTES,传给具体的Create函数。见句柄表的标志

2.父进程生成子进程,CreateProcess

    BOOL bInheritHandles需要为TRUE

    父进程和子进程中,对一个内核对象进行标识的句柄值是一样的。

    子进程仍会将内核对象使用计数加1:子进程仍可访问被父进程关闭的内核对象

    *系统上所有进程都共享内核空间

3.子进程获得它想要的内核对象句柄值

    父进程将句柄值作为命令行参数传给子进程

    父进程等待子进程完成初始化(WaitForInputIdle),发送消息

    父进程向其环境块添加一个环境变量,子进程会继承环境变量,获得句柄值。适合反复继承。

---改变句柄标志---

控制句柄的继承标志

SetHandleInformation

可继承->不可继承

允许关闭句柄->不允许关闭句柄

获得标志:GetHandleInformation

---方法2,为对象命名---

1.通过函数创建命名的内核对象

    CreateMutex

    CreateEvent

    CreateWaitableTimer......

    参数pszName:NULL即匿名,否则命名

    *没有机制防止重名

2.共享方法

    2.1.进程A调用 CreateMutex(NULL, FALSE, TEXT("JeffMutex"));

    2.2.另一个进程B调用CreateMutex(NULL, FALSE, TEXT("JeffMutex"));(前两个参数会被忽略

    2.3.系统检查类型,检查访问权限(限制权限,可以使用ex版本的dwDesiredAccess参数),若成功,则返回Handle

*两个进程的句柄值可能不同。

*可以使用GetLastError判断CreateMutex是否创建了新的对象。

*名称不可重复,可使用GUID防止重复

    2.2.1也使用Open*函数搜索匹配对象,而不create

*利用命名对象来防止一个应用程序多开[p50]

---终端服务命名空间---

客户端会话拥有命名空间,防止名称重复导致问题

适用于远程桌面、快速用户切换、服务器

使用ProcessIdToSessionId(WinBase.h)来得知进程在那个会话中运行。

强制把命名对象放入全局命名空间:Global\ 命名前缀

强制把命名对象放入当前回话命名空间:Local\ 命名前缀

---专有命名空间---

命名对象使用自定义前缀防止命名劫持,并关联一个安全描述符,更安全的singleton程序

[p54]CheckInstaces函数

---方法3,复制对象句柄---

DuplicateHandle

催化剂进程C获得一个进程A句柄表中一个记录项,并在另一个进程B的句柄表中创建它的一个副本。


        

    


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值