内核空间与内核模块

内核空间与内核模块

内核空间

进程A,B两个不同进程,低2G内存空间(ring 3)所对应的物理页几乎是不一样的,而高2G的内存空间对应的物理页却几乎是一样的.

在这里插入图片描述
不是每一个进程都有自己的内核空间,而是所有的进程共享一个内核空间

可以做个实验

驱动环境:win7 x64

//定义一个变量,输出变量线性地址

#include<ntddk.h>
VOID DriverUnload(PDRIVER_OBJECT driver)
{
	DbgPrint("EXIT!");

}
ULONG x = 0x12345678;
extern"C"
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
{
	DbgPrint("Welcome Driver,\r\n");
    DbgPrint("addr64 = %llx\n", &x);
	driver->DriverUnload = DriverUnload;
	return STATUS_SUCCESS;

}

拿到线性地址
0xfffff88003173000 很明显这是高2G的内存地址空间

在这里插入图片描述

然后利用windbg切换到另一个进程,并查看那个进程的0xfffff88003173000地址内容

在这里插入图片描述

可以看到不同进程的高2G内存都是通用的!

内核模块

在这里插入图片描述
模块为硬件和操作系统之间的交互做桥梁

  • 硬件种类繁多,不可能做一个兼容所有硬件的内核,所以,微软提供规定的接口格式,让硬件驱动人员安装规定的格式编写"驱动程序"
  • 这些驱动程序每一个都是一个模块,称为"内核模块",都可以加载到内核中,像之前的ntoskrnl.exe也是模块,和现在自己编写的驱动程序两者没有什么差别.

DRIVER_OBJECT

既然给了你写模块的权利,那就需要一些约束,比如模块们都有相同的入口点DriverEntry一样,这样才好管理.

就像我们即将说的DRIVER_OBJECT 这是一个结构体,这个结构体约束了你想要称为模块而要做出的规范,你的驱动需要按照该结构体来做.每一个模块都需要这个结构体来描述重要信息

1: kd> dt _DRIVER_OBJECT
ntdll!_DRIVER_OBJECT
   +0x000 Type             : Int2B
   +0x002 Size             : Int2B
   +0x008 DeviceObject     : Ptr64 _DEVICE_OBJECT
   +0x010 Flags            : Uint4B
   +0x018 DriverStart      : Ptr64 Void//驱动模块所处位置
   +0x020 DriverSize        : Uint4B//大小
   +0x028 DriverSection    : Ptr64 Void//对应一个指针,指向的是LDR_DATA_TABLE_ENTRY,这样的一个链表把所有的内核模块全部圈在了一起.
   +0x030 DriverExtension  : Ptr64 _DRIVER_EXTENSION
   +0x038 DriverName       : _UNICODE_STRING//名称
   +0x048 HardwareDatabase : Ptr64 _UNICODE_STRING
   +0x050 FastIoDispatch   : Ptr64 _FAST_IO_DISPATCH
   +0x058 DriverInit       : Ptr64     long 
   +0x060 DriverStartIo    : Ptr64     void 
   +0x068 DriverUnload     : Ptr64     void 
   +0x070 MajorFunction    : [28] Ptr64     long 

实验:

#include<ntddk.h>
VOID DriverUnload(PDRIVER_OBJECT driver)
{
	DbgPrint("EXIT!");

}
ULONG x = 0x12345678;
extern "C"
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
{
	DbgPrint("Welcome Driver,\r\n");

	DbgPrint("addr64 = %llx\n", driver);//读取指向当前驱动程序模块的结构体地址
	driver->DriverUnload = DriverUnload;
	return STATUS_SUCCESS;

}

拿到结构体地址,用windbg 查看

在这里插入图片描述

便可以看到当前驱动模块的信息:

在这里插入图片描述

上面结构体还有比较重要的一个

 +0x028 DriverSection    : Ptr64 Void//对应一个指针,指向的是LDR_DATA_TABLE_ENTRY,这样的一个链表把所有的内核模块全部圈在了一起.
kd> dt _LDR_DATA_TABLE_ENTRY 0xfffffa80`02b8f030

在DriverSection的值的地方查看该结构体:

在这里插入图片描述

找到这里 你会发现这张图覆盖了模块的所有细节

并且可以顺着这条链 一直找到所有模块,注意链表有些节点内容是空的,但是不影响可以继续往下找!
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值