驱动开发:内核解析内存四级页表

news2024/12/23 22:13:13

当今操作系统普遍采用64位架构,CPU最大寻址能力虽然达到了64位,但其实仅仅只是用到了48位进行寻址,其内存管理采用了9-9-9-9-12的分页模式,9-9-9-9-12分页表示物理地址拥有四级页表,微软将这四级依次命名为PXE、PPE、PDE、PTE这四项。

关于内存管理和分页模式,不同的操作系统和体系结构可能会有略微不同的实现方式。9-9-9-9-12的分页模式是一种常见的分页方案,其中物理地址被分成四级页表:PXE(Page Directory Pointer Table Entry)、PPE(Page Directory Entry)、PDE(Page Table Entry)和PTE(Page Table Entry)。这种分页模式可以支持大量的物理内存地址映射到虚拟内存地址空间中。每个级别的页表都负责将虚拟地址映射到更具体的物理地址。通过这种层次化的页表结构,操作系统可以更有效地管理和分配内存。

首先一个PTE管理1个分页大小的内存也就是0x1000字节,PTE结构的解析非常容易,打开WinDBG输入!PTE 0即可解析,如下所示,当前地址0位置处的PTE基址是FFFF898000000000,由于PTE的一个页大小是0x1000所以当内存地址高于0x1000时将会切换到另一个页中,如下FFFF898000000008则是另一个页中的地址。

0: kd> !PTE 0
                                           VA 0000000000000000
PXE at FFFF89C4E2713000    PPE at FFFF89C4E2600000    PDE at FFFF89C4C0000000    PTE at FFFF898000000000
contains 8A0000000405F867  contains 0000000000000000
pfn 405f      ---DA--UW-V  not valid

0: kd> !PTE 0x1000
                                           VA 0000000000001000
PXE at FFFF89C4E2713000    PPE at FFFF89C4E2600000    PDE at FFFF89C4C0000000    PTE at FFFF898000000008
contains 8A0000000405F867  contains 0000000000000000
pfn 405f      ---DA--UW-V  not valid

由于PTE是动态变化的,找到该地址的关键就在于通过MmGetSystemRoutineAddress函数动态得到MmGetVirtualForPhysical的内存地址,然后向下扫描特征寻找mov rdx,0FFFF8B0000000000h并将内部的地址提取出来。

这段代码完整版如下所示,代码可动态定位到PTE的内存地址,然后将其取出;

// 署名权
// right to sign one's name on a piece of work
// PowerBy: LyShark
// Email: me@lyshark.com

#include <ntifs.h>
#include <ntstrsafe.h>

// 指定内存区域的特征码扫描
PVOID SearchMemory(PVOID pStartAddress, PVOID pEndAddress, PUCHAR pMemoryData, ULONG ulMemoryDataSize)
{
	PVOID pAddress = NULL;
	PUCHAR i = NULL;
	ULONG m = 0;

	// 扫描内存
	for (i = (PUCHAR)pStartAddress; i < (PUCHAR)pEndAddress; i++)
	{
		// 判断特征码
		for (m = 0; m < ulMemoryDataSize; m++)
		{
			if (*(PUCHAR)(i + m) != pMemoryData[m])
			{
				break;
			}
		}
		// 判断是否找到符合特征码的地址
		if (m >= ulMemoryDataSize)
		{
			// 找到特征码位置, 获取紧接着特征码的下一地址
			pAddress = (PVOID)(i + ulMemoryDataSize);
			break;
		}
	}

	return pAddress;
}

// 获取到函数地址
PVOID GetMmGetVirtualForPhysical()
{
	PVOID VariableAddress = 0;
	UNICODE_STRING uioiTime = { 0 };

	RtlInitUnicodeString(&uioiTime, L"MmGetVirtualForPhysical");
	VariableAddress = (PVOID)MmGetSystemRoutineAddress(&uioiTime);
	if (VariableAddress != 0)
	{
		return VariableAddress;
	}
	return 0;
}

// 驱动卸载例程
VOID UnDriver(PDRIVER_OBJECT driver)
{
	DbgPrint("Uninstall Driver \n");
}

// 驱动入口地址
NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath)
{
	DbgPrint("Hello LyShark \n");

	// 获取函数地址
	PVOID address = GetMmGetVirtualForPhysical();

	DbgPrint("GetMmGetVirtualForPhysical = %p \n", address);

	UCHAR pSecondSpecialData[50] = { 0 };
	ULONG ulFirstSpecialDataSize = 0;

	pSecondSpecialData[0] = 0x48;
	pSecondSpecialData[1] = 0xc1;
	pSecondSpecialData[2] = 0xe0;
	ulFirstSpecialDataSize = 3;

	// 定位特征码
	PVOID PTE = SearchMemory(address, (PVOID)((PUCHAR)address + 0xFF), pSecondSpecialData, ulFirstSpecialDataSize);
	__try
	{
		PVOID lOffset = (ULONG)PTE + 1;
		DbgPrint("PTE Address = %p \n", lOffset);
	}
	__except (EXCEPTION_EXECUTE_HANDLER)
	{
		DbgPrint("error");
	}

	Driver->DriverUnload = UnDriver;
	return STATUS_SUCCESS;
}

运行如上代码可动态获取到当前系统的PTE地址,然后将PTE填入到g_PTEBASE中,即可实现解析系统内的四个标志位,完整解析代码如下所示;

// 署名权
// right to sign one's name on a piece of work
// PowerBy: LyShark
// Email: me@lyshark.com

#include <ntifs.h>
#include <ntstrsafe.h>

INT64 g_PTEBASE = 0;
INT64 g_PDEBASE = 0;
INT64 g_PPEBASE = 0;
INT64 g_PXEBASE = 0;

PULONG64 GetPteBase(PVOID va)
{
	return (PULONG64)((((ULONG64)va & 0xFFFFFFFFFFFF) >> 12) * 8) + g_PTEBASE;
}

PULONG64 GetPdeBase(PVOID va)
{
	return (PULONG64)((((ULONG64)va & 0xFFFFFFFFFFFF) >> 12) * 8) + g_PDEBASE;
}

PULONG64 GetPpeBase(PVOID va)
{
	return (PULONG64)((((ULONG64)va & 0xFFFFFFFFFFFF) >> 12) * 8) + g_PPEBASE;
}

PULONG64 GetPxeBase(PVOID va)
{
	return (PULONG64)((((ULONG64)va & 0xFFFFFFFFFFFF) >> 12) * 8) + g_PXEBASE;
}

// 驱动卸载例程
VOID UnDriver(PDRIVER_OBJECT driver)
{
	DbgPrint("Uninstall Driver \n");
}

// 驱动入口地址
NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath)
{
	DbgPrint("Hello LyShark \n");

	g_PTEBASE = 0XFFFFF20000000000;

	g_PDEBASE = (ULONG64)GetPteBase((PVOID)g_PTEBASE);
	g_PPEBASE = (ULONG64)GetPteBase((PVOID)g_PDEBASE);
	g_PXEBASE = (ULONG64)GetPteBase((PVOID)g_PPEBASE);

	DbgPrint("PXE = %p \n", g_PXEBASE);
	DbgPrint("PPE  = %p \n", g_PPEBASE);
	DbgPrint("PDE  = %p \n", g_PDEBASE);
	DbgPrint("PTE  = %p \n", g_PTEBASE);

	Driver->DriverUnload = UnDriver;
	return STATUS_SUCCESS;
}

我的系统内PTE地址为0XFFFFF20000000000,填入变量内解析效果如下图所示;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/582084.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

七年老程序员的三四月总结:三十岁、准备婚礼、三次分享

你好&#xff0c;我是 shixin&#xff0c;一名工作七年的安卓开发。 每两个月我会做一次总结&#xff0c;记下这段时间里有意义的事和值得反复看的内容&#xff0c;为的是留一些回忆、评估自己的行为、沉淀有价值的信息。 一转眼 2023 年过去了三分之一&#xff0c;这两个月经历…

【数据湖仓架构】数据湖和仓库:Databricks 和 Snowflake

是时候将数据分析迁移到云端了。我们比较了 Databricks 和 Snowflake&#xff0c;以评估基于数据湖和基于数据仓库的解决方案之间的差异。 在这篇文章中&#xff0c;我们将介绍基于数据仓库和基于数据湖的云大数据解决方案之间的区别。我们通过比较多种云环境中可用的两种流行技…

HTML+CSS+JavaScript制作弹幕效果

全屏弹幕 <!DOCTYPE html> <html> <head><meta charset"UTF-8"><title>弹幕效果</title><style>/* 设置弹幕的样式 */.bullet {position: absolute;font-size: 20px;color: white;text-shadow: 1px 1px 1px black;white-s…

用Python让小朋友的手绘图跳起来(附源码)

大家好&#xff0c;我是小F&#xff5e; 今天给大家介绍一个非常有趣的项目&#xff0c;基于AI识别&#xff0c;制作儿童手绘图舞蹈图。 只需几分钟&#xff0c;就能自动生成儿童手绘人物或类人角色&#xff08;即具有双臂、两条腿等的角色&#xff09;的动画&#xff0c;而且生…

波奇学C++:模板和STL

什么是模板&#xff1f;为什么我们需要模板&#xff1f; 先假设一个场景&#xff0c;我们要编写一个函数交换a,b两个数的值 void swap(int& a,int& b) {int cmpa;ab;ba; } swap函数可以帮我们交换两个int型的值&#xff0c;那如果要交换的类型是float&#xff0c;do…

基础篇010.1 STM32驱动RC522 RFID模块之一:基础知识

目录 1. RFID概述 1.1 RFID工作原理 1.2 RFID分类 1.3 RFID模块 1.4 RFID卡片 1.5 IC卡和ID卡介绍 1.6 IC卡和ID的区分 2. Mifare卡结构原理 2.1 Mifare卡概述 2.2 Mifare非接触式 IC 卡性能简介&#xff08;M1&#xff09; 2.2.1 Mifare S50与Mifare S70 2.2.2 S5…

操作系统的发展史

█ DOS操作系统 上期提到&#xff0c;20世纪70年代&#xff0c;伴随着计算机技术的成熟&#xff0c;操作系统也进入了一个快速发展阶段。现代操作系统的概念&#xff0c;也在那一时期逐渐形成。 1975年初&#xff0c;MITS电脑公司推出了基于Intel 8080芯片的Altair 8800微型计算…

7 种常见的路由协议

网络路由是网络通信的重要组成部分&#xff0c;通过互联网将信息从源地址移动到目的地的过程。路由发生在 OSI 模型的第 3 层&#xff08;网络层&#xff09;。实际网络中通常会将静态和动态路由结合使用。静态路由适用于小型网络&#xff0c;而动态路由适用于大型网络。 什么…

Office project 2013安装

哈喽&#xff0c;大家好。今天一起学习的是project 2013的安装&#xff0c;Microsoft Office project项目管理工具软件&#xff0c;凝集了许多成熟的项目管理现代理论和方法&#xff0c;可以帮助项目管理者实现时间、资源、成本计划、控制。有兴趣的小伙伴也可以来一起试试手。…

Anthropic 推出 Claude ,一款与ChatGPT竞争的聊天机器人

最近&#xff0c;谷歌承诺向 Anthropic 投资 3 亿美元&#xff0c;收购这家初创公司 10% 的股份。 Anthropic 是一家由前 OpenAI 员工共同创立的初创公司&#xff0c;近日推出一款与ChatGPT对标的产品。 Anthropic 名为 Claude 的人工智能聊天机器人&#xff0c;可以被指示执行…

【Zero to One系列】window系统安装Linux、docker

1、在window系统安装Linux&#xff08;开启微软的Linux子系统功能-WSL&#xff09; 1.1 什么是WSL&#xff1f; 传送门&#xff1a;适用于 Linux 的 Windows 子系统安装指南 (Windows 10) 链接里有全部的步骤 1.2 开启 WSL 在 控制面板-->程序和功能 页面找到 Windows 功…

【运维知识进阶篇】Ansible自动化运维-PlayBook详解

这篇文章给大家介绍下PlayBook&#xff0c;我们叫它剧本&#xff0c;它是以一种固定的格式&#xff0c;将多个ad-hoc放入yml文件中。在Ansible中&#xff0c;剧本文件是yml结尾的&#xff0c;在SaltStack中剧本文件是sls结尾的&#xff0c;但是两者语法都是使用的yaml语法。 P…

军用电子元器件质量如何界定?

为了保证元器件的质量&#xff0c;我国制定了一系列的元器件标准。在上世纪70年代末期制定了“七专”7905技术协议和80年代初制定了“七专”8406技术协议&#xff0c;已具备了军用器件标准的雏形&#xff0c;但标准是在改革开放之前制定的&#xff0c;有很多局限性&#xff0c;…

Studio One6简体中文版全新版本功能详解

Studio One 6是一款强大的音乐编曲软件,可以帮助您使用灵活的和弦轨道功能实现音乐创作。通过新的智能模板、直观的拖放工作流、可定制的用户界面和强大的集成工具&#xff0c;使创建快速而轻松。 无论你选择 Studio One 哪个版本&#xff0c;你都可以得到无限的音轨、通道和插…

ChatGPT强到离谱,这么十一款ChatGPT浏览器插件你值得拥有

&#x1f517; 运行环境&#xff1a;ChatGPT &#x1f6a9; 撰写作者&#xff1a;左手の明天 &#x1f947; 精选专栏&#xff1a;《python》 &#x1f525; 推荐专栏&#xff1a;《算法研究》 #### 防伪水印——左手の明天 #### &#x1f497; 大家好&#x1f917;&#x1f9…

【ChatGPT功能挖掘】论文绘图救星!

前言 &#x1f497;未来全网粉丝100W、全栈领域优质创作者、掘金、阿里云等社区博客专家、专注于全栈领域和毕业项目实战&#x1f497; 今天分享一个使用ChatGPT来解决绘图没有思路、不知如何下手的问题&#xff01; 注意看&#xff01;全文干货&#xff0c;无废话&#xff01…

路径规划 | 图解RRT*算法(附ROS C++/Python/Matlab仿真)

目录 0 专栏介绍1 图解RRT*算法原理2 ROS C算法实现3 Python算法实现4 Matlab算法实现 0 专栏介绍 &#x1f525;附C/Python/Matlab全套代码&#x1f525;课程设计、毕业设计、创新竞赛必备&#xff01;详细介绍全局规划(图搜索、采样法、智能算法等)&#xff1b;局部规划(DWA…

chatgpt赋能python:使用Numpy在Python中进行科学计算

使用Numpy在Python中进行科学计算 对于需要进行科学计算和数据分析的程序员&#xff0c;Python是一个非常有用的编程语言。而Numpy&#xff08;Numerical Python&#xff09;则是Python生态系统中最受欢迎和广泛使用的科学计算库之一。该库提供了高效的数组操作&#xff0c;线…

跟着我学 AI丨知识图谱,搜索的根

搜索是现在大家都很熟悉的功能&#xff0c;同时也是我们搜集信息离不开的重要手段。而搜索之所以能帮助我们获取到对应的信息&#xff0c;其实离不开知识图谱的重要支撑。知识图谱是什么呢&#xff1f;为什么能够支撑起搜索的提升呢&#xff1f;今天我们就来认识一下知识图谱。…

36从零开始学Java之到底什么是方法的重载?

作者&#xff1a;孙玉昌&#xff0c;昵称【一一哥】&#xff0c;另外【壹壹哥】也是我哦 千锋教育高级教研员、CSDN博客专家、万粉博主、阿里云专家博主、掘金优质作者 前言 壹哥在之前给大家讲解构造方法的时候说过&#xff0c;在一个类中&#xff0c;可以定义多个构造方法&a…