windows驱动开发-内核编程技术汇总(五)
使用安全字符串函数
和应用层不一样的是,windows内核完全使用Unicode字符串,许多支持AsciiC的windowsAPI,是在应用层完成项Unicode的切换的。许多系统安全问题是由缓冲区处理不善和生成的缓冲区溢出引起的。 糟糕的缓冲区处理通常与字符串操作相关联。 C/C++ 语言运行时库 (strcat、 strcpy、 sprintf 等) 提供的标准字符串操作函数不会阻止写入缓冲区末尾。
两组新的字符串操作函数(称为安全字符串函数)提供额外的处理,以便在代码中正确处理缓冲区。 这些安全字符串函数在 Windows 驱动程序工具包 (WDK) 以及 Microsoft Windows XP SP1 及更高版本的驱动程序开发工具包 (DDK) 和 Windows SDK 中可用。 它们旨在替换其内置的 C/C++ 对应项和 Windows 提供的类似例程。
一组安全字符串函数用于内核模式代码。 这些函数在名为 Ntstrsafe.h 的头文件中原型。 WDK 中提供了此头文件和关联的库。
另一组安全字符串函数用于用户模式应用程序。 相应的头文件 Strsafe.h 包含这些函数的原型。 该文件和关联的库在 Windows SDK 中可用。
内核模式安全字符串函数集由以下两个子集组成:
- Unicode 和 ANSI 字符的安全字符串函数:其中每个函数在支持双字节 Unicode 字符的 W 后缀版本中可用,以及支持单字节 ANSI 字符的 A 后缀版本。 例如, RtlStringCbCatN 连接两个字符串并限制追加字符串的长度,可用作 RtlStringCbCatNW 和 RtlStringCbCatNA;
- 用于UNICODE_STRING结构的安全字符串函数:其中每个函数都接受 UNICODE_STRING 结构作为输入参数或输出参数,或同时接受这两者。 例如, RtlStringCbCopyUnicodeString 接受结构作为输入参数, RtlUnicodeStringCopyString 接受结构作为输出参数, RtlUnicodeStringCopy 接受结构作为输入和输出参数;
内核模式安全字符串函数提供以下功能:
- 每个安全字符串函数接收目标缓冲区的大小作为输入。 因此,函数可以确保它不会写入缓冲区的末尾;
- Unicode 和 ANSI 字符串函数使用 NULL 字符终止所有输出字符串,即使操作截断了预期结果;
- 所有安全字符串函数都返回 NTSTATUS 值, (STATUS_SUCCESS) 只有一个可能的成功代码;
- 大多数安全字符串函数在字节计数和字符计数版本中都可用。 例如, RtlStringCbCata 连接两个字节计数字符串, RtlStringCchCata 连接两个字符计数字符串;
大多数安全字符串函数在扩展的 Ex-suffixed 版本中提供,可提供其他功能。 例如, RtlStringCbCatExa 扩展 了 RtlStringCbCata 的功能。
使用安全整数函数
尽量减少安全问题的一种方法是防止整数溢出和下溢。 当算术运算的结果大于设置为接收它的数据类型的内存空间时,会发生整数溢出。 这会导致整数被截断,结果不正确。 当运算(通常为减法)给出不正确的结果时,将发生下溢。 由于截断了不适合新内存空间的结果,两种数据类型之间的强制转换也可能导致不正确的结果。
ntintsafe 库提供了一组 C 函数,这些函数通过边界检查执行安全整数算术运算,以防止内核模式代码中出现溢出和下溢。 这些函数对应于应用程序代码使用的 Windows IntSafe 函数。 使用这些函数来计算索引或缓冲区大小,或计算某种其他形式的边界检查。 函数针对速度进行优化。
安全整数函数具有以下优点:
- 始终向函数提供目标缓冲区的大小,以确保函数不会写入缓冲区末尾;
- 保证缓冲区以 null 结尾,即使操作截断了预期结果;
- 所有函数都返回 NTSTATUS,其中只有一个可能的成功代码 (STATUS_SUCCESS) , (STATUS_INTEGER_OVERFLOW) 一个可能的错误条件;
确定操作系统是否在安全模式下运行
下面除了介绍设备驱动程序如何确定其上运行的操作系统是否已在安全模式下启动,还介绍如何防止驱动程序在安全模式下运行。
Microsoft Windows 操作系统内核导出名为 InitSafeBootMode 的指针。 InitSafeBootMode 指向包含当前有效的安全模式设置的 ULONG 变量。 设备驱动程序可以检查这些设置,以确定操作系统是否在安全模式下运行。
InitSafeBootMode 变量对应的模式。
- 0:操作系统未处于安全模式。
- 1:SAFEBOOT_MINIMAL
- 2:SAFEBOOT_NETWORK
- 3:SAFEBOOT_DSREPAIR 注意:仅适用于 Windows 域控制器。
若要使用 InitSafeBootMode 变量,必须在驱动程序中声明它,如以下代码示例所示:
extern PULONG InitSafeBootMode;//声明 InitSafeBootMode 后,可以使用以下代码示例来确定操作系统是否在安全模式下运行
if (*InitSafeBootMode > 0)
{// The operating system is in Safe Mode.// Take appropriate action.//
}
若要防止驱动程序在安全模式下运行,请使用以下列表中与驱动程序类型匹配的技术:
1. 功能驱动程序:如果功能驱动程序的服务启动类型为 SERVICE_BOOT_START,请在功能驱动程序的 AddDevice 例程中检查 InitSafeBootMode 的值。 如果系统处于安全模式,则返回失败状态。注意 切勿从 DriverEntry 例程返回失败。
2. Filter驱动程序:如果Filter驱动程序在系统启动期间启动,请在Filter驱动程序的 AddDevice 例程中检查 InitSafeBootMode 的值。 如果操作系统处于安全模式,请执行以下操作:
不要将Filter设备对象附加到设备堆栈。
从Filter驱动程序的 AddDevice 例程返回成功。
3. 其他驱动程序:对于除功能或Filter驱动程序以外的驱动程序,在驱动程序的 DriverEntry 例程中检查 InitSafeBootMode 的值。 如果操作系统处于安全模式,则返回失败状态。
在 WDM 驱动程序中使用浮点数
使用浮点运算时,Windows 的内核模式 WDM 驱动程序必须遵循某些准则。 这些在 x86 和 x64 系统之间有所不同。 默认情况下,Windows 会关闭这两个系统的算术异常。
x86 系统
x86 系统的内核模式 WDM 驱动程序必须在调用 KeSaveExtendedProcessorState 和 KeRestoreExtendedProcessorState 之间包装浮点计算的使用。 浮点运算必须置于非内联子例程中,以确保在检查 KeSaveExtendedProcessorState 的返回值之前,不会执行浮点计算,因为编译器重新排序。
编译器使用 MMX/x87 也称为浮点单元, FPU)寄存器进行此类计算,用户模式应用程序可以同时使用这些计算。 在使用这些寄存器之前未能保存这些寄存器,或者在完成后无法还原它们,可能会导致应用程序中出现计算错误。
x86 系统的驱动程序可以调用 KeSaveExtendedProcessorState ,并在 IRQL <= DISPATCH_LEVEL 执行浮点计算。 x86 系统上 (的 ISR) 中断服务例程不支持浮点操作。
x64 系统
64 位编译器不对浮点运算使用 MMX/x87 寄存器。 而是使用 SSE 寄存器。 不允许 x64 内核模式代码访问 MMX/x87 寄存器。 编译器还负责正确保存和还原 SSE 状态,因此,不需要调用 KeSaveExtendedProcessorState 和 KeRestoreExtendedProcessorState ,并且可以在 ISR 中使用浮点操作。 使用其他扩展处理器功能(如 AVX)需要保存和还原扩展状态。 有关详细信息,请参阅 在 Windows 驱动程序中使用扩展处理器功能。
注意:通常,Arm64 与 AMD64 相似,无需先调用保存浮点状态。 但是,需要移植到内核上的 x86 的代码可能仍需要跨平台执行此操作。
示例代码
以下示例演示 WDM 驱动程序应如何包装其 FPU 访问:
__declspec(noinline)
VOID
DoFloatingPointCalculation(VOID)
{double Duration;LARGE_INTEGER Frequency;Duration = 1000000.0;DbgPrint("%I64x\n", *(LONGLONG*)&Duration);KeQueryPerformanceCounter(&Frequency);Duration /= (double)Frequency.QuadPart;DbgPrint("%I64x\n", *(LONGLONG*)&Duration);
}NTSTATUS
DriverEntry(_In_ PDRIVER_OBJECT DriverObject,_In_ PUNICODE_STRING RegistryPath)
{XSTATE_SAVE SaveState;NTSTATUS Status;Status = KeSaveExtendedProcessorState(XSTATE_MASK_LEGACY, &SaveState);if (!NT_SUCCESS(Status)) {goto exit;}__try {DoFloatingPointCalculation();}__finally {KeRestoreExtendedProcessorState(&SaveState);}exit:return Status;
}
在此示例中,对浮点变量的赋值发生在对 KeSaveExtendedProcessorState 和 KeRestoreExtendedProcessorState 的调用之间。 由于对浮点变量的任何赋值都使用 FPU,因此在初始化此类变量之前,驱动程序必须确保 KeSaveExtendedProcessorState 返回且没有错误。
上述调用在 x64 系统上是不必要的,在指定XSTATE_MASK_LEGACY标志时是无害的。 因此,在为 x64 系统编译驱动程序时,无需更改代码。
相关文章:
windows驱动开发-内核编程技术汇总(五)
使用安全字符串函数 和应用层不一样的是,windows内核完全使用Unicode字符串,许多支持AsciiC的windowsAPI,是在应用层完成项Unicode的切换的。许多系统安全问题是由缓冲区处理不善和生成的缓冲区溢出引起的。 糟糕的缓冲区处理通常与字符串操…...
Java中的optional类是啥和例子
Optional 是 Java 8 引入的一个容器对象,用于表示值存在或不存在。这是一个可以为 null 的容器对象,但使用 Optional 比直接使用 null 更安全,因为 Optional 类提供了许多有用的方法,以便更优雅地处理可能存在或不存在的值。 使用…...

AI大模型探索之路-训练篇16:大语言模型预训练-微调技术之LoRA
系列篇章💥 AI大模型探索之路-训练篇1:大语言模型微调基础认知 AI大模型探索之路-训练篇2:大语言模型预训练基础认知 AI大模型探索之路-训练篇3:大语言模型全景解读 AI大模型探索之路-训练篇4:大语言模型训练数据集概…...
mysql事务锁排查
-- mysql show full PROCESSLIST; -- 查看哪些表在锁。 show open tables where IN_use>0; -- 正在执行的事务: SELECT * FROM information_schema.INNODB_TRX;-- 8.0之前 查看正在锁的事务 select * from information_schema.innodb_locks;-- 查看等待锁的事务 …...

ChatGPT变懒原因:正在给自己放寒假!已被网友测出
ChatGPT近期偷懒严重,有了一种听起来很离谱的解释: 模仿人类,自己给自己放寒假了~ 有测试为证,网友Rob Lynch用GPT-4 turbo API设置了两个系统提示: 一个告诉它现在是5月,另一个告诉它现在是1…...

C#标签设计打印软件开发
1、新建自定义C#控件项目Custom using System; using System.Collections.Generic; using System.Text;namespace CustomControls {public class CommonSettings{/// <summary>/// 把像素换算成毫米/// </summary>/// <param name="Pixel">多少像素…...

Springboot+vue+小程序+基于微信小程序的在线学习平台
一、项目介绍 基于Spring BootVue小程序的在线学习平台从实际情况出发,结合当前年轻人的学习环境喜好来开发。基于Spring BootVue小程序的在线学习平台在语言上使用Java语言进行开发,在数据库存储方面使用的MySQL数据库,开发工具是IDEA。…...

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-13-按键实验
前言: 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM(MX6U)裸机篇”视频的学习笔记,在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…...

ubuntu与redhat的不同之处
华子目录 什么是ubuntu概述 ubuntu版本简介桌面版服务器版 安装部署部署后的设置设置root密码关闭防火墙启用允许root进行ssh登录更改apt源安装所需软件 安装nginx安装apache网络配置Netplan概述配置详解配置文件DHCP静态IP设置设置 软件安装方法apt安装软件作用常用命令配置ap…...

三岁孩童被家养大型犬咬伤 额部撕脱伤达10公分
近期,一名被家养大型犬咬伤了面部的3岁小朋友,在被家人紧急送来西安国际医学中心医院,通过24小时急诊门诊简单救治后,转至整形外科,由主治医师李世龙为他实施了清创及缝合手术。 “患者额部撕脱伤面积约为10公分&…...
@click=“handleClick()“不会传递默认事件参数
当你使用click"handleClick()"这种形式绑定事件处理器时,Vue会将它视为一个函数调用,而不是一个事件监听器。在这种情况下,Vue不会自动传递原生事件对象作为默认参数。 如果你想让Vue自动传递原生事件对象作为默认参数,…...
KVM安装Ubuntu24.04简要坑点以及优点
本机环境是ubuntu22.04的环境,然后是8核16线程 ssd是500的 目前对于虚拟机的选择,感觉kvm确实会更加流畅,最重要的一点是简洁,然后实际安装效果也比较的好,如果对于速度方面希望快一点,并且流畅一点的话这…...

QT_day1
#include "mywidget.h"MyWidget::MyWidget(QWidget *parent): QWidget(parent) {//修改窗口标题this->setWindowTitle("4.6.0");//修改窗口图标this->setWindowIcon(QIcon("C:\\Users\\zj\\Desktop\\yuanshen\\icon"));//修改窗口大小this…...

AWS宣布推出Amazon Q :针对商业数据和软件开发的生成性AI助手
亚马逊网络服务(AWS)近日宣布推出了一项名为“Amazon Q”的新服务,旨在帮助企业利用生成性人工智能(AI)技术,优化工作流程和提升业务效率。这一创新平台的推出,标志着企业工作方式的又一次重大变…...

C++:多继承虚继承
在C中,虚继承(Virtual Inheritance)是一种特殊的继承方式,用于解决菱形继承(Diamond Inheritance)问题。菱形继承指的是一个类同时继承自两个或更多个具有共同基类的类,从而导致了多个实例同一个…...

Linux进程间通信
每个进程的用户空间都是独立的,不能相互访问。 所有进程的内核空间(32位系统3G-4G)都是共享的 应用场景 作为缓冲区,处理速度不同的进程之间的数据传输资源共享:多个进程之间共享同样的资源,一个进程对共享数据的修改,…...
【二叉树算法题记录】222. 完全二叉树的节点个数
题目描述 给你一棵 完全二叉树 的根节点root ,求出该树的节点个数。 完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位…...
每日新闻掌握【2024年5月6日 星期一】
2024年5月06日 星期一 农历三月廿八 大公司/大事件 多个品牌黄金优惠后价格重回600元/克以下 “五一”假期期间,记者走访调研黄金消费市场发现,受国际金价回落及“五一”假期促销等多重因素影响,终端黄金价格出现了较为明显的回落。包括周大…...

谈谈Tcpserver开启多线程并发处理遇到的问题!
最近在学习最基础的socket网络编程,在Tcpserver开启多线程并发处理时遇到了一些问题! 说明 在linux以及Windows的共享文件夹进行编写的,所以代码中有的部分使用 #ifdef WIN64 ... #else ... #endif 进入正题!!&…...

618好物节不知道买什么?快收下这份好物推荐指南!
随着618好物节的临近,你是否在为选择什么产品而犹豫不决?不用担忧,我精心准备了一份购物指南,旨在帮助你发现那些性价比高、口碑爆棚的商品。无论是科技新品还是生活小物件,这份指南都能帮你快速定位到那些值得投资的好…...

19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...

Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...

Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统
💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「storms…...
tomcat指定使用的jdk版本
说明 有时候需要对tomcat配置指定的jdk版本号,此时,我们可以通过以下方式进行配置 设置方式 找到tomcat的bin目录中的setclasspath.bat。如果是linux系统则是setclasspath.sh set JAVA_HOMEC:\Program Files\Java\jdk8 set JRE_HOMEC:\Program Files…...
Django RBAC项目后端实战 - 03 DRF权限控制实现
项目背景 在上一篇文章中,我们完成了JWT认证系统的集成。本篇文章将实现基于Redis的RBAC权限控制系统,为系统提供细粒度的权限控制。 开发目标 实现基于Redis的权限缓存机制开发DRF权限控制类实现权限管理API配置权限白名单 前置配置 在开始开发权限…...
41道Django高频题整理(附答案背诵版)
解释一下 Django 和 Tornado 的关系? Django和Tornado都是Python的web框架,但它们的设计哲学和应用场景有所不同。 Django是一个高级的Python Web框架,鼓励快速开发和干净、实用的设计。它遵循MVC设计,并强调代码复用。Django有…...