Windows驱动开发学习笔记(三)—— 内核空间&内核模块

前言

一、学习自滴水编程达人中级班课程,官网:https://bcdaren.com
二、海东老师牛逼!

内核空间

描述:两个进程在低2G内存空间中所对应的物理页是不同的,但是在高2G内存空间中所对应的物理页几乎是相同的(所有的进程共享同一个内核空间)
在这里插入图片描述

实验

第一步:编译如下代码

#include "ntddk.h"

//卸载函数
VOID DriverUnload(PDRIVER_OBJECT driver)
{
   DbgPrint("驱动程序已停止.\r\n");
}

ULONG x = 0x12345678;

//驱动程序入口函数,相当于控制台的main函数
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)
{
   DbgPrint("驱动程序已运行.\r\n");
   DbgPrint("%x . \r\n", &x);

   //设置一个卸载函数  便于退出
   DriverObject->DriverUnload = DriverUnload;

   return STATUS_SUCCESS;
}

第二步:将 .sys 文件拷贝到虚拟机中

第三步:部署 .sys 文件并运行

在这里插入图片描述

第四步:创建一个任意进程

本实验采用飞鸽传书(ipmsg.exe
在这里插入图片描述

第五步:在 WinDbg 中查看新进程的高2G内存

在这里插入图片描述

内核模块

描述

  1. 硬件的种类繁多,不可能做一个兼容所有硬件的内核,因此,微软提供规定的接口格式,让硬件驱动人员按照规定的格式编写“驱动程序
  2. 这些驱动程序每一个都是一个模块,称为“内核模块”,可以加载到内核中,并遵守PE结构。但本质上讲,任意一个.sys文件与内核文件没有区别
  3. 不管是我们自己编写的 .sys 文件,还是 Windows 自带的内核文件(如 ntoskrnl.exe),它们在内核中的地位是相同的,都是内核模块中的其中一个

在这里插入图片描述

驱动对象

DRIVER_OBJECT

在WinDbg中查看
在这里插入图片描述
DriverStart:驱动模块在内核中的地址
DriverSize:驱动模块在内核中的大小
DriverName:驱动模块在内核中的名字
DriverSection:指向 _LDR_DATA_TABLE_ENTRY 结构体

LDR_DATA_TABLE_ENTRY

描述:包含了当前内核模块的具体信息,以及其它内核模块的双向链表

在WinDbg中查看
在这里插入图片描述
InLoadOrderLinks:双向链表,包含所有内核模块
DllBase:当前内核模块起始地址
SizeOfImage:当前内核模块的大小
FullDllName:当前内核模块的完整路径
BaseDllName:当前内核模块的模块名

实验

第一步:编译如下代码

#include "ntddk.h"

//卸载函数
VOID DriverUnload(PDRIVER_OBJECT driver)
{
	DbgPrint("驱动程序已停止.\r\n");
}

//驱动程序入口函数,相当于控制台的main函数
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)
{
	DbgPrint("驱动程序已运行.\r\n");
	DbgPrint("%x . \r\n", DriverObject);

	//设置一个卸载函数  便于退出
	DriverObject->DriverUnload = DriverUnload;

	return STATUS_SUCCESS;
}

第二步:将 .sys 文件拷贝到虚拟机中

第三步:部署 .sys 文件并运行

在这里插入图片描述

第四步:在 WinDbg 中查看驱动对象

在这里插入图片描述

第五步:通过双向链表查看其它模块的信息

注意:遇到NULL则跳过
在这里插入图片描述
直到找到一个有效的内核模块
在这里插入图片描述

总结

  1. 内核空间中,每个进程低2G各不相同,高2G相同,在高2G中做任何事情影响的是所有进程
  2. 在高2G中,并不是只有一个内核模块为所有进程提供服务,而是由许多个模块组成,每个模块在高2G中都有属于自己独立的内存地址和大小
  3. 若想了解每个内核模块的具体信息,可以通过 _DRIVER_OBJECT 这个结构体,它存储了当前内核模块的具体信息
  4. 任意加载一个驱动,便可通过 _LDR_DATA_TABLE_ENTRY 这个结构体中的双向链表得到所有内核模块的信息
发布了45 篇原创文章 · 获赞 2 · 访问量 1822

猜你喜欢

转载自blog.csdn.net/qq_41988448/article/details/103514007