zoukankan      html  css  js  c++  java
  • 第3章 内核对象(1)

    3.1 何为内核对象

    3.1.1 Windows平台上的3大对象

    (1)分类

    对象

    描述

    备注

    GUI对象

    也叫用户对象,一般是单线程访问,属于线程级的对象,如

    加速键表(HACCEL)、插入记号(Caret)、光标(HCURSOR)、桌面(HDESK)、

    钩子(HHOOK)、图标(HICON)、菜单(HMENU)、窗口(HWND)、窗口栈(HWINSTA)

    句柄值是系统唯一的,即一个进程可以通过该句柄值对另一个进程中的对象进行操作,如发送消息。

    GDI对象

    如DC、Pen、Font等,一般是单线程访问,属于线程级的对象

    句柄值只在进程内有效

    内核对象

    如进程、线程、文件等,一般允许多进程、多线程访问,因为内核对象有严格的安全机制及多线程访问控制策略,属系统级的对象。

    句柄值是表示该内核对象在句柄表里的一个索引(注意,只是个索引值),该句柄值是与进程相关的,同一个对象在不同进程中可能有不同的索引

    (2)内核对象——所有者为操作系统内核,而非进程

    内核对象

    对象名称

    句柄

    类型

    创建函数

    销毁函数

    Access token

    访问令牌

    HANDLE

    CreateRestrictedToken, DuplicateToken(Ex),

    OpenProcessToken,

    OpenThreadToken

    CloseHandle

    Change notification

    文件、目录变更通知

    HANDLE

    FindFirstChangeNotification

    FindCloseChangeNotification

    Communications

    device

    串口通信

    HANDLE

    CreateFile

    CloseHandle

    Console input

    控制台输入

    HANDLE

    CreateFile,with CONIN$

    CloseHandle

    Console screen

    buffer

    控制台输出

    HANDLE

    CreateFile,with CONOUT$

    CloseHandle

    Desktop

    桌面

    HDESK

    GetThreadDestop

    应用程序无法删除该对象

    Event

    事件

    HANDLE

    CreateEvent, CreateEventEx, OpenEvent

    CloseHandle

    Event log

    事件日志

    HANDLE

    OpenEventLog, RegisterEventSource, OpenBackupEventLog

    CloseEventLog

    File

    文件

    HANDLE

    CreateFile

    CloseHandle, DeleteFile

    File mapping

    文件映射

    HANDLE

    CreateFileMapping, OpenFileMapping

    CloseHandle

    Find file

    文件查找

    HANDLE

    FindFirstFile

    FindClose

    Heap

    HANDLE

    HeapCreate

    HeapDestroy

    I/O completion port

    完成端口

    HANDLE

    CreateIoCompletionPort

    CloseHandle

    Job

    作业

    HANDLE

    CreateJobObject

    CloseHandle

    Mailslot

    邮槽

    HANDLE

    CreateMailslot

    CloseHandle

    Memory resource notification

    内存资源通知

    HANDLE

    CreateMemoryResourceNotification

    CloseHandle

    Module

    模块

    HMODULE

    LoadLibrary, GetModuleHandle

    FreeLibrary

    Mutex

    互斥

    HANDLE

    CreateMutex, CreateMutexEx, OpenMutex

    CloseHandle

    Pipe

    管道(命名、匿名)

    HANDLE

    CreateNamedPipe, CreatePipe

    CloseHandle, DisconnectNamedPipe

    Process

    进程

    HANDLE

    CreateProcess, OpenProcess, GetCurrentProcess

    CloseHandle, TerminateProcess

    Semaphore

    信标量

    HANDLE

    CreateSemaphore, CreateSemaphoreEx, OpenSemaphore

    CloseHandle

    Socket

    套接字

    SOCKET

    socket, accept,WSASocket

    closesocket

    Thread

    线程

    HANDLE

    CreateThread, CreateRemoteThread, GetCurrentThread

    CloseHandle, TerminateThread

    Timer

    计时器

    HANDLE

    CreateWaitableTimer, CreateWaitableTimerEx, OpenWaitableTimer

    CloseHandle

    Update resource

    更新资源

    HANDLE

    BeginUpdateResource

    EndUpdateResource

    Window station

    窗口栈

    HWINSTA

    GetProcessWindowStation,CreateWindowStation

    CloseWindowStation

    3.1.2 内核对象的安全性

    (1)安全描述符SD(SECURITY_DESCRIPTOR)

    字段

    描述

    UCHAR  Revision

    UCHAR  Sbz1

    SECURITY_DESCRIPTOR_CONTROL

     Control;

    一个控制位集合,说明安全描述符的含义或它每个成员

    PSID  Owner

    拥有者的安全ID

    PSID  Group

    基本组对象SID

    PACL  Sacl

    系统访问控制链表,当一个进程常识访问一个安全对象的时候,系统检查对象的 DACL 中的访问控制实体来决定是否赋予访问权限。

    PACL  Dacl

    DACL指定特殊用户或组的允许或拒绝的访问权限

    ★程序不需要直接操作安全描述符的内容。Windows API提供设置和返回安全描述符号的函数。另外,有用来创建和初始化一个新对象安全描述符号的函数。

    (2)SECURITY_ATTRIBUTES结构体——创建内核对象几乎都要传此参数。

    字段

    描述

    LPVOID nLength

    结构体大小

    lpSecurityDescriptor

    指向安全描述符SD的指针

    BOOL bInheritHandle;

    是否继承父进程可继承的对象句柄

    3.2 进程内核对象句柄表

    3.2.1 进程句柄表(Handle Table)的结构

    (1)进程句柄表仅供内核对象使用,不适用于用户对象或GDI对象

    (2)进程初始化时,句柄表为空,当创建一个内核对象时,加入句柄表的记录项。

    (3)进程句柄表的结构

    索引

    指向内核对象内存块的指针

    访问掩码(包含标志位的DWORD)

    标志

    1

    0x????????

    0x????????

    0x????????

    2

    0x????????

    0x????????

    0x????????

    ……

    ……

    ……

    ……

    3.2.2 创建一个内核对象

    (1)创建内核对象的函数:如CreateThread、CreateFile、CreateSemaphore等。(在32位系统中,内核对象的内容被保存在0x80000000至0xFFFFFFFF的这个内核地址空间中)

    (2)返回值,是个句柄,表示该内核对象的在句柄表中的索引。(注意因句柄表可能会分层,所以该句柄最后两位(共32位)表示该对象在句柄表中所在的层数,因此如果要得到实际的索引值,必将该句柄值右移2位,见《Windows内核原理与实现·潘爱民》,p131图3.4)

    (3)创建失败时,返回0(NULL),这也是句柄表中第1个内核对象的索引值为1,而为是0的原因。(注意句柄值是实际的索引值的4倍,所以第1个对象的返回的句柄值是4)。但有些函数的返回值是-1(INVALID_HANDLE_VALUE),如CreateFile,使用时请参考MSDN说明。

    (4)调用一个内核对象时,在该函数内部会查找进程的句柄表,获得目标内核对象地址来操作对象的数据结构,如果传入的是一人无效句柄,调用失败。GetLastError将返回ERROR_INVALID_HANDLE。

    3.2.3 关闭内核对象

    (1)CloseHandle内部发生的事情

      ①首先检查进程的句柄表,验证传进来的函数该句柄的访问权限

    ②如果句柄有效,获得该内核对象的内存地址,并将该内核对象的“使用计数”减1

    ③如果计数变为0,将内核对象销毁。

    (2)返回值:

    成功

    TRUE

    失败

    当进程是正常运行的,返回FALSE;

    当进程正在被调试,返回EEEOR_INVALID_HANDLE,便于调试错误。

    (3)CloseHandle的几点说明

      ①内核对象的生命期可能长于进程的生命期。CloseHandle只是表明这个句柄不再使用了,但内核对象并不一定被销毁(可能被其他线程引用)。无论内核对象是否被销毁,都不要再试图用这个值。当 CloseHanle后,一般要将该值设为NULL。

    ②如果不小心再次使用这个句柄值来调用内核对象,则将可能发生如下意外情况:

      A、当句柄表中的记录项己被完全删除时,会收到一个无效参数的错误报告。

    B、当句柄表中的记录项被删除后,该项被新加入的内核对象重新填补,如果新内核对象与旧的内核对象类型不同,则会定位到该对象,但会报错。如果类型相同,这里并不会报错,但应用程序可能出现难于预料的结果,甚至应用程序状态被损坏,而无法恢复。

    C、如果该记录未被删除(即,使用计数不为0,说明有其他线程调用),则会继续定位到该对象,但这很不安全。因为我们己经调用CloseHanle了,所以该对象不再受我们的控制,它将在什么时候被销毁,我们并不知道。这时如果这时另一线程也调用CloseHandle,则会出现内核对象被销毁,我们就会引用了一个被销毁的对象,导致程序出错。

    ④如果忘记调用CloseHandle,在进程运行期间会导致内存泄漏,但程序结束后,该对象仍会被系统正确清除

  • 相关阅读:
    《ECMAScript6入门》___阮一峰 笔记
    JS的常用正则表达式 验证密码(转载自用)
    微信小程序 写一个获取验证码 及setInterval 使用基本方法
    python中将图片从客户端(client)推到(POST)到服务器端(server)的方法
    用python将MSCOCO和Caltech行人检测数据集转化成VOC格式
    Tensorflow物体检测(Object Detection)API的使用
    opencv获取IP摄像头(IP-camera)实时视频流
    利用flask将opencv实时视频流输出到浏览器
    Tensorflow同时加载使用多个模型
    opencv在同一窗口打印多张图片
  • 原文地址:https://www.cnblogs.com/5iedu/p/4649809.html
Copyright © 2011-2022 走看看