如何从具有内核 read/write 功能的 ARM64 程序中获取 swapper_pg_dir 地址?

How to get swapper_pg_dir address from an ARM64 program with kernel read/write capabilties?

我有一个可以读写内核内存的程序,我想得到swapper_pg_dir的地址。有问题的设备 运行 Android 采用 ARM64 架构并启用了 kASLR。

swapper_pg_dir 没有打印到 /proc/kallsyms 而我试图做的是从 System.map 获取 swapper_pg_dir 地址(通过编译内核源代码获得)并计算使用 /proc/kallsyms 的偏移量,并使用它来计算当前的 swapper_pg_dir 地址。但是结果地址似乎是错误的,因为程序无法从中读取内存(从这个地址读取内存 returns 一些字符串大多是格式 "u:object_r:####_prop:s0" 这通常发生在内存未映射时)

此外,刷新修改后的内核或加载内核模块也不是一种选择,因为引导加载程序在此设备中已锁定(并且不允许解锁)。

那么获取 swapper_pg_dir 地址的可能方法是什么?可以从将 this 作为变量的结构(其地址在 kallsyms 中导出或可以计算)中读取,但我还没有找到这样的结构。

你的最终目标是什么?

根据head.S

/*
 * swapper_pg_dir is the virtual address of the initial page table. We place
 * the page tables 3 * PAGE_SIZE below KERNEL_RAM_VADDR. The idmap_pg_dir has
 * 2 pages and is placed below swapper_pg_dir.
 */

并且KERNEL_RAM_VADDR是

#define KERNEL_RAM_VADDR    (PAGE_OFFSET + TEXT_OFFSET)

page_size可以从proc中查询到

这些地址将为您提供 swapper_pg_dir 的地址。

结构 init_mm 包含 swapper_pg_dir 地址。

struct mm_struct init_mm = {
[...]
  .pgd = swapper_pg_dir,
[...]
};

在我的例子中,它位于 init_mm 地址后 64 字节的地址。

使用以下命令。注意一定要配置内核。

cat /sys/kernel/debug/kernel_page_tables | grep swapper_pg_dir .