参考:《Windows内核情景分析》

0x01  ObReferenceObjectByHandle

  这个函数从句柄得到对应的内核对象,并递增其引用计数。

NTSTATUS
ObReferenceObjectByHandle(
IN HANDLE Handle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_TYPE ObjectType,IN
KPROCESSOR_MODE AccessMode,
OUT PVOID* Object,
OUT POBJECT_HANDLE_INFORMATION
HandleInformation)
{
*Object = NULL;
//若句柄是一个内核句柄或当前进程、线程的句柄
if (HandleToLong(Handle) < 0)
{
if (Handle == NtCurrentProcess())//若句柄值是当前进程的句柄(-1),特殊处理
{
if ((ObjectType == PsProcessType) || !(ObjectType))
{
CurrentProcess = PsGetCurrentProcess();
GrantedAccess = CurrentProcess->GrantedAccess;
//if内核模式/要求的权限<=进程对象支持的权限(权限检查)
if ((AccessMode == KernelMode) ||!(~GrantedAccess & DesiredAccess))
{
if (HandleInformation)
{
HandleInformation->HandleAttributes = 0;
HandleInformation->GrantedAccess = GrantedAccess;
} ObjectHeader = OBJECT_TO_OBJECT_HEADER(CurrentProcess);
InterlockedExchangeAdd(&ObjectHeader->PointerCount, 1);//递增引用计数
*Object = CurrentProcess;//返回得到的对象指针
Status = STATUS_SUCCESS;
}
Else //权限检查不通过
Status = STATUS_ACCESS_DENIED;
}
else
Status = STATUS_OBJECT_TYPE_MISMATCH;
return Status;
}
else if (Handle == NtCurrentThread())//若句柄值是当前线程的句柄(-2),特殊处理
{
if ((ObjectType == PsThreadType) || !(ObjectType))
{
CurrentThread = PsGetCurrentThread();
GrantedAccess = CurrentThread->GrantedAccess;
if ((AccessMode == KernelMode) ||!(~GrantedAccess & DesiredAccess))
{
if (HandleInformation)
{
HandleInformation->HandleAttributes = 0;
HandleInformation->GrantedAccess = GrantedAccess;
}
ObjectHeader = OBJECT_TO_OBJECT_HEADER(CurrentThread);
InterlockedExchangeAdd(&ObjectHeader->PointerCount, 1);
*Object = CurrentThread;
Status = STATUS_SUCCESS;
}
else
Status = STATUS_ACCESS_DENIED;
}
else
Status = STATUS_OBJECT_TYPE_MISMATCH;
return Status;
}
else if (AccessMode == KernelMode)//若句柄是一个内核句柄
{
Handle = ObKernelHandleToHandle(Handle);//去掉最高位的1,转为普通句柄
HandleTable = ObpKernelHandleTable;//采用内核句柄表
}
}
Else //最典型的情况,普通句柄,就使用当前进程的句柄表
HandleTable = PsGetCurrentProcess()->ObjectTable;
//以该句柄的值为“索引”,找到句柄表中对应的句柄表项
HandleEntry = ExMapHandleToPointer(HandleTable, Handle)
if (HandleEntry)//如果找到了,这就是一个有效句柄
{
ObjectHeader = ObpGetHandleObject(HandleEntry);//关键。获得该句柄指向的对应对象
if (!(ObjectType) || (ObjectType == ObjectHeader->Type))
{
GrantedAccess = HandleEntry->GrantedAccess;
if ((AccessMode == KernelMode) ||!(~GrantedAccess & DesiredAccess))//通过权限检查
{
InterlockedIncrement(&ObjectHeader->PointerCount);
Attributes = HandleEntry->ObAttributes & OBJ_HANDLE_ATTRIBUTES;
if (HandleInformation)
{
HandleInformation->HandleAttributes = Attributes;
HandleInformation->GrantedAccess = GrantedAccess;
}
*Object = &ObjectHeader->Body;//返回的是对象体的地址
return STATUS_SUCCESS;
}
Else //权限检查没通过
Status = STATUS_ACCESS_DENIED;
}
else
Status = STATUS_OBJECT_TYPE_MISMATCH;
}
Else //有可能用户给定的句柄值是一个无效句柄,在句柄表中找不到
Status = STATUS_INVALID_HANDLE;
*Object = NULL;
return Status;
}

  

两个特殊情况:

#define NtCurrentProcess()   (HANDLE)-1

#define NtCurrentThread()   (HANDLE)-2

这是两个伪句柄值,永远获得的是当前进程、线程的内核对象。

另外:若句柄值的最高位是1,则是一个内核句柄,各进程通用。内核型句柄是“System”进程的句柄表中的句柄。因此,要获得内核句柄对应的对象,系统会挂靠到“System”进程的地址空间中,去查询句柄表。

根据句柄值在句柄表中找到对应的表项是靠ExMamHandleToPointer这个函数实现的,这个函数又在内部调用ExpLookupHandleTableEntry来真正查找。句柄表组织为一个稀疏数组(目的用来节省内存),但可以

简单的看做一个一维数组,不影响理解,句柄值本身也可简单理解为一个索引。

调用方传递给驱动程序的句柄不会经过 I/O 管理器,因此 I/O 管理器不对这类句柄执行任何验证检查。决不要假设一个句柄有效;始终确保句柄拥有正确的对象类型、对于所需任务的合适的访问权、正确的访问模式,并且访问模式与请求的访问兼容。

  驱动程序应该谨慎使用句柄,特别是那些从用户模式应用程序接收到的句柄。
  第一,这种句柄特定于进程上下文,因此它们仅在打开句柄的进程中有效。当从不同的进程上下文或工作线程使用时,句柄可以引用不同的对象或者只是变得无效。
  第二,在驱动程序使用句柄期间,攻击者可以关闭和重新打开句柄来改变其引用的内容。
  第三,攻击者可以传入这样一个句柄来引诱驱动程序执行对于应用程序非法的操作,例如调用 ZwXxx 函数。对于这些函数的内核模式调用方,访问检查被跳过,因此攻击者可以使用这种机制绕过验证。

  驱动程序还应该确保用户模式应用程序不能误用驱动程序创建的句柄。为一个句柄设置 OBJ_KERNEL_HANDLE 属性使其成为内核句柄,内核句柄可以在任何进程上下文中使用,但是只能从内核模式进行访问(对于传递给ZwXxx 例程的句柄,这特别重要)。用户模式的进程不能访问、关闭或替换内核句柄。

几个常用内核函数(《Windows内核情景分析》)的更多相关文章

  1. Linux 内核和 Windows 内核有什么区别?

    Windows 和 Linux 可以说是我们比较常见的两款操作系统的. Windows 基本占领了电脑时代的市场,商业上取得了很大成就,但是它并不开源,所以要想接触源码得加入 Windows 的开发团 ...

  2. Windows内核原理系列01 - 基本概念

    1.Windows API Windows 应用编程接口(API)是针对WIndwos操作系统用户模式的系统编程接口,包含在WindwosSDK中. 2.关于.NET .NET由一个被称为FCL的类库 ...

  3. windows内核基础与异常处理

    前两日碰到了用异常处理来做加密的re题目 所以系统学习一下windows内核相关 windows内核基础 权限级别 内核层:R0 零环 核心态工作区域 大多数驱动程序 应用层:R3 用户态工作区域 只 ...

  4. windows内核情景分析之—— KeRaiseIrql函数与KeLowerIrql()函数

    windows内核情景分析之—— KeRaiseIrql函数与KeLowerIrql()函数 1.KeRaiseIrql函数 这个 KeRaiseIrql() 只是简单地调用 hal 模块的 KfRa ...

  5. windows内核编程之常用数据结构

    1.返回状态 绝大部分的内核api返回值都是一个返回状态,也就是一个错误代码.这个类型为NTSTATUS.我们自己写的函数也大部分这样做. NTSTATUS MyFunction() { NTSTAT ...

  6. [4]Windows内核情景分析---内核对象

    写过Windows应用程序的朋友都常常听说"内核对象"."句柄"等术语却无从得知他们的内核实现到底是怎样的, 本篇文章就揭开这些技术的神秘面纱. 常见的内核对象 ...

  7. [1]windows 内核情景分析---说明

    本文说明:这一系列文章(笔记)是在看雪里面下载word文档,现转帖出来,希望更多的人能看到并分享,感谢原作者的分享精神. 说明 本文结合<Windows内核情景分析>(毛德操著).< ...

  8. Windows内核-7-IRP和派遣函数

    Windows内核-7-IRP和派遣函数 IRP以及派遣函数是Windows中非常重要的概念.IRP 是I/O Request Pocket的简称,意思是I/O操作的请求包,Windows中所有Use ...

  9. Windows 驱动发展基金会(九)内核函数

    Windows 驱动发展基金会系列,转载请注明出处:http://blog.csdn.net/ikerpeng/article/details/38849861 这里主要介绍3类Windows的内核函 ...

随机推荐

  1. 虚拟现实外包—动点飞扬软件专门承接VR/AR场景、游戏、项目外包

    VR外包AR外包公司(虚拟现实外包公司)承接虚拟现实项目开发(企业.教育.游戏.企业大数据展示等) 有VR/AR.Unity3D项目.游戏外包业务欢迎 联系我们 QQ:372900288 TEL:13 ...

  2. OpenGL.Tutorial15_Lightmaps

    ZC:撤销 & 重做 — Blender Manual.html(https://docs.blender.org/manual/zh-hans/dev/interface/undo_redo ...

  3. Qt5OpenGL.顶点像素大小设置

    1. 2. // ZC: 像素点的大小 设置:2种方式: // ZC: (1)代码指定方式 // ZC: (2)GLSL种指定方式[A]只能在顶点着色器种指定,不能在片原着色器种指定[B]代码中还要指 ...

  4. Eclipse下运行maven项目失败且Tomcat服务器也启动不了

    今天遇到一个神奇的问题,在eclipse中创建一个maven项目后,Run on server 时说服务器启动失败.我以为是Eclipse配置tomcat的问题.找了一大堆没找到想要的答案!!! 我还 ...

  5. Cocos Creator学习三:生命周期回调函数

    1.目的:学习生命周期回调函数以及回调顺序,更有利于我们逻辑的处理把控. 2.生命周期回调函数: 节点:指cc.Node:组件:指cc.Component. ①onLoad:脚本组件绑定的节点所在场景 ...

  6. vue中使用动画vue-particles

    1.下载依赖 npm install vue-particles --save-dev 2.main.js引入 import Vue from 'vue' import VueParticles fr ...

  7. LINUX内核PCI扫描过程

    LINUX内核PCI扫描过程 内核版本 3.10.103 1. ACPI热插拔扫描subsys_initcall(acpi_init)@drivers/acpi/bus.c |-acpi_scan_i ...

  8. D - Mayor's posters(线段树+离散化)

    题目: The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campai ...

  9. CodeIgniter框架解析

    转载于:https://www.cnblogs.com/xiaoxiaoqingyi/p/6901654.html 转载仅为以后自己学习. 业余花了点时间看看CodeIgniter框架(简称CI),C ...

  10. 强力推荐!那些你不能错过的 GitHub 插件和工具

    以代码托管平台起家的 GitHub 网站,已然成为全球程序员工作和生活中不可或缺的一份子.从优秀的企业,到优秀的程序员,都将自己最优秀的代码作品存放在这片开源净土里,供彼此学习交流.\\LS--201 ...