Win下NT式驱动编程学习笔记
文章平均质量分 65
主要是学习使用WDK8.1开发包学习NT式驱动过程中的学习记录。
其参考的主要是《Windows驱动开发技术详解》作者: 张帆
Kiopler
这个作者很懒,什么都没留下…
展开
-
内核态进行进程与线程的监控
进程监控主要使用PsSetCreateProcessNotifyEx线程监控主要使用PsSetCreateThreadNotify主要需要注意一点就是,这种方式的使用条件是需要强制完整性检查。可以通过/integritycheck选项添加。或者网上有一种绕过方式, 在调用上面那两个函数前首先调用下面这个函数,如果执行成功即可绕过强制完整性检查。BOOLEAN BypassCheckSign(PDRIVER_OBJECT pDriverObject){#ifdef _WIN64..原创 2022-03-21 20:59:49 · 854 阅读 · 0 评论 -
Windows内核编程R0与R3通信
直接设备读写其原理是锁定用户空间内存(这解决了分页内存置换导致缺页异常的问题)并将其映射到内核空间地址,直接对该内核空间地址进行写入即可,由于进程的内核空间是共享的。所以属于任何进程的线程都可以写入。注意的点:1. 要为设备添加DO_DIRECT_IO标志2. 为R3下ReadFile和WriteFile派遣函数时获取对对应传入参数a. 其中WriteFile的用户输入内存地址和ReadFile的设备输出地址通过MmGetSystemAddressForMdlSafe函数锁定IRP.原创 2022-03-20 16:38:04 · 1977 阅读 · 0 评论 -
遍历驱动的设备栈遇到的问题及解决
首先来说一下我遇到的几个问题:可以看到上面的代码中我是要打印4项,分别是驱动名称, 设备名称,驱动地址以及设备地址。但结果:驱动名称出来了但设备名没有。分明pObjNameInfo->Name.Buffer都存在,怎么会打印不出来呢? 于是我看了下里面可以看到这里显示无法读取这里的内存, 这我真的懵逼了。在者,这里面会打印如下内容:驱动自身的设备链 附着在驱动设备上的设备链可以看到上面结果中所有设备名称都存在的但是没被显示出来,原因是无法被读取。而无法读取的原创 2020-11-20 09:36:25 · 689 阅读 · 0 评论 -
Windows内核定时器总结
总结了两种内核态的定时器,IO定时器和DPC定时器。其显著特点是IO定时器精度至少为1秒而DPC定时器可以精确到100ns级别。DPC定时器使用步骤:KeInitializeTimer初始化定时器 KeInitializeDpc(和1的步骤顺序无所谓)初始化DPC并设置对应例程 KeSetTimer 定时启动DPC例程 KeCancelTimer 停止DPC定时器IO定时器使用步骤:IoInitializeTimer 初始化IO定时器 IoStartTimer 开始定时 IoStop原创 2020-11-18 07:39:29 · 1187 阅读 · 0 评论 -
[Win32驱动14]通过4种方式手动创建IRP
1. IoBuildSynchronousFsdRequest__drv_aliasesMem PIRP IoBuildSynchronousFsdRequest( ULONG MajorFunction, PDEVICE_OBJECT DeviceObject, PVOID Buffer, ULONG Length, PLARGE_INTEGER StartingOffset, PKEVENT原创 2020-11-11 14:06:03 · 558 阅读 · 0 评论 -
通过符号链接名获取设备名称
有时候只知道符号链接名,可是通过比如ZwCreateFile等方式打开设备需要设备名。可以通过以下两个内核函数来获取(该方法在另一篇博客内也有提及):NTSYSAPI NTSTATUS ZwOpenSymbolicLinkObject( PHANDLE LinkHandle, ACCESS_MASK DesiredAccess, // 这个权限至少是GENERIC_READ POBJECT_ATTRIBUTES ObjectAttributes);原创 2020-11-09 09:41:56 · 668 阅读 · 1 评论 -
Windbg符号表无法加载问题解决办法
搞定了符号表的问题。之前一直显示符号表无法加载。下了离线版本的都没办法用,现在:已经解决了这个问题。原因在于我一开始用的是离线版符号表。结果版本不对导致符号表加载失败。所以我挂了VPN。使用外网后成功下载了在线版本的符号表。这里记录下在线版本的符号表加载中的几个注意点:记得添加windbg的安装目录到Path环境变量下,因为符号表需要symsrv.dll和symstore.exe, 而这两个工具位于windbg的安装目录 添加入下图所示的环境变量我用A和B来代替了变量值中的路径和域名: SR原创 2020-11-09 09:06:02 · 1939 阅读 · 0 评论 -
驱动中同步与异步发送IRP
1. 同步创建2. 异步创建原创 2020-11-09 09:44:09 · 432 阅读 · 0 评论 -
[Win32驱动13]IRP传递方式总结
1. 直接转发IRP2. 转发IRP后等待完成并重新获取IRP控制权3. 不转发IRP4. 暂时挂起当前IRP,设置完成例程以及StartIO例程原创 2020-11-04 10:59:07 · 383 阅读 · 0 评论 -
在WinDBG中查看变量的命令
在WinDBG中查看变量的命令 命令============dvDisplay Variable的缩写, 查看局部变量.dv /i查看局部变量, 并显示符号的类型和参数类型.dv /V查看局部变量, 并显示变量的存储位置.dv /V VariableName指定需要查看的变量的名字dv 02sample!gGlo*dv命令可以带有通配符, 来查看具有某命名模式的变量.举例:dtDisplay...转载 2020-11-02 23:43:04 · 1960 阅读 · 0 评论 -
[Win32驱动11] 驱动中的IRP同步异步以及串行化处理方式(Part 2)
自定义StartIO例程原创 2020-11-03 09:19:36 · 159 阅读 · 0 评论 -
[Win32驱动11] 驱动中的IRP同步异步以及串行化处理方式(Part 1)
1. 异步IO读写的处理方式这段代码是驱动异步处理应用层发来的IRP的一种方式,其基本作用原理是这样的:应用层进程以异步的方式多次发来Read IRP请求。由于设备一次性无法立即处理完所有IRP,所以设备在收到IRP后首先将其挂载到一个链表中并挂起该IRP,返回STATUS_PENDING。这些挂在链表上的IRP会在设备被关闭时被处理掉。即当CloseHandle被调用后,设备收到CLEANUP类型的IRP时处理。其处理方式也非常简单,这里仅仅是完成IRP的处理什么也不做。接下去看一下代码:原创 2020-11-02 12:40:50 · 404 阅读 · 0 评论 -
关于Windbg双机调试以及VirtualKD+Windbg双机调试经验总结
终于吐血的VirtualKD双机调试环境终于成功了。看下下面的图,真的太坑了..... 之前用VirtualKD连虚拟机一直连不上,所有步骤我都检查了很多遍但还是有问题,我都怀疑我人生了,今天!!!! 就在3分钟前出现了如下的画面:我第一次见到这个绿绿的圆点那么开心!!!!现在来总结下,到底在这么长的一段时间是什么问题困扰了我。其实都是非常小的问题。原因是:我的VM15.5与VirtualKD版本不兼容....如果想要VirtualKD支持15.5及以上版本的VM就需要用更新的Virt原创 2020-10-23 19:40:39 · 1384 阅读 · 0 评论 -
使用 VMware + win10 + VirtualKD + windbg 从零搭建双机内核调试环境
原 总结 debug 调试 kernel debug windbg bcdedit virtualKD 转储 双机调试 双机内核调试 前言当我们没有两台物理机时,又想做双机内核调试怎么办?当然是装虚拟机啦!本文总结了使用 VMware15.5 + win10 + virtualkd + windbg 搭建双机内核调试环境。 安装环境 VMware 版本: 15.5 pro 。可以到 VMware 官网下载地址 下载最新版本。 我的物理主机系统:win10 1909转载 2020-10-23 18:52:31 · 1022 阅读 · 1 评论 -
[Win32驱动12]DeviceIoControl方式进行内核态与用户态的通信
这篇博客里介绍了如何通过缓冲区,直接和其他方式进行IO通信,还有一种更灵活的通信方式那就是DeviceIoControl, 先来看一下该函数的原型:BOOL DeviceIoControl( HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD ...原创 2020-10-23 10:10:15 · 1090 阅读 · 0 评论 -
[Win32驱动10] 派遣函数与读写方式
1. 派遣函数在Windows中,用户态进程的各类IO请求最后都会转化成对应的IRP请求并发送给底层驱动。其流程差不多是这样的,拿WriteFile来举例:在用户态调用WriteFile函数 WriteFile会调用NTDLL.dll中的NtWriteFile函数 NtWriteFile会陷入内核调用系统服务NtWriteFile(注意只是相同的名字,但本质完全不同) NtWriteFile会生成相应的IRP,对应IRP类型为: IRP_MJ_WRITE并将其发送给底层对应驱动 IRP会顺次原创 2020-10-21 18:21:57 · 582 阅读 · 0 评论 -
[Win32驱动1]Windows驱动注册表操作
111111111原创 2020-10-20 11:26:25 · 1153 阅读 · 0 评论 -
[Win驱动2]内核模式下的文件操作
1. 文件的创建NTSYSAPI NTSTATUS ZwCreateFile( PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, PLARGE_INTEGER AllocationSize, ULONG FileAttribu原创 2020-10-18 21:49:12 · 172 阅读 · 0 评论 -
[Win驱动8]利用定时器编写取消例程
当应用程序发送了一个读请求IRP给驱动派遣函数时,派遣函数可以选择完成这个IRP也可以选择取消这个IRP,可以通过DPC例程来设置取消IRP执行,方法如下:#include <ntddk.h>typedef struct _DEVICE_EXTENSION { UNICODE_STRING ustrSymLinkName; UNICODE_STRING ustrDeviceName; PDEVICE_OBJECT pDevice; PIRP currentPendingIRP;原创 2020-10-18 19:32:43 · 100 阅读 · 0 评论 -
[Win驱动7]ObReferenceObjectByName获取设备对象指针(PDEVICE_OBJECT)
1. ObReferenceObjectByName是通过设备对象名获取设备对象指针, 其会造成设备对象的引用计数增加所以还需要调用ObDereferenceObject来降低引用计数2. IoGetDeviceObjectPointer可以通过设备对象名获取设备对象指针和与其相关的文件对象指针,同样需要对其调用ObDereferenceObject来降低引用第一种方式是通过这个未公开的内核函数ObReferenceObjectByName来获取设备对象指针,该原型是这样的:NTKERNELA原创 2020-10-18 16:33:09 · 1470 阅读 · 0 评论 -
[Win驱动9]Windows分层驱动
ghfd原创 2020-10-31 08:39:24 · 398 阅读 · 0 评论 -
[Win驱动6]Windows驱动之间的同步相互调用
应用程序->驱动B(Read)->驱动A(Read)// 应用程序#include <windows.h>#include <stdio.h>int main() { DWORD dRet; HANDLE hDevice = CreateFile("\\\\.\\HelloDDKB", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,原创 2020-10-17 17:50:49 · 654 阅读 · 0 评论 -
error LNK2019: 无法解析的外部符号 DriverEntry错误原因
error LNK2019: 无法解析的外部符号 DriverEntry,该符号在函数 GsDriverEntry 中被引用导致该问题的原因是使用了.cpp后缀的文件格式,解决方法很简单, 可以直接把它换成.c结尾。或者加上extern "C"让它以C语言方式链接就可以了(完)...原创 2020-10-16 14:10:15 · 3174 阅读 · 1 评论 -
[Win驱动5]Windows内核定时器
两种定时器1. IoTimer方式NTSTATUS IoInitializeTimer( PDEVICE_OBJECT DeviceObject, PIO_TIMER_ROUTINE TimerRoutine, __drv_aliasesMem PVOID Context);void IoStartTimer( PDEVICE_OBJECT DeviceObject);void IoStopTimer( PDEVICE_OBJECT Dev原创 2020-10-15 18:03:19 · 1179 阅读 · 0 评论 -
[Win驱动4]Windows内核态字符串操作
1. 内核的字符串操作原创 2020-10-11 00:23:43 · 684 阅读 · 0 评论 -
[Win驱动3] Windows内核态的堆管理, LookAside,链表以及运行时函数
内存机制简述现代操作系统一般都有分页机制,其控制方式是通过Cr0控制寄存器中的PG位,如果PG位置位则表示分页机制开启,这种机制在还未进入保护模式时就已经确定了。在32位的CPU下,假设是4KB为一页,则4GB内存可以被分成2^20个页,并且通过页表来映射到各个进程或者磁盘上去。同一页可以映射到多个进程的虚拟内存空间中。内核态堆空间分配内核态中可以分配分页内存以及非分页的内存, 分页内存是CPU开启分页机制时才存在,如果没有开启分页机制,所有内存都是非分页的。分页机制作用主要是为了给进程一个原创 2020-10-08 23:16:38 · 492 阅读 · 0 评论 -
CONTAINING_RECORD宏解析
CONTAINING_RECORD内容这里分析一下这个CONTAINING_RECORD宏,该宏的作用是通过结构体类型内部某一成员的位置来获取该结构体的位置。结构体内容如下://// Calculate the address of the base of the structure given its type, and an// address of a field within the structure.//#define CONTAINING_RECORD(address, t原创 2020-10-07 23:59:52 · 887 阅读 · 0 评论 -
Windows驱动程序Windbg调试方法[2]
1. 导言这里主要记录的是以下操作系统配置双机调试的方法。WindowsXP X86 Windows7的X86和X64 Windows10的X86和X64使用的工具:Windows XP Professional X86 WDK8.1驱动开发包 Windbg 6.x VMWare Workstation Pro所用驱动开发包均为WDK8.1,Windbg用的就是开发包内自带的那个版本。由于Win7与Win10配置双机调试方法不管机器位数都是一样的,所以这里只选择记录Win7的2原创 2020-10-04 18:16:47 · 2508 阅读 · 2 评论 -
自写驱动最优先自启动
1. 先导使用的平台: Win7 X64 集成开发环境: VS2013+WDK8.1关于数字签名的困惑注意: 在x86下无所谓,但在x64下由于有数字签名,所以需要想办法绕过检测数字签名1. 一种比较通用的方法, 开启测试模式, 这样生成的驱动便带有测试签名了,方法如下:以管理员身份打开cmd控制台 打开64位测试签名模式: bcdedit /set testsigning on 关闭64位测试签名模式: bcdedit /set testsigning off 需要重启才能生效原创 2020-10-02 16:46:46 · 791 阅读 · 0 评论 -
寒江独钓Windows内核编程-双机调试1
今天总结一下关于双机调试,前面一直使用的是DDK包进行NT式与WDM式驱动入门,至今已进入使用WDK包进行编程了,DDK包早已落后我只作为入门因为大体内容变化不大。我使用的书是《寒江独钓Windows内核安全编程》,这个系列将围绕三本书进行,一本就是刚刚所提到的,还有两本分别为《天数夜读从汇编语言到Windows内核编程》和《Windows内核安全与驱动开发》。首先来总结一下双机调试,驱动程序...原创 2019-07-16 18:30:49 · 607 阅读 · 0 评论