Loading... 环境配置 A1Systest 测试软件 Win7 默认过滤掉了处理需要修改才能调试输出信息 修改后缀 .reg 之后 在Win7 虚拟机执行 然后就可以在WinDbg 输出调试信息 保存到 .reg文件中双机执行即可 ``` Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Debug Print Filter] [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Debug Print Filter] "DEFAULT"=dword:0000000f ``` ![image.png](http://www.irohane.top/usr/uploads/2021/02/769298394.png) ![image.png](http://www.irohane.top/usr/uploads/2021/02/320722415.png) 简单的驱动 <span style="color:#FF0000">DriverObject 结构体</span> ``` /* * 驱动对象: 类似于 GUI 程序中的应用程序本身,不能直接和 R3 进行交互,需要依赖设备对象传递 IRP * SHORT Type; // 表示结构体的类型,所以的驱动对象都为 4 * SHORT Size; // 驱动对象的大小,所占用的字节数 * struct _DEVICE_OBJECT* DeviceObject; // * 当前驱动对象下所有设备对象组合成的单向链表 * ULONG Flags; // 标志位 * VOID* DriverStart; // 当前对象在内存中的起始位置 * ULONG DriverSize; // 驱动对象所占用的总空间 * VOID* DriverSection; // * 指向 LDR 链表,可以用于遍历系统下的所有驱动对象 * struct _DRIVER_EXTENSION* DriverExtension; // 指向扩展空间的指针 * struct _UNICODE_STRING DriverName; // * 驱动对象的名称,是一个字符串结构体 * struct _UNICODE_STRING* HardwareDatabase; // 在注册表硬件配置表中的一个名称 * struct _FAST_IO_DISPATCH* FastIoDispatch; // 特殊的派遣函数,在文件过滤驱动中会被使用 * VOID* DriverInit; // 驱动程序最先执行的代码 * VOID* DriverStartIo; // 用于驱动 IRP 的串行化处理 * VOID* DriverUnload; // * 驱动程序的卸载函数,不提供就无法卸载 * VOID* MajorFunction[28]; // * 消息派遣函数组成的列表(类似于消息处理函数) */ // LDR 链表中的每一项都是这个结构体,保存了驱动的基本信息 typedef struct _LDR_DATA_TABLE_ENTRY { struct _LIST_ENTRY InLoadOrderLinks; //0x0 struct _LIST_ENTRY InMemoryOrderLinks; //0x8 struct _LIST_ENTRY InInitializationOrderLinks; //0x10 VOID* DllBase; //0x18 VOID* EntryPoint; //0x1c ULONG SizeOfImage; //0x20 struct _UNICODE_STRING FullDllName; //0x24 struct _UNICODE_STRING BaseDllName; //0x2c // ... 后面还有一些字段,由于用不到,为了节省代码量,直接不考虑 } *PLDR_DATA_TABLE_ENTRY; ``` ![image.png](http://www.irohane.top/usr/uploads/2021/03/2937543996.png) ``` #include <ntddk.h> // LDR 链表中的每一项都是这个结构体,保存了驱动的基本信息 typedef struct _LDR_DATA_TABLE_ENTRY { struct _LIST_ENTRY InLoadOrderLinks; //0x0 struct _LIST_ENTRY InMemoryOrderLinks; //0x8 struct _LIST_ENTRY InInitializationOrderLinks; //0x10 VOID* DllBase; //0x18 VOID* EntryPoint; //0x1c ULONG SizeOfImage; //0x20 struct _UNICODE_STRING FullDllName; //0x24 struct _UNICODE_STRING BaseDllName; //0x2c // ... 后面还有一些字段,由于用不到,为了节省代码量,直接不考虑 } *PLDR_DATA_TABLE_ENTRY; //提供卸载函数 在卸载函数时会被调用 VOID DriverUnload(PDRIVER_OBJECT DriverObject) { KdPrint(("DriverUnload\n")); UNREFERENCED_PARAMETER(DriverObject); } // 驱动对象 驱动注册路径 NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) { //在驱动编程中 未引用对象会报错,所以使用宏来使用一下=。= UNREFERENCED_PARAMETER(DriverObject); UNREFERENCED_PARAMETER(RegistryPath); //Windows 提供 DbgBreakPoint 来检测双机环境,如果是双机环境 //该异常会被内核调试器 WinDbg接收到。可继续调试 DbgBreakPoint(); //提供卸载函数,如果没有提供该驱动就无法被卸载 可以故意不写 DriverObject->DriverUnload = DriverUnload; KdPrint(("Driverload\n")); //LDR 是一个双向链表 PLDR_DATA_TABLE_ENTRY current = DriverObject->DriverSection; PLDR_DATA_TABLE_ENTRY item = DriverObject->DriverSection; //创建索引标识第几个 int index = 1; do { //输出信息 名字是一个字符串结构体 需要取地址 KdPrint(("%d-%wZ-%wZ\n", index++, &item->BaseDllName, &item->FullDllName)); //遍历下一个元素 item = (PLDR_DATA_TABLE_ENTRY)item->InLoadOrderLinks.Flink; } while (item!=current); //利用双向链表 切断本驱动链 //本驱动的上一个链表的下一个 切换到本驱动的下一个 current->InLoadOrderLinks.Blink->Flink = current->InLoadOrderLinks.Flink; //本驱动的下一个链表的上一个 切换到 本驱动的上一个 current->InLoadOrderLinks.Flink->Blink = current->InLoadOrderLinks.Blink; //返回成功 成功为 0 不成功为 1 return STATUS_SUCCESS; } ``` ![image.png](http://www.irohane.top/usr/uploads/2021/02/1124219371.png) PCHunter 检测到当前的驱动链表问题 ![请输入图片描述](http://www.irohane.top/usr/uploads/2021/02/1940915398.png) 最后修改:2021 年 04 月 03 日 © 允许规范转载 赞 0 如果觉得我的文章对你有用,请随意赞赏