驱动分类:
NT 驱动:最简单的驱动模型,不支持硬件特性;
WDM驱动:WDM驱动是在NT驱动基础上引入的一套驱动模型,支持即插即用、电源事件等特性
WDF驱动:WDF驱动是WDM驱动的封装和升级,屏蔽了部分细节,简化了大量接口
创建驱动:
新建项目
入口函数:
#include<ntddk.h>
void DriverUnload(PDRIVER_OBJECT pDriver)
{
DbgPrint("卸载!");
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pReg)//类似main
{
DbgPrint("%wZ Hello world %X!",pReg,pDriver);//输出驱动安装位置&驱动所在地址
pDriver->DriverUnload = DriverUnload;//驱动程序必须含有卸载函数
return STATUS_SUCCESS;
}
运行程序报错
warning C4100: “pDriver”: 未引用的形参
三种解决方式:
1、添加 #pragma warning( disable : 4100)
2、函数内添加 UNREFERENCED_PARAMETER(driver);//参数driver 改为未引用的参数
3、属性->C/C+±>常规->警告等级设置为3/把警告视为错误关闭
输出:
\REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\MyDriver1 Hello world 861273B8!
//安装位置为\REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\MyDriver1,驱动地址为861273B8
查看地址:
kd> dt _DRIVER_OBJECT 861273B8 //在地址处查看驱动结构体
ntdll!_DRIVER_OBJECT
+0x000 Type : 0n4
+0x002 Size : 0n168
+0x004 DeviceObject : (null)
+0x008 Flags : 0x12
+0x00c DriverStart : 0xf794d000 Void
+0x010 DriverSize : 0x6000
+0x014 DriverSection : 0x8619bcb8 Void
+0x018 DriverExtension : 0x86127460 _DRIVER_EXTENSION
+0x01c DriverName : _UNICODE_STRING "\Driver\MyDriver1"
+0x024 HardwareDatabase : 0x80671ae0 _UNICODE_STRING "\REGISTRY\MACHINE\HARDWARE\DESCRIPTION\SYSTEM"
+0x028 FastIoDispatch : (null)
+0x02c DriverInit : 0xf7951000 long MyDriver1!GsDriverEntry+0
+0x030 DriverStartIo : (null)
+0x034 DriverUnload : 0xf794e030 void MyDriver1!DriverUnload+0
+0x038 MajorFunction : [28] 0x804f454a long nt!IopInvalidDeviceRequest+0
源码调试
可以通过添加DbgBreakPoint(相当于INT 3)进行调试,系统会自动读取PDB文件
字符串操作
#include<ntddk.h>
#include<ntstrsafe.h>
#pragma warning( disable : 4100)
void DriverUnload(PDRIVER_OBJECT pDriver)
{
DbgPrint("卸载");
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pReg)
{
UNICODE_STRING buf = { 0 };
buf.Buffer = ExAllocatePoolWithTag(PagedPool, 1024, '123');
buf.Length = 0;
buf.MaximumLength = 1024;
WCHAR str[] = L"hello world!\n";
RtlUnicodeStringCopyString(&buf, str);
//WCHAR str2[] = L"M";
//RtlInitEmptyUnicodeString(&buf, str, sizeof(str));//初始化一个空的计数 Unicode 字符串
//RtlUnicodeStringCopyString(&buf, str);//复制 需要头文件ntstrsafe.h
//RtlInitUnicodeString(&buf, str);//初始化
DbgPrint("%wZ", &buf);
pDriver->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}