Windows内核之内核对象

1内核对象定义:

1.1:每个内 核对象只是内核分配的一个内存块,并且只能由该内核访问。

1.2:该内存块是一种数据结构,它的成员负责维护该对象的各种信息。

有些数据成员(如安全性描述符、使用计数等)在所有对象类型中是相同的,但大多数数据成员属于特定的对象类型。例如,进程对象有一个进程ID 、一个基 本优先级和一个退出代码,而文件对象则拥有一个字节位移、一个共享模式和一个打开模式。

2内核对象种类:

比如存取符号对象、 事件对象、文件对象、文件映射对象、I / O 完成端口对象、作业对象、信箱对象、互斥对象、管道对象、进程对象、信标对象、线程对象和等待计 时器对象等。

3内核对象拥有者:

内核对象由内核所拥有,而不是由进程所拥有。如果你的进程调用了一个创建内核对象的函数,然后你的进程终止运行,那么内核对象不 一定被撤消。在大多数情况下,对象将被撤消,但是如果另一个进程正在使用你的进程创建的内核对象,那么该内核知道,在另一个进程停止使用该 对象前不要撤消该对象,必须记住的是,内核对象的存在时间可以比创建该对象的进程长。

4内核对象使用计数:

内核对象悲哀创建时候,计数设置为1,当有进程访问该内核对象的时候,计数加1,当进程终止运行的时候,内核会判断该对象技术是否为0,是0的话就撤销该内核对象。

5进程对象内核句柄表:

当一个进程被初始化时,系统要为它分配一个句柄表。该句柄表只用于内核对象,不用于用户对象或G D I 对象。

当进程初次被初始化时,它的句柄表是空的。然后,当进程中的线程调用创建内核对象的函数时,比如Cr e a t e F i l e M a p p i n g ,内核 就为该对象分配一个内存块,并对它初始化。

用于创建内核对象的所有函数均返回与进程相关的句柄,这些句柄可以被在相同进程中运行的任何或所有线程成功地加以使用。

6内核对象的关闭和撤销的区别:

内核对象的关闭是指一个进程利用CloseHandle(Handle hObj)函数把内核对象在该进程中的句柄表中清除掉,因而该进程不能再访问该内核对象。

内核对象的撤销试着内核把内核对象从内存中清除,此时的内核对象计数为0.

两者的区别:内核对象关闭是进程操作的,关闭内核对象不一定会撤销对象;撤销对象是内核操作的,当撤销对象的时候,对象一定会关闭的。

7 共享内核对象

7.1 通过对象句柄的继承性

只有当进程具有父子关系时,才能使用对象句柄的继承性。在这种情况下,父进程可以使用一个或多个内核对象句柄,并且该父进程可以决定生成一 个子进程,为子进程赋予对父进程的内核对象的访问权。

实施步骤:

7.1.1:父进程必须指定一个S E C U R I T Y _ AT T R I B U TE S 结构并对它进行初始化,然后将该结构的地址传递给特定的Cr e a t e 函数。

    SECURITY_ATTRIBUTES sa;
     sa.nLength = sizeof(sa);
     sa.lpSecuntyDescriptor = NULL;
     /Make the returned handle inheritable.
     sa.bInheritHandle =- TRUE;
     HANDLE hMutex = CreateMutex(&sa,FALSE, NULL);

7.1.2:父进程生成子进程

BOOL CreateProcess(
  PCTSTR pszApplicationName,
  PTSTR pszCommandLine,
  PSECURITY_ATTRIBUTES psaProcess,
  PSECURITY_ATTRIBUTES psaThread,
  BOOL bInheritHandles,
  DWORD fdwCreale,
  PVOIO pvEnvironment,
  PCTSTR pszCurDir,
  PSTARTUPINFO psiStartInfo,
  PPROCESS_INFORMATION ppiProcInfo);

要把bInheritHandles设置为True,表示是继承了父进程。

7.1.3子进程确定继承内核对象的方法

子进程为了确定它期望的内核对象的句柄值,最常用的方法是将句柄值作为一个命令行参数传递给子进程。

7.1.3 改变句柄标志

当父父进程想选择不同的子进程具有不同的句柄继承权的时候,可以通过设置句柄的标志来实现。通过该函数来实现设置句柄的标志

BOOL SetHandleInformation(
   HANDLE hObject,
   DWORD dwMask,    //标志位
   DWORD dwFlags);  //标识值

7.2 命名对象

7.2.1创建命名内核对象

HANDLE CreateJobObject(

PSECURITY_ATTRIBUTES psa,

PCTSTR pszName);

通过观察创建内核对象的函数,我们知道其中的最后一个参数是一个字符串,这个字符串表示内核对象的名字。当然如果我们不想给它起名字的话,我们可以设置其为NULL。该名字的长度最多可以达到MAX_PATH(定义为260 )个字符。

HANDLE hMutexPronessA = CreateMutex(NULL, FALSE,"JeffMutex");
HANDLE hMutexProcessB = CreateMutex(NULL, FALSE,"JeffMutex");

此时第一次调用该函数时候,创建一个名字为JeffMutex的内核对象,第二次调用该创建内核对象函数时候,由于待创建的内核对象的名字以及类型都一样,再加上如果权限符合的话,此时在进程B中就不会再次创建内核对象,而是引用了进程A中同名同类型的对象JeffMutex。同时内核对象的计数就会加1.

警告:如果命名的内核对象已经存在,那么再次创建该名字的内核对象的时候,将会忽略第二次创建时传递给函数的参数并且不再创建此内核对象,否则会创建一个按照第二次指定参数的新的内核对象。

7.2.2 打开命名内核对象

可以利用Open函数来打开已经有的命名内核对象,而不是去用Create***来实现。两个的区别是:当没有该内核对象的时候,Open函数会运行失败,而Create***函数则会创建一个新的内核对象。例如:

HANDLE OpenFileMapping(
   DWORD dwDesiredAccess,
   BOOL bInheritHandle,
   PCTSTR pszName);

7.3 复制进程

把进程A中的某个内核对象的句柄复制到进程B 中的句柄表中。

BOOL DuplicateHandle(
   HANDLE hSourceProcessHandle,
   HANDLE hSourceHandle,
   HANDLEhTargetProcessHandle,
   PHANDLE phTargetHandle,
   DWORD dwDesiredAccess,   //访问屏蔽值
   BOOL bInheritHandle,             //继承标志
   DWORD dwOptions);             //是否继承源进程的访问屏蔽值

复制内核对象的一个实例

从例子中可以看到同一个进程的句柄表中可以有两个句柄,它们欲访问的内核对象值相同,但是一些访问标志以及继承权限可以不同。

#include <windows.h>

DWORD CALLBACK ThreadProc(PVOID pvParam);

int main()
{
    HANDLE hMutex = CreateMutex(NULL, FALSE, NULL);
    HANDLE hMutexDup, hThread;
    DWORD dwThreadId;

    DuplicateHandle(GetCurrentProcess(),
                    hMutex,
                    GetCurrentProcess(),
                    &hMutexDup,
                    0,
                    FALSE,
                    DUPLICATE_SAME_ACCESS);

    hThread = CreateThread(NULL, 0, ThreadProc,
        (LPVOID) hMutexDup, 0, &dwThreadId);

    // Perform work here, closing the handle when finished with the
    // mutex. If the reference count is zero, the object is destroyed.
    CloseHandle(hMutex);

    // Wait for the worker thread to terminate and clean up.
    WaitForSingleObject(hThread, INFINITE);
    CloseHandle(hThread);
    return 0;
}

DWORD CALLBACK ThreadProc(PVOID pvParam)
{
    HANDLE hMutex = (HANDLE)pvParam;

    // Perform work here, closing the handle when finished with the
    // mutex. If the reference count is zero, the object is destroyed.
    CloseHandle(hMutex);
    return 0;
}

Windows内核之内核对象,布布扣,bubuko.com

时间: 2024-10-05 14:02:32

Windows内核之内核对象的相关文章

浏览器内核与BOM对象介绍

BOM(Browser Object Model)对象介绍 我们都知道js有三部分组成,ECMAScript.DOM和BOM,根据宿主(浏览器)的不同,具体的表现形式也不尽相同,ie和其它浏览器也是风格迥异. 那么BOM和DOM有什么不同呢? DOM是由W3C的制订,所有浏览器共同遵守的标准,描述了处理网页内容和方法的接口:BOM是各个浏览器厂商根据DOM实现与各自浏览器进行交互的方法和接口,表现为不同浏览器定义有差别,实现方式不同. BOM主要处理浏览器容器的框架,不过通常浏览器特定的js扩展

HUSTOJ的Windows版评判内核(限制内存使用)

HUSTOJ的Windows版评判内核(一) 作者:游蓝海 个人主页:http://blog.csdn.net/you_lan_hai 2013.4.9 注:最新版本项目地址:https://github.com/NsLib/FreeJudger.新版FreeJudger,跟我之前写的这个已经完全不一样了,之前的这个废除.虽然现在工作忙,但我们会继续开发FreeJudger,直到功能完善,详见:HUSTOJ的Windows版评判内核(二) 在线评测系统(Online Judge System,O

VirtualKD+Windbg+vmware 极速调试+Windbg下载符号+windows 7本地内核调试

================================Windbg下载符号===================================打了补丁后经常出现"Your debugger is not using the correct symbols", 使用WINDBG命令下载更新符号文件即可,以下命令不能去掉“.”,打完命令就开始下载了 流量监控可以看到 1: .sympath srv*G:\WinDDK\7600.16385.1\Debuggers\Symbols

第七章——Windows内核基础-内核理论基础(内存空间布局,Windows与内核启动过程)

1.内存空间布局 X86系统支持32位寻址,因此支持2^32=4GB的虚拟内存空间,windwos系统的内存主要分为内核空间和应用层空间 每部分占2GB,其中包括一个64KB的NULL空间以及非法区域. windows内存的逻辑地址分为两部分: 段选择符和偏移地址,CPU在进行地址翻译的时候,先通过分段机制计算出一个线性地址,在通过页表机制将线性地址映射到物理地址,再从物理内存中读取数据和指令 X64的内存布局与X86的内存布局类似,X64下存在一些空洞,并且X64的最大寻址空间为2^64KB的

Linux 内核开发 - 内核定时器

时间差的度量 系统的定时器硬件以固定的频率产生时钟中断,产生始终中断的间隔以HZ 常量来决定,通常在50~1200之间,x86默认是1000,HZ可以根据不同的内核来配置. Linux 采用jiffies (unsigned long)来对时钟中断进行计数,每当发生时钟中断时jiffies的值将+1,因此jiffies就记录了系统开机以来的时钟中断总次数.在驱动开发过程中经常会使用时钟中断来计算不同事件的时间间隔. 延迟执行 对于不精确的时间延迟要求,可以使用while 循环来计算延迟的时间.

Linux 内核开发——内核简介

内核简介 Linux 构成 Linux 为什么被划分为系统空间和内核控件 隔离核心程序和应用程序,实现对核心程序的保护,如保护操作系统本身的保护. 什么内核空间,用户空间 内核空间和用户空间是程序运行的两种不同的状态,Linux对自身软件系统进行了划分,一部分核心的软件独立于普通的软件,拥有特权级别,能够访问平台的所有硬件和资源,称为"内核空间".而普通的软件运行在"用户空间",它只拥有有限的系统资源,不能直接访问内核空间和硬件资源. 将系统分为"内核空间

在阿里云中编译Linux4.5.0内核 - Ubuntu内核编译教程

实验环境:Ubnuntu 64位(推荐使用14.04)+Xshell 阿里云现在提供的云服务器很好用的,用来编译内核性能也不错.本文介绍最基本的内核编译方法,为了方便,所有操作均在root用户下进行. 如果不是root用户可以使用su命令切换到root用户. 注:使用xshell的时候最好把这一项给关闭了(工具——选项——高级) 一.环境准备 1.准备linux源码和补丁,可以在官网(http://www.kernel.org)上下载,这里我们下载4.5版本. 不过阿里提供了http://mir

windows系统调用 利用事件对象实现进程通信

1 #include "iostream" 2 #include "windows.h" 3 #include "cstring" 4 using namespace std; 5 6 static LPCTSTR g_szContinueEvent="w2kdg.EventDemo.event.Continue"; 7 8 BOOL CreateChild(){ 9 TCHAR szFilename[MAX_PATH]; 1

Linux0.11内核剖析–内核体系结构 &#169;Fanwu

Linux0.11内核剖析–内核体系结构 ©Fanwu <Linux内核完全注释>下载:http://files.cnblogs.com/files/HanBlogs/linux-kernel.pdf(进入pdf后要点击右下角保存喔^_^) 一个完整可用的操作系统主要由 4 部分组成:硬件.操作系统内核.操作系统服务和用户应用程序,如下图所示: 用户应用程序是指那些字处理程序. Internet 浏览器程序或用户自行编制的各种应用程序: 操作系统服务程序是指那些向用户所提供的服务被看作是操作系