zoukankan      html  css  js  c++  java
  • windows核心编程学习笔记1-内核对象

    主要的内核对象
     
    §进程(Process)
    §线程(Thread)
    §作业(Job)
    §可等待定时器(Timer)
    §文件(File)
    §信标(Semphore,Event)
    §互斥对象(Mutex)
    §控制台输入(Console Input,Output)
     
     
     
     
     
    每个内核对象都只是一个内存块。它由操作系统内核分配,并只能由操作系统内核访问。这个内存块是一个数据结构,其成员维护者与对象相关的信息。少数成员(安全描述符和使用计数等)是所有对象都有的,但是其他大多数成员都是不同类型的对象特有的。
     
    通过句柄来操作内核对象
     
    句柄值是进程相关的
     
    所有内核对象都有计数成员,对象创建时为1,另一个进程对其访问时累加,进程终止时递减,当计数为0时操作系统内核就会销毁该对象
     
    安全描述符
    安全描述符描述了谁(通常是对象的创建者)拥有对象;哪些组合用户被允许访问或使用此对象;哪些组和用户被拒绝访问此对象。
    大多数应用程序只是为这个参数传入NULL,这样创建的内核对象具有默认的安全性——具体包括哪些默认的安全性,取决于当前进程的安全令牌(security token)。也可以分配一个SECURITY_ATTRIBUTES结构,并对其初始化,再传入这个参数。
     
    typedef struct _SERCURITY_ATTRIBUTES
    {
           DWORD nLength;
    /*将此值设置为该结构的大小*/
           LPVOID lpSecurityDescriptor;
    /*对该结构的 SECURITY_DESCRIPTOR 指针控制对对象的访问。 如果该成员的值是 Nothing ,对象分配默认安全说明符与调用来访问标记为已处理。这与授予对每个人的输入通过将 Nothing 自由访问 (DACL)控制列表 (acl)。在进程中访问标记的默认 DACL 只允许访问访问标记表示的用户*/
           BOOL bInheritHandle;
    /*指定的布尔值返回的句柄是否继承,在更新过程中创建。 如果此字段为 true,更新过程继承处理*/
    }SERCURITY_ATTRIBUTES;
     
    初始化
     
    SERCURITY_ATTRIBUTES sa;
    sa.nLength = sizeof(sa);
    sa.lpSecurityDescriptor = pSD;
    sa.bInheritHandle = FALSE;
    HANDLE hFileMapping = CreateFileMapping(INVALID_HANDLE_VALUE, &sa, PAGE_READWRITE, 01024, TEXT("MyFileMapping"));
     
    UAC(用户账户控制)会强制应用在一个受限的上下文运行。
     
     
     
    句柄表
    索引          内核对象内存块的指针          访问屏蔽(标志位的DWORD)          标志(标志位的DOWRD)
    1               0x????????                           0x????????                                        0x????????
    2               0x????????                           0x????????                                        0x????????
    ...
     
    进程句柄表
     
     
    内核对象的关闭
    调用CloseHandle结束使用对象‘
    如果传给CloseHandle函数的是一个无效的句柄,可能发生两种情况:如果进程是正常运行的,CloseHandle将返回FALSE,而GetLastError返回ERROR_INVALID_HANDLE。如果进程正在被调试,那么系统将抛出0xC0000008异常(“指定了无效的句柄”)。
    句柄变量作为参数,调用CloseHandle函数后还应设置为NULL。如果此时用这个变量调用一个Win32函数可能发生两种意外情况:
    1.由于变量引用的句柄表记录项已被清除,所以Windows会接受到一个无效的参数并报告错误。
    2.要函数调用时,一旦错误地用这个尚未设为NULL的变量,就可能会定位到一个错误类型的内核对象(这时会报错)。还可能会定位到一个类型(和已经关闭的内核对象)相同的内核对象(不会报错),这是应用程序的状态将损坏,没有任何办法可以恢复。
     
     
    跨进程边界共享内核对象情况:
    利用文件映射对象,可以在同一台机器上运行两个不同进程之间共享数据块。
    借助邮件槽和命名管道,在网络中的不同计算机上运行的进程可以相互发送数据库。
    互斥量、信号量和事件运行不同进程中的线程同步执行。
     
    允许进程共享内核对象的机制:
    使用对象句柄的继承、为对象命名、复制对象句柄
    • 使用对象句柄的继承
          父子进程间才能使用对象句柄继承,创建一个可继承的句柄需要父进程分配并初始化一个SECURITY_ATTRIBUTES结构,把这个结构的地址传给具体的Create函数。
    • 改变句柄的标志
          控制部分子进程能继承内核对象句柄,可以调用SetHandleInformation函数来改变内核对象句柄的继承对象标志。      
    BOOL SetHandleInformation(
        HANDLE hObject,
        DWORD dwMask,
        DWORD dwFlags);

      hObject 标识了一个有效的句柄,dwMask指出需要更改哪些标志,dwFlag指出希望将标志设为多少

          打开一个内核对象句柄的继承性
    SetHandleInformation(hObj,HANDLE_FLAG_INHERIT,HANDLE_FLAG_INHERIT);

      关闭这个标志

    SetHandleInformation(hObj,HANDLE_FLAG_INHERIT,0);
    • 为对象命名规范
         共享方式:创建为Create*函数,打开为Open*函数。
         在调用Create*函数时参数pszName用于对内核对象命名,传入NULL时创建一个匿名对象。
         对象都共享一个命名空间,无法保证当前不存在同名对象,创建一个同名而不同类型的内核对象时仅会获得ERROR_INVALID_HANDLE错误,同名且同类型时会获得ERROR_ALREADY_EXISTS。
         利用创建函数共享:A进程创建并命名对象后,B进程创建相同类型且同名对象时,会先查看是否存在同名对象,再检查其类型,都一致时会验证调用者是否拥有该对象的完全访问权限。全部检查完毕后,B进程的句柄表中分配一个      指向该对象的句柄值(引用该对象,句柄值是对B进程而言,与该对象在A进程中的句柄值并不相同)。此时B进程调用的创建函数中的参数并无作用。
         利用打开函数共享:B进程打开A进程创建的命名对象时,没有这个名称对象时返回NULL,获得2(ERROR_FILE_NOT_FOUND)。名称存在但类型不同,返回NULL,获得6(ERROR_INVALID_HANDLE)。都相同,检查请求的访问(dwDesiredAccess)是否允许。     
     
    对象句柄的继承性
    §只有当进程具有父子关系时,才能使用对象句柄的继承性
    §父进程创建子进程,为子进程赋予对父进程内核对象对象的访问权
    §内核对象句柄如果能被继承,必须在创建内核对象的时候把安全描述符的成员赋值:
    •bInherritHandle=TRUE
    §父进程创建子进程的时候CreateProcess函数的bInheritHandle参数必须指定为TRUE
    •通常把内核对象句柄作为进程启动命令行参数(CreateProcess的pszCommondLine)传递给子进程
  • 相关阅读:
    Eclipse 的SVN 插件
    linux克隆后修配置
    SVN服务器端环境搭建步骤
    Linux安装 jdk、tomcat、eclipse、mysql
    Linux RPM和YUM
    linux进程管理
    day21
    day20
    day18 作业
    day 19
  • 原文地址:https://www.cnblogs.com/fancystar/p/6368661.html
Copyright © 2011-2022 走看看