读书笔记----《windows核心编程》第三章 内核对象1(句柄与安全性)

最近一直没有更新博客,因为一直在想一个问题,内核对象这一章内容很多很重要,自己没有掌握好也没有把握写好这一章,最后还是决定能写多少写多少,一面写一面学,后续学到新的再更新吧;

《windows核心编程》提了几种内核对象:

访问令牌对象:与windows的安全性有关,目前不是很懂,了解后再写;

事件对象: Event对象,可跨进程同步; 由CreateEvent创建;

文件对象: File对象,比较常见; 由CreateFile创建;

文件映射对象: 通过文件映射可以方便的操作文件(如同文件数据就在内存上一样);由CreateFileMapping创建,WinObj可以看出系统创建的是Session对象;

I/O完成端口对象: 简称IOCP,经常用于套接字编程中;

作业对象: 不是很了解;

邮件槽对象: 可用于进程间同步,但很少用。目前还没有发现有其他的特殊用途;

互斥量对象: 常用于的进程同步;

管道对象: 常用于进程的数据传输,并且进程可以在不同的计算机上;

进程对象: 操作系统 利用此对象进行进程的管理工作

线程对象: 操作系统利用此对象进行线程的管理工作;

信号量对象: 常用于线程同步的内核对象,功能强大;

可等待的计时器对象:不是很了解,应该可以使用精度很高的Timer;

线程池对象: 没用过;

几乎所有的内核对象内部都有安全描述符(描述哪些成员可以访问以及何种访问权限)和使用计数(当前对象被几个成员同时使用着,如果为0,代表已没有成员使用了,该内核对象就没有存在的意义了,会自动销毁)两个成员;

使用计数:

为什么会有使用计数?

内核对象是操作系统而不是单个程序拥有的,这样的话可能就会出现多个程序使用同一个内核对象,使用计数值就表示了该内核对象被引用了多少次,当该内核对象被再次打开时计数值+1,当被Close时计数值-1,当计数值减为0时,操作系统自动销毁该内核对象;

(当进程终止时,操作系统会逐个Close掉句柄表中的所有句柄)

安全描述符:

安全描述符提供了谁拥有对象,谁可以访问对象,以何种方式访问(DACL)以及何种审查访问类型(SACL)等信息。一个用户A创建了对象ObjectA(File,Pipe等),但用户A希望用户B仅仅可以读不可以写ObjectA,这时候可以通过安全描述符完成这一需求;

安全描述符的结构体如下:

typedef struct _SECURITY_DESCRIPTOR
    {
        UCHAR Revision; //版本控制信息;
        UCHAR Sbz1;   //版本控制信息;
        SECURITY_DESCRIPTOR_CONTROL Control; //unsigned short 类型,控制位;
        PSID Owner;   // 对象的拥有者SID, 可以更改安全描述符,而不管其他人对访问的锁定。
        PSID Group;   // Windows 通常忽略此参数(这是为了 POSIX 兼容性,但它现在已经退化了)
        PACLSacl;    //指定要对对象执行的审核的类型。如果发生了审核事件,会被存储到审核事件的日志中。
        PACL Dacl;     //这儿保存着对象的许可(允许谁访问对象,而拒绝谁)。
    }SECURITY_DESCRIPTOR;

其中Dacl指向的是ACL的结构体:

typedef struct _ACL
    {
    	UCHAR AclRevision; //版本控制信息;
    	UCHAR Sbz1;      //版本控制信息;
    	USHORT AclSize;   //(Bytes)   ACL + ACEs+ Free Buffer  见winnt.h 注释;
    	USHORT AceCount; // ACE 个数 见winnt.h注释;
    	USHORT Sbz2;     //版本控制信息;
    } ACL;
typedef ACL *PACL;

我们可以看到这里有AceCount,但是没有发现AceList这个保存Ace信息的字段,我猜测Ace字段也保存到了这个结构体中只不过没有进行命名不让用户程序去索引,实现手段类似于char acelist[0],这些仅仅是猜测,如果想知道的话,可以跟踪GetAce或者AddAce的汇编代码就知道了;

ACE(访问控制项)需要关注的三个字段是AceType,Mask和SID,AceType包括allow(允许)/deny(拒绝)/audit(审计)/ alarm(警告);Mask表示允许或者拒绝的行为组合;SID表示关联的SID;

关于Token:

看完《深入解析windows操作系统》后再加;

当打开一个对象时,会从线程所拥有的令牌中(如果存在模仿令牌则使用模仿令牌,否则使用主令牌)获取用户名和用户所在组列表,与对象的安全描述符中的DACL比较,这个时候会发生如下情况之一:

1. 对象的DACL==Null,则线程拥有完全的访问权限。

2. 对象的DACL不为Null,但是AceCount==0(ACE,访问控制项),则拒绝任何线程访问。

3. 遍历DACL,找到跟令牌中用户或组一致的Ace,如果该Ace指明没有拥有制定的访问权限,则直接退出安全检查函数,并拒绝该线程访问。

4. 遍历DACL,没找到跟令牌中用户或组一致的Ace,并拒绝该线程访问。

5. 遍历DACL,找到跟令牌中用户或组一致的Ace,如果该Ace指明拥有制定的访问权限,则直接退出安全检查函数,并允许该线程访问。

安全描述符以及其他安全性的文章可参考:

http://blog.csdn.net/hjxyshell/article/details/38502933

http://blog.csdn.net/hjxyshell/article/details/38503387

http://www.doc88.com/p-382740626684.html

《深入解析windows操作系统》第八章

内核对象是由操作系统创建、访问、修改、销毁的内存块并且只能由内核访问,用户程序不应该去猜测内存块的内容进行访问和更改,用户程序如果想操作内核对象的话,应该使用Windows提供的一组函数;当用户程序调用函数创建(由内核执行创建的操作)或者打开一个内核对象时,函数会返回一个句柄值(handle),这个句柄标识了该内核对象,将该句柄传给对应函数可对内核对象进行操作; 32位程序下sizeof(handle) = 4; 64为程序下 sizeof(handle) = 64;

Notice:

1. handle是与进程相关的,所以句柄值只能在同一进程内使用,不能把该值传给另一进程使用访问,如果需要多进程共同访问同一内核对象,后面会介绍多个方法

2. handle的真实含义是handle/4 = handle对应内核对象在该进程句柄表的索引值,也证明1。但是句柄的含义并没有在windows的文档中公开,所以将来也有可能发生变化

时间: 2024-10-11 13:38:13

读书笔记----《windows核心编程》第三章 内核对象1(句柄与安全性)的相关文章

windows核心编程第三章

3.1.1  内核对象的使用计数 内核对象由内核所拥有,而不是由进程所拥有.换句话说,如果你的进程调用了一个创建内核对象的函数,然后你的进程终止运行,那么内核对象不一定被撤消.在大多数情况下,对象将被撤消,但是如果另一个进程正在使用你的进程创建的内核对象,那么该内核知道,在另一个进程停止使用该对象前不要撤消该对象,必须记住的是,内核对象的存在时间可以比创建该对象的进程长. 3.2.1 创建内核对象 如果调用一个函数创建内核对象,但是调用失败了,那么返回的句柄值通常是0(N U L L).不过有少

Windows核心编程之核心总结(第三章 内核对象)(2018.6.2)

学习目标 第三章内核对象的概念较为抽象,理解起来着实不易,我不断上网找资料和看视频,才基本理解了内核对象的概念和特性,其实整本书给我的感觉就是完整代码太少了,没有多少实践的代码对内容的实现,而且书本给的源码例子,有太多我们不知道的知识,并且这些知识对本章主要内容来说是多余的,所以我们理解起来也非常困难.为了更好的学习这章,我补充了一些辅助性内容.这一章的学习目标:1.Windows会话和安全机制2.什么是内核对象?3.使用计数和安全描述符4.内核对象句柄表5.创建内核对象6.关闭内核对象7.跨进

python核心编程-第三章-个人笔记

1.语句和语法 (1)反斜杠"\"表示语句继续.python良好的编程习惯是一行最后不超过80个字符,一行字符过多时便须用到反斜杠换行继续该语句. PS:在使用小括号.中括号.大括号时可以跨行书写,无须反斜杠:三引号的字符串也可以跨行书写 (2)分号";"可以在同一行写多个语句.虽然python支持这么做,但为了代码可读性,一般不建议这么做 2.变量赋值 (1) python中,对象是引用传递的,而不是直接将值赋给对象  如: >>> a = 12

【1】python核心编程 第三章

1.继续( \ ) 有两种例外情况一个语句不使用反斜线也可以跨行.在使用闭合操作符时,单一语句可以跨多行,例如:在含有小括号.中括号.花括号时可以多行书写.另外就是三引号包括下的字符串也可以跨行书写 2.变量赋值 赋值并不是直接将一个值赋给一个变量, 尽管你可能根据其它语言编程经验认为应该如此.在Python 语言中,对象是通过引用传递的.在赋值时,不管这个对象是新创建的,还是一个已经存在的,都是将该对象的引用(并不是值)赋值给变量. 3.关键字 # 判断是否为关键字 import keywor

python核心编程-第三章-习题

1.这是python的语言特性,python先创建对象,在给变量赋值时,不需要定义变量的名称和类型,它实际是用变量引用对象.变量类型在给变量赋值时自动声明 2.原因类似变量无须声明类型 3.python用下划线作为变量前缀和后缀指定特殊变量,对解释器有特殊意义,也是内建标识符所使用的特殊符号,故一般避免用下划线作为变量的开头和结尾 4.python一行可以书写多个语句,多个语句间用";"分隔.但是为了良好的编程风格,不推荐这么做 5.python可以将一个语句分成多行书写,行的末尾用反

读书笔记 - js高级程序设计 - 第三章 基本概念 -

启用严格模式 "use strict" 这是一个 pragma 编译指示 让编码意图更清晰  是一个重要原则 5种简单数据类型 Undefined Null Boolean Number String 1种复杂数据类型 Object 检测数据类型的方法 typeof 有如下值: undefined boolean object string number function typeof Null object 意在保存对象还没有保存对象的变量的初始值最好是什么 null 八进制的第一位

python核心编程第四章 python对象

4–1. Python 对象.与所有 Python 对象有关的三个属性是什么?请简单的描述一下.  身份,类型和值. 4–2. 类型.不可更改(immutable)指的是什么?Python 的哪些类型是可更改的 (mutable),哪些不是? 如果对象支持更新操作,那么它的值就可以改变,否则它的值也是只读的.对象的值是否 可以更改被称为对象的可改变性(mutability) 数字 Scalar 不可更改 直接访问 字符串 Scalar 不可更改 顺序访问 列表 Container 可更改 顺序访

读书笔记-----Java并发编程实战(二)对象的共享

1 public class NoVisibility{ 2 private static boolean ready; 3 private static int number; 4 private static class ReaderThread extends Thread{ 5 public void run(){ 6 while(!ready) 7 Thread.yield(); 8 System.out.println(number); 9 } 10 } 11 12 public s

Windows核心编程之核心总结(第一章 错误处理)(2018.5.26)

前沿 学习Windows核心编程是步入Windows编程殿堂的必经之路,2018年寒假重温了计算机操作系统知识,前阵子又过学习Windows程序设计方面的基础,正所谓打铁要乘热,所以我又入了Windows核心编程的坑啦,哈哈~ 学习目标 每一章的学习都要明确一个目标,就是你学完这一章之后你能做些什么?好的,我们一步步来学习第一章节错误处理.以下是这一章节的学习目标:1.了解Windows函数的错误机制2.了解GetLastError和SetLastError函数的使用3.了解FormatMess