Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
mmiotic — 无文档硬件的延迟 X 射线透视 | Kitploit
工具/GitHubGitHub/xoreaxeaxeax/mmiotic
侦察逆向工程信息收集硬件黑客硬件安全
GitHubxoreaxeaxeax/mmiotic

mmiotic

无文档硬件的延迟 X 射线透视

查看仓库
13399天前Kitploit 审核通过

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

mmiotic

一个用于 MMIO 时序分析的探索性工具——对任意物理地址计时,并从延迟中剖析硬件。

MMIO latency heatmap

它出人意料地适用于硬件逆向工程、虚拟机监控程序指纹识别、设备活动的侧信道分析、寄存器特征刻画、校准恶意触发条件,以及构造超长机器指令。

示例

逆向工程内存范围

物理内存的第一个兆字节是一个简单的入门示例,尽管其结构已广为人知。

first megabyte heatmap

延迟边界让我们能够划分地址空间,而无需依赖报告的内存布局。

  1. 从一个简单的延迟扫描开始:sudo ./mmiotic --start-address 0x0 --end-address 0x100000 --stride 4 --count 20 --quiet-mmap
  2. 延迟恰好落在经典的边界上——DRAM 到 0x9FFFF 约 380 周期,然后是 128 KB 的视频空洞,它在 0xB0000 处一分为二。0x20000 处方差的变化可能表明对空页采用了不同的页表遍历。
  3. A0000–AFFFF:缓慢且抖动(996 周期,标准差 327),被路由到已上电但空闲的 Radeon。B0000–BFFFF:快速且稳定(780 周期,标准差 3.2,读出 ffffffff),无人认领。数据看似相似,但方差相差 100 倍。
  4. C0000–FFFFF:/proc/iomem 显示为 "System ROM",但扫描显示的是 DRAM 延迟,而非闪存速度——BIOS 已被映射到 DRAM 中。

未文档化的邮箱寄存器

扫描根复合体配置空间(00:00.0,4 KB),寻找相对于约 675 周期平坦基线的延迟异常点:

mailbox register heatmap

邮箱延迟显著高于周围的数据,而重复出现的尖峰和等效的方差让我们能够匹配功能相似的寄存器。

  1. 扫描根复合体配置空间:sudo ./mmiotic --start-address 0xf8000000 --end-address 0xf8001000 --stride 4 --count 200
  2. 两个双字是异常点:偏移 0xe4(1218 周期,值 80e3110b)和 0xa4(1199 周期,值 deadbeef)。e4 是有文档记载的门铃寄存器;a4 则无文档记载。
  3. 延迟几乎相同,相隔 0x40,且都远高于基线——同一寄存器家族访问同一个片外目标,其中只有 e4 是公开的。
  4. 读取的值不同:deadbeef 读作未初始化/错误哨兵值——同一邮箱,a4 未实现或接收了无效输入。

中断校准

精心挑选的延迟有时可用于不寻常的漏洞利用场景(MCHAMMER、smiiiiiiiiiiiiiiii):

interrupt calibration heatmap

在这里,一块空闲且未加载驱动的 Radeon 将一次对齐的 4 字节读取变成约 100,000 周期的停顿。

  1. sudo ./mmiotic --start-address 0x90e00000 --end-address 0x90e00100 --stride 4 --count 50 — 扫描 GPU BAR 的起始部分(0x90e00000,256 KB)。0x90e00008 耗时 110,152 周期;偏移 16 字节的 0x90e00018 又恢复快速,为 1,523——按寄存器区分,而非按页区分。
  2. sudo ./mmiotic --start-address 0x90e00000 --end-address 0x90e40000 --stride 4 --count 1 --binary — --binary 按位反转顺序探测,因此在 1,012 次探测后,整个 256 KB 窗口被均匀覆盖,映射出一个连续的 48 KB 块,其中每个寄存器都很慢。
  3. 这一延迟很可能源于一次用于解除时钟/电源门控域的 SMU 往返——因此延迟图能够还原 GPU 的电源布局,无需驱动或数据手册。

致命窥探

理想情况下,读取物理地址应当是相对安全的操作,但 mmiotic 尤其擅长意外地发现例外:

killer peek heatmap

例如,在上述平台上,对 0xdc5003b0 的 1 字节读取——未加载驱动的 Zen 4 iGPU 寄存器 BAR(区域 5,0xdc500000,512 KB)的偏移 0x3b0——会可靠地导致系统复位。

  1. sudo ./mmiotic --address 0xdc5003b0 --size 1 --count 1。没有任何输出;机器直接重启。
  2. 恰好只有一个双字:两侧的 0x3ac 和 0x3b4 以约 3,200 周期读出 00000000,均无害。
  3. 对 0x3a0–0x3fc 逐双字扫描,发现 7 个有害双字与 17 个安全双字交错排列。
  4. 如果不想绕弯子,sudo busybox devmem 0xdc5003b0 32 与 sudo dd if=/dev/mem bs=1 count=1 skip=$((0xdc5003b0)) 同样能让机器宕机。

用法

[!WARNING] 某些平台在被 mmiotic 探测特定地址区域时会直接复位。请谨慎选择使用环境。

目标定位

ECAM 基址和大小从 ACPI MCFG(/sys/firmware/acpi/tables/MCFG)自动检测。可通过 -M, --mmio-base / -Z, --mmio-size 覆盖。

扫描

--find-target/--find-longest 将扫描转变为搜索:

选项作用
-F, --find-target <s>找到访问时间达到 s 秒的地址,然后升级宽度(非对齐 4b → 8/16/32/64/512b)以进一步提高
-G, --find-longest相同的搜索,但穷尽所有候选者,而非在首次命中时停止
-B, --fallbacks <n>带入升级阶段的候选者数量(默认:10)

访问方式

输出 / 执行

结果行

root@kitploit:~
b/d/f.o.l: 00:02:00.00.4  address: 00000000f0100000  min:      312  max:      480  stdev:      2.1  dynamic: 0  value: 8086abcd

-T 为周期计数添加 cy 后缀,并插入经过换算的最小/最大时间对(-N 以原始纳秒打印它们):

root@kitploit:~
b/d/f.o.l: 00:02:00.00.4  address: 00000000f0100000  min:      312 cy  max:      480 cy  (   104 ns/   160 ns)  stdev:      2.1  dynamic: 0  value: 8086abcd

构建

构建:

root@kitploit:~
make

需要以 root 身份运行,以获得 /dev/mem 的访问权限。

如果看到:mmap ... Operation not permitted,请尝试以 iomem=relaxed 启动内核,以解除 CONFIG_STRICT_DEVMEM 的限制:

root@kitploit:~
# /etc/default/grub
GRUB_CMDLINE_LINUX="iomem=relaxed nopat"

然后执行 sudo update-grub 并重启。

实战应用

mmiotic 已被用于推进多项内部与外部研究,有时用途出人意料。以下是一些 mmiotic 的应用示例:

  • MCHAMMER:mmiotic 校准延迟的 机器检查异常,以将 MC# 信号精确投递至受保护环境。

  • smiiiiiiiiiiiiiiii: mmiotic 解析用于打破 SMM 会合的高延迟指令。

  • The Assembly Hall of Shame: mmiotic 被广泛用于性能去优化这一重要课题。

作者

mmiotic 是 Christopher Domas(@xoreaxeaxeax)的一项研究工作。

下载工具
选项名称
-b/-d/-f/-rPCI --bus/--device/--function/--register — 基于 ECAM 基址解码
-o, --offset <n>相对于 MMIO 基址的偏移(跳过 B/D/F 解码)
-A, --address <n>单个物理地址;隐式设置区域基址
-a/-z--start-address/--end-address — 一个物理范围;隐含启用 --scan
选项作用
-S, --scan遍历目标区域中的所有地址
-t, --stride <n>地址之间的步长(默认:4)
-n, --limit <n>探测到该数量的地址后停止
--binary按位反转顺序探测——经过 k 次探测后,该范围以约 range/k 的粒度获得均匀覆盖(见上面的警告)
-x, --limited受限寄存器范围(0x00–0xff,而非 0x000–0xfff)
-e, --skip跳过在偏移 0 处读出 0xffffffff 的功能(不存在的设备)
-I, --iomem扫描 /proc/iomem 中所有非 System-RAM 的顶级区域
-R, --ioregion <name>扫描 /proc/iomem 中标签匹配 <name> 的区域,任意深度
选项作用
-s, --size <n>每次访问的字节数:1 / 2 / 4(默认)/ 8 / 16(XMM)/ 32(YMM)/ 64(ZMM)/ 512(fxrstor)。大于 4 的大小超出规范,但在测试过的硬件上可用;AVX 宽度需要 AVX / AVX-512F
-c, --count <n>每个地址的采样次数(默认:1);报告最小值
-L, --lock对锁定的 RMW 计时:lock xadd(大小 1/2/4/8)或 lock cmpxchg16b(大小 16)。将值写回
-g, --gather对向量化 gather 计时;--size 16/32/64 选择 XMM/YMM/ZMM(AVX-512)
-w, --write-read通过对必须观察到先前 posted write 的读取计时,来捕捉写入延迟——见下文
-E, --enter(--enter-2、--enter-3)从一条 enter $0, $31 驱动多达 30 次访问的突发——见下文
-k, --continue在 fxrstor 出错时,丢弃该样本并继续扫描
选项作用
-C, --min-cycles <n>仅打印满足 min_cycles >= n 的结果
-T, --time在周期之外同时显示纳秒(检测 TSC 频率)
-N, --nanosecond与 --time 一起使用时,打印原始纳秒,不做单位换算
-P, --progress在 stderr 上实时显示扫描进度
-p, --processor <n>固定到逻辑 CPU n(默认:0)— 减少计时器噪声
-u, --unbound不固定到任何核心
--lazy-mmap按需以 2 GB 窗口映射;大于 2 GB 的区域必需
--quiet-mmap抑制来自不可访问区域的 "mmap failed" 噪声
字段含义
b/d/f.o.l总线/设备/功能、寄存器偏移、访问大小
offset相对于 MMIO 基址的偏移 —— 当目标来自 -o/-A/-a+-z 时替代 b/d/f.o.l
address完整的 64 位物理地址
min/max观察到的最快和最慢访问,以周期计
stdev采样周期计数的标准差
dynamic如果值在样本间任意时刻发生变化则为 1
value读取的值 —— 对于超过 8 字节的大小,显示前 32 字节,以空格分隔的 qword 表示
faults仅当某次访问出错时附加