安卓驱动跳板 PTE 物理映射读写
摘要
本文介绍一个基于 ARM64 页表项(PTE)直接操控的 Linux 内核模块,通过预先分配跳板页并动态修改其 PTE 映射,实现对任意用户态进程物理内存的透明读写。系统通过手动遍历五级页表(PGD→P4D→PUD→PMD→PTE)完成虚拟地址到物理地址的翻译,支持 1GB/2MB 大页识别与 4KB 标准页处理,并利用单页跳板 PTE 重映射技术绕过内核常规内存保护机制。配合软件 TLB 缓存优化,连续内存访问性能接近直接内存拷贝。整个过程对目标进程完全“透明”——不修改目标进程页表、不触发缺页异常。
一、技术背景与设计目标
1 传统内存访问的局限
在 Linux 内核中访问其他进程内存通常有以下方式:
| 方案 | 原理 | 缺陷 |
|------|------|------|
| `access_process_vm` | 内核标准接口 | 权限检查严格,受 `FOLL_FORCE` 限制 |
| `ioremap` | 建立新映射 | Device 属性导致非对齐崩溃,开销大 |
2 设计目标
透明性:目标进程无任何感知,不修改其页表结构
高效性:避免频繁的页表分配与释放,仅修改单个 PTE
灵活性:支持任意物理内存访问,包括大页映射
二、技术架构
2核心原理
只分配一次,永久复用。后续所有物理内存访问都通过修改这一个 PTE 实现。
三、前置知识
在这我就不讲述基本的内核和系统原理了
1 五级页表遍历
ARM64 Linux 采用五级页表(实际使用取决于配置):
```
虚拟地址
│
▼
[PGD] ──► [P4D] ──► [PUD] ──► [PMD] ──► [PTE] ──► 物理地址
512 512 512 512 512
entries entries entries entries entries
```
2 基本的寄存器
当然在本帖只用到了存放pgd的寄存器
4 ttbr1_el1寄存器布局
TTBR1_EL1 (Translation Table Base Register 1)
64-bit 寄存器布局:
+-----------------------------------------------------+
| BADDR[47:1] | ASID[63:48] |
+-----------------------------------------------------+
具体位分配:
bits [63:48] - ASID (Address Space Identifier)
bits [47:1] - BADDR (Base Address of translation table)
bit [0] - CnP (Common not Private)
5 arm64物理地址宽度
有俩个宽度分别是PA48和PA52
PA48(48位物理地址):
冰与火的战歌:Windows内核攻防实战高级班!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。
最后于 6小时前
被gongchuang编辑
,原因: