Windows内核--系统调用参数验证(5.1)

news2024/11/20 10:46:22

内核参数验证的重要性

        内核模式之所以有别于用户模式,在于内核模式应该是安全、可信的。用户系统调用可以传入各式各样的参数,可能是代码无意写错或因不预期的内存覆盖"暗地修改"参数,也可能是Hack有意传入,内核都应当妥善处理,避免内核读写到不预期的地址,造成内核被破解或不稳定。

NtCreateProcessEx

NTSTATUS
NtCreateProcessEx(
    __out PHANDLE ProcessHandle,
    __in ACCESS_MASK DesiredAccess,
    __in_opt POBJECT_ATTRIBUTES ObjectAttributes,
    __in HANDLE ParentProcess,
    __in ULONG Flags,
    __in_opt HANDLE SectionHandle,
    __in_opt HANDLE DebugPort,
    __in_opt HANDLE ExceptionPort,
    __in ULONG JobMemberLevel
    )
{
    NTSTATUS Status;

    PAGED_CODE(); /* 判断是否在可访问分页内存的IRQL */

    if (KeGetPreviousMode() != KernelMode) {

        //
        // Probe all arguments
        //

        try {
            ProbeForWriteHandle (ProcessHandle); /* 检查handle是否可写 */
        } except (EXCEPTION_EXECUTE_HANDLER) {
            return GetExceptionCode ();
        }
    }

    if (ARGUMENT_PRESENT (ParentProcess)) {  /* 判断父进程handle是否存在 */
        Status = PspCreateProcess (ProcessHandle,
                                   DesiredAccess,
                                   ObjectAttributes,
                                   ParentProcess,
                                   Flags,
                                   SectionHandle,
                                   DebugPort,
                                   ExceptionPort,
                                   JobMemberLevel);
    } else {
        Status = STATUS_INVALID_PARAMETER;
    }

    return Status;
}
  • NtCreateProcessEx默认是创建用户模式进程,必须有父进程。
  • PsCreateSystemProcess才可创建系统进程,默认父进程handle为PspInitialSystemProcessHandle.

ProbeForWriteHandle

FORCEINLINE
VOID
ProbeForWriteHandle (
    IN PHANDLE Address
    )
{

    if (Address >= (HANDLE * const)MM_USER_PROBE_ADDRESS) {
        Address = (HANDLE * const)MM_USER_PROBE_ADDRESS;
    }

    *((volatile HANDLE *)Address) = *Address;
    return;
}

        比较有意思的是,先判断地址是否越过默认的MM_USER_PROBE_ADDRESS,如果超过,说明在内核空间,不能向内核空间随便写数据测试权限,先把地址改成MM_USER_PROBE_ADDRESS做读写确认。

        这种情况,似乎检查了个寂寞。

        在PspCreateProcess结尾有如下这段code再次确认写ProcessHandle是否有异常:

                

                 try/except处理异常的方式是NOTHING! 这个应该是不恰当的处理方式。

ProbeForWrite

VOID
ProbeForWrite (
    __inout_bcount(Length) PVOID Address,
    __in SIZE_T Length,
    __in ULONG Alignment)
{

    ULONG_PTR EndAddress;
    ULONG_PTR StartAddress;

#define PageSize PAGE_SIZE
    if (Length != 0) { /* Length如果是0, 就不用检查了! */

        //
        // If the structure is not properly aligned, then raise a data
        // misalignment exception.
        //
        /* Alignment必须是1/2/4/8/16之一 */
        ASSERT((Alignment == 1) || (Alignment == 2) ||
               (Alignment == 4) || (Alignment == 8) ||
               (Alignment == 16));

        StartAddress = (ULONG_PTR)Address;
        if ((StartAddress & (Alignment - 1)) == 0) {
            //
            // Compute the ending address of the structure and probe for
            // write accessibility.
            //
            EndAddress = StartAddress + Length - 1;
            if ((StartAddress <= EndAddress) &&
                (EndAddress < MM_USER_PROBE_ADDRESS)) {
                EndAddress = (EndAddress & ~(PageSize - 1)) + PageSize;
                do {
                    *(volatile CHAR *)StartAddress = *(volatile CHAR *)StartAddress;
                    StartAddress = (StartAddress & ~(PageSize - 1)) + PageSize;
                } while (StartAddress != EndAddress);

                return;

            } else { /* 地址范围不在用户空间可探测区域,抛出访问异常 */
                ExRaiseAccessViolation();
            }

        } else { /* 起始地址未对齐, 抛出未对齐异常 */
            ExRaiseDatatypeMisalignment();
        }
    }
    return;
}
  •  官方介绍: ProbeForWrite. 

  • ProbeForWrite例程检查的是用户模式缓冲区权限是否正确:是否可写且正确对齐。

  • 内核和驱动对于用户模式参数必须用ProbeFor*系列函数确保权限正确,而且是任何需要访问用户模式参数的位置。这是因为调用者可能之后用另一个线程修改参数,导致之前的检测不能挡住所有可能的非法访问。

Drivers must call ProbeForWrite inside a try/except block. If the routine raises an exception, the driver should complete the IRP with the appropriate error. Note that subsequent accesses by the driver to the user-mode buffer must also be encapsulated within a try/except block: a malicious application could have another thread deleting, substituting, or changing the protection of user address ranges at any time (even after or during a call to ProbeForRead or ProbeForWrite). For more information, see Handling Exceptions.

核心代码

if ((StartAddress & (Alignment - 1)) == 0) { /* 起始地址对齐 */
            //
            // Compute the ending address of the structure and probe for
            // write accessibility.
            //
            EndAddress = StartAddress + Length - 1;
            if ((StartAddress <= EndAddress) && /* 起始地址肯定要小于结束地址 */

                /* 地址不能超过用户空间可Probe范围*/
                (EndAddress < MM_USER_PROBE_ADDRESS)) {
                EndAddress = (EndAddress & ~(PageSize - 1)) + PageSize;
                do {

                    /* 每次只读写StartAddr第一个字节确认即可, 因为是分页为单位管理! */
                    *(volatile CHAR *)StartAddress = *(volatile CHAR *)StartAddress;

                    /* 以PageSize为单位, 每个PageSize只读写首字节即可确认! */
                    StartAddress = (StartAddress & ~(PageSize - 1)) + PageSize;
                } while (StartAddress != EndAddress);

                return;

            } 

}

核心在于MM_USER_PROBE_ADDRESS.

MM_USER_PROBE_ADDRESS

        

         内存管理模块初始化会设置初始值。

                

/* Amd64 */
#define MI_HIGHEST_USER_ADDRESS (PVOID) (ULONG_PTR)((0x80000000000 - 0x10000 - 1)) // highest user address
#define MI_SYSTEM_RANGE_START (PVOID)(0xFFFF080000000000) // start of system space
#define MI_USER_PROBE_ADDRESS ((ULONG_PTR)(0x80000000000UI64 - 0x10000)) // starting address of guard page
/* x86 */
#define KSEG0_BASE 0x80000000
  •  64位系统,赋值为系统空间0xFFFF080000000000向下64KB.
  •  32位系统,赋值为系统空间0x8000 0000向下64KB.

        当然,用户空间也不能访问用于Probe的区域, 上图可以看到:MmHighestUserAddress被赋值为MI_USER_PROBE_ADDRESS - 1.

ARGUMENT_PRESENT

//
// Determine if an argument is present by testing the value of the pointer
// to the argument value.
//

#define ARGUMENT_PRESENT(ArgumentPointer)    (\
    (CHAR *)((ULONG_PTR)(ArgumentPointer)) != (CHAR *)(NULL) )

        32位和64位系统指针默认长度不一样,统一用可自定义长度的ULONG_PTR类型。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/29161.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【强化学习论文合集】ICRA-2022 强化学习论文 | 2022年合集(六)

强化学习&#xff08;Reinforcement Learning, RL&#xff09;&#xff0c;又称再励学习、评价学习或增强学习&#xff0c;是机器学习的范式和方法论之一&#xff0c;用于描述和解决智能体&#xff08;agent&#xff09;在与环境的交互过程中通过学习策略以达成回报最大化或实现…

生成者(建造者)模式

思考生成者模式 生成者模式就是将对象构建和对象内部构建分离 对象构建&#xff1a;手机的构建 对象内部构建&#xff1a;手机中屏幕和电池的构建 1.生成者模式的本质 生成器模式的本质:分离整体对象构建算法和对象的部件构造。 构建一个复杂的对象&#xff0c;本来就有构建的过…

前端程序员辞掉朝九晚五工作成为独立开发者一年开发出6款软件的故事

一个前端程序员的梦想 作为一个程序员&#xff0c;陈明福的梦想是&#xff1a; 自主自由的工作内容和方式。在全球范围内发展个人品牌和影响力。学习技术和经验&#xff0c;成为 SaaS 软件方面的专家。对世界产生积极影响。财务自由&#xff0c;能提前退休。 他的故事 1、他…

JS 根据某个字段进行排序或分组

JS 数组中根据某个字段进行排序 const arr [ { name: "崔喻琪", age: 32 }, { name: " 王忱景", age: 18 }, { name: " 房真睿", age: 27 }, { name: "姬泉孝", age: 20 }, { name: "余嘉芳", age: 16 }, { na…

Deep Few-Shot Learning for Hyperspectral Image Classification-浅读

这里写目录标题Deep Few-Shot Learning for Hyperspectral Image ClassificationIntroductionMethodExperimentDeep Few-Shot Learning for Hyperspectral Image Classification 我看的第一篇 few-shot learning 文章&#xff0c;记录一下&#xff0c;看看能不能说明few-shot …

学生家乡网页设计作品静态HTML网页—— HTML+CSS+JavaScript制作辽宁沈阳家乡主题网页源码(11页)

家乡旅游景点网页作业制作 网页代码运用了DIV盒子的使用方法&#xff0c;如盒子的嵌套、浮动、margin、border、background等属性的使用&#xff0c;外部大盒子设定居中&#xff0c;内部左中右布局&#xff0c;下方横向浮动排列&#xff0c;大学学习的前端知识点和布局方式都有…

Python绘制三维图详解

利用Python绘制三维图 目标&#xff1a; 绘制图像z2x2y2z^2 x^2 y^2z2x2y2 import matplotlib.pyplot as plt import numpy as np from mpl_toolkits.mplot3d import Axes3D #绘制3D图案画曲面的第一步是就是要创建一个二维平面的网格&#xff0c;在Python当中&#xff0c;…

设备树_基础知识

设备树 格式 /dts-v1/; // 版本号 / { // /表示根节点string-property "xxx"; // string 类型string-list-property "xxx", "yyy"; // strin…

Linux下的Framebuffer编程

文章目录前言一、LCD操作原理二、代码解析及编写程序的步骤0.定义各类参数1.打开LCD设备节点2.获取触摸屏数据3.mmap映射Framebuffer&#xff0c;在Framebuffer中写入数据三、LCD操作函数解析1.描点函数2.显示字符函数总结前言 本篇文章将会介绍Linux下的Framebuffer编程&…

html中的定位知识点如何使用

目录 系列文章目录 文章目录 前言 一、定位是什么&#xff1f;有什么用&#xff1f; 二、定位方式有哪些&#xff1f;怎么使用&#xff1f; 1、静态定位&#xff1a;就是默认的定位方式&#xff0c;意思就是没有定位; 2、相对定位&#xff1a; 3、绝对定位&…

PDF怎么转成Word?安利几个转换小技巧

平时我们工作学习的时候&#xff0c;经常要跟文件打交道&#xff0c;并且接触最多的文件形式就是PDF与Word两种文件格式&#xff0c;它们各有各的好处&#xff0c;PDF的保密性以及兼容性好&#xff0c;便于我们进行文件分享查阅&#xff0c;而Word就方便我们进行编辑。如果我们…

Ubuntu Server 22.04.1配置(配置root账号、设置固定IP、更改SSH端口、配置UFW、VM扩展磁盘后Ubuntu的扩容)

为了能快速的创建虚拟机&#xff0c;通过VM创建了一个2核CPU、4G内存、40G硬盘&#xff0c;安装Ubuntu Server 22.04.1的虚拟机&#xff0c;以便在需要的时候随时克隆一个新的虚拟机出来。 在新的虚拟机克隆出来后可能会调整硬件的配置&#xff0c;例如将40G硬盘扩展到50G&…

Python编程 字典创建

作者简介&#xff1a;一名在校计算机学生、每天分享Python的学习经验、和学习笔记。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.字典 1.字典介绍 &#xff08;了解&#xff09; 2.字典创建&#xff0…

艾美捷nickases内切酶活性检测及相关研究

艾美捷nickases内切酶组分&#xff1a; NLS-Cas9(D10A) Nickase(0.1 μg/μl) 500 μL 10Reaction Buffer 1 ml 艾美捷nickases内切酶切割活性检测&#xff1a; NLS-Cas9(D10A) Nickase(0.1 μg/μl) 500 μL 10Reaction Buffer 1 ml 经多次柱纯化&#xff0c;SDS-PAGE 胶检…

70. 爬楼梯(动态规划解法)

题目 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 示例 1&#xff1a; 输入&#xff1a;n 2 输出&#xff1a;2 解释&#xff1a;有两种方法可以爬到楼顶。 1. 1 阶 1 阶 2. 2 阶 示例 2&a…

【异常】com.alicp.jetcache.CacheException: refresh error

jetcache refresh error一、背景描述二、报错内容三、报错原因四、解决方案4.1 解决方案一&#xff0c;使用一级缓存4.2 解决方案二&#xff0c;开启写入权限一、背景描述 技术栈&#xff1a;Spring Boot(2.1.5.RELEASE) Spring Cloud Oopenfeign(2.1.1.RELEASE) jetCache(2.…

基于nodejs电商购物系统的设计与实现(论文+源码+ppt文档+视频录制)

资料下载地址&#xff1a;请点击》》》》 1 前言 2 1.1课题背景 2 1.2课题内容 3 2 需求分析 4 2.1 功能需求 4 2.2 性能需求 5 系统安全性 5 系统数据完整性 5 2.3 数据需求 6 2.4 运行环境需求 6 客户端配置 6 服务器配置 6 2.5 nodejs框架分析 6 3 系统设计 7 3.1 系统设计…

软件项目管理期中准备(自用,仅供参考)

考前拿到了样卷(#^.^#) 直接面向样卷备考 软件项目管理期中准备&#xff08;自用&#xff0c;仅供参考&#xff09;选择题计算题1.进度管理-关键路径法&#xff0c;时间压缩法2.进度管理-任务历时估计3.成本管理-COCOMO估算法4.项目的执行与控制-挣值分析法5.成本管理-专家估算…

数据库-----JDBC技术

JDBC概述 数据的持久化 持久化(persistence)&#xff1a;将内存中的数据保存到可永久保存的存储 设备中&#xff08;如磁盘&#xff09;。 持久化的主要应用是将内存中的数据存储在关系型数据库中&#xff0c;当 然也可以存储在磁盘文件、XML数据文件中。 什么是 JDBC 1、JDBC…

DIN EN ISO 4589-2塑料 用氧指数法测定燃烧行为 第2 部分:室温试验

ISO 4589-2 塑料-用氧指数法测定燃烧行为-第2部分:室温测试&#xff0d;标准名称&#xff1a; ISO 4589-2 塑料-用氧指数法测定燃烧行为-第2部分:室温测试 ISO 4589-2 Plastics-Determination of burning behaviour by oxygen index –Part 2: Ambient-temperature test ISO 4…