Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
Herramientas/GitHubGitHub/xoreaxeaxeax/mmiotic
ReconocimientoIngeniería InversaRecopilación de InformaciónHacking de HardwareSeguridad de Hardware
GitHubxoreaxeaxeax/mmiotic

mmiotic

Radiografía de latencia para hardware no documentado

Ver Repositorio
1339hace 10 díasRevisado por Kitploit

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

mmiotic

Una herramienta exploratoria para medir tiempos de MMIO: mide el tiempo de cualquier dirección física y disecciona el hardware a partir de la latencia.

Mapa de calor de latencia MMIO

Sorprendentemente útil para ingeniería inversa de hardware, fingerprinting de hipervisores, actividad de dispositivos por canales laterales, caracterización de registros, calibración de activadores maliciosos y creación de instrucciones de máquina absurdamente largas.

Ejemplos

Ingeniería inversa de rangos de memoria

El primer megabyte de memoria física es un ejemplo fácil para empezar, incluso si su estructura ya es bien conocida.

mapa de calor del primer megabyte

Los límites de latencia nos permiten delimitar el espacio de direcciones, sin depender de los diseños reportados.

  1. Comience con un escaneo de latencia simple: sudo ./mmiotic --start-address 0x0 --end-address 0x100000 --stride 4 --count 20 --quiet-mmap
  2. La latencia aterriza en los límites clásicos: DRAM hasta 0x9FFFF a ~380 ciclos, luego el hueco de video de 128 KB, que se divide en dos en 0xB0000. El cambio en la varianza en 0x20000 puede indicar un page walk diferente para la página nula.
  3. A0000–AFFFF: lento y con jitter (996 ciclos, desviación estándar 327), enrutado a la Radeon encendida pero inactiva. B0000–BFFFF: rápido y rígido (780 ciclos, desviación estándar 3.2, lee ffffffff), no reclamado por nadie. Datos de aspecto similar, pero una brecha de varianza de 100x.
  4. C0000–FFFFF: /proc/iomem dice "System ROM", pero el escaneo muestra latencia de DRAM, no velocidad de flash: la BIOS está sombreada en la DRAM.

Registros de buzón (mailbox) no documentados

Escanee el espacio de configuración del root complex (00:00.0, 4 KB) en busca de valores atípicos de latencia frente a un piso plano de ~675 ciclos:

mapa de calor de registros de buzón

La latencia del buzón es significativamente mayor que la de los datos circundantes, y los picos duplicados y las varianzas equivalentes nos permiten emparejar registros funcionalmente similares.

  1. Escanee el espacio de configuración del root complex: sudo ./mmiotic --start-address 0xf8000000 --end-address 0xf8001000 --stride 4 --count 200
  2. Dos dwords son los valores atípicos: el offset 0xe4 (1218 ciclos, valor 80e3110b) y 0xa4 (1199 ciclos, valor deadbeef). e4 es un doorbell documentado; a4 no está documentado.
  3. Latencia casi idéntica, separados por 0x40, ambos muy por encima del piso: una misma familia de registros que alcanza el mismo objetivo fuera del chip, de la cual solo e4 es público.
  4. Los valores difieren: deadbeef se lee como un centinela de error/no inicializado: mismo buzón, a4 no implementado o alimentado con entrada inválida.

Calibración de interrupciones

Ciertas latencias cuidadosamente seleccionadas a veces pueden usarse en escenarios de explotación inusuales (MCHAMMER, smiiiiiiiiiiiiiiii):

mapa de calor de calibración de interrupciones

Aquí, una Radeon inactiva y sin controlador convierte una lectura alineada de 4 bytes en una parada de ~100,000 ciclos.

  1. sudo ./mmiotic --start-address 0x90e00000 --end-address 0x90e00100 --stride 4 --count 50 — barra la cabecera del BAR de la GPU (0x90e00000, 256 KB). 0x90e00008 cuesta 110,152 ciclos; 0x90e00018, 16 bytes más adelante, vuelve a ser rápido a 1,523 — por registro, no por página.
  2. sudo ./mmiotic --start-address 0x90e00000 --end-address 0x90e40000 --stride 4 --count 1 --binary — --binary sondea en orden de inversión de bits, por lo que la apertura completa de 256 KB se cubre uniformemente después de 1,012 sondas, mapeando un bloque contiguo de 48 KB donde todos los registros son lentos.
  3. Probablemente, la latencia se deba a un viaje de ida y vuelta al SMU para desactivar el gate de un dominio con reloj/alimentación conmutados — así que el mapa de latencia extrae el diseño de alimentación de la GPU, sin necesidad de controlador ni datasheet.

Peek letal

Idealmente, leer una dirección física sería una operación relativamente segura, pero mmiotic es especialmente bueno encontrando las excepciones por accidente:

mapa de calor de peek letal

Por ejemplo, en la plataforma anterior, una lectura de 1 byte en 0xdc5003b0 — offset 0x3b0 de un BAR de registros de iGPU Zen 4 sin controlador (Región 5, 0xdc500000, 512 KB) — reinicia el sistema de forma fiable.

  1. sudo ./mmiotic --address 0xdc5003b0 --size 1 --count 1. Sin salida; la máquina se reinicia.
  2. Exactamente un dword: 0x3ac y 0x3b4 a cada lado leen 00000000 a ~3,200 ciclos y son inofensivos.
  3. Un barrido por dword de 0x3a0–0x3fc encuentra 7 dwords venenosos intercalados con 17 seguros.
  4. sudo busybox devmem 0xdc5003b0 32 y sudo dd if=/dev/mem bs=1 count=1 skip=$((0xdc5003b0)) tumban la máquina si prefieres saltarte el intermediario.

Uso

[!WARNING] Algunas plataformas se reiniciarán cuando mmiotic sondee regiones de direcciones específicas. Ten cuidado con dónde lo usas.

Selección de objetivo

La base y el tamaño ECAM se detectan automáticamente desde ACPI MCFG (/sys/firmware/acpi/tables/MCFG). Se puede sobrescribir con -M, --mmio-base / -Z, --mmio-size.

Escaneo

--find-target/--find-longest convierten el escaneo en búsqueda:

OpciónEfecto
-F, --find-target <s>encuentra una dirección cuyo tiempo de acceso alcance s segundos, luego escala el ancho (4b no alineado → 8/16/32/64/512b) para empujarlo más alto
-G, --find-longest

Método de acceso

Salida / ejecución

Líneas de resultado

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 añade el sufijo cy a los conteos de ciclos e inserta un par de tiempos min/max escalados (-N los imprime como nanosegundos crudos):

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

Configuración

Compilar:

root@kitploit:~
make

Se ejecuta como root para obtener acceso a /dev/mem.

Si ves: mmap ... Operation not permitted, prueba a arrancar con iomem=relaxed para levantar CONFIG_STRICT_DEVMEM:

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

Luego sudo update-grub y reinicia.

En la naturaleza

mmiotic se ha utilizado para avanzar diversas investigaciones internas y externas, a veces de formas inesperadas. Algunos ejemplos de aplicaciones de mmiotic:

  • MCHAMMER: mmiotic calibra una excepción de machine check retrasada para la entrega de precisión de señales MC# en entornos protegidos.

  • smiiiiiiiiiiiiiiii: mmiotic resuelve la instrucción de alta latencia para romper el rendezvous de SMM.

  • The Assembly Hall of Shame: mmiotic se usa ampliamente para el importante problema de la deoptimización de rendimiento.

Autor

mmiotic es un esfuerzo de investigación de Christopher Domas (@xoreaxeaxeax).

Descargar herramienta
OpciónNombres
-b/-d/-f/-rPCI --bus/--device/--function/--register — decodificado contra la base ECAM
-o, --offset <n>offset desde la base MMIO (omite la decodificación B/D/F)
-A, --address <n>una dirección física; establece la base de la región implícitamente
-a/-z--start-address/--end-address — un rango físico; implica --scan
OpciónEfecto
-S, --scanrecorre todas las direcciones en la región objetivo
-t, --stride <n>paso entre direcciones (por defecto: 4)
-n, --limit <n>se detiene después de esta cantidad de direcciones
--binarysondea en orden de inversión de bits — después de k sondas el rango tiene cobertura uniforme a granularidad ~range/k (ver la advertencia anterior)
-x, --limitedrango de registros limitado (0x00–0xff vs 0x000–0xfff)
-e, --skipomite funciones que leen 0xffffffff en el offset 0 (dispositivos ausentes)
-I, --iomemescanea toda región de nivel superior que no sea System-RAM en /proc/iomem
-R, --ioregion <name>escanea regiones de /proc/iomem cuya etiqueta coincida con <name>, a cualquier profundidad
misma búsqueda, pero agota todos los candidatos en lugar de detenerse en el primer acierto
-B, --fallbacks <n>candidatos llevados a la fase de escalado (por defecto: 10)
OpciónEfecto
-s, --size <n>bytes por acceso: 1 / 2 / 4 (por defecto) / 8 / 16 (XMM) / 32 (YMM) / 64 (ZMM) / 512 (fxrstor). Los tamaños > 4 están fuera de especificación pero funcionan en hardware probado; los anchos AVX necesitan AVX / AVX-512F
-c, --count <n>muestras por dirección (por defecto: 1); se reporta el mínimo
-L, --lockmide un RMW con bloqueo: lock xadd (tamaños 1/2/4/8) o lock cmpxchg16b (tamaño 16). Escribe el valor de vuelta
-g, --gathermide un gather vectorizado; --size 16/32/64 elige XMM/YMM/ZMM (AVX-512)
-w, --write-readcaptura la latencia de escritura midiendo una lectura que debe observar una escritura posted previa — ver abajo
-E, --enter (--enter-2, --enter-3)impulsa una ráfaga de hasta 30 accesos desde un solo enter $0, $31 — ver abajo
-k, --continueante un fallo de fxrstor, descarta esa muestra y continúa escaneando
OpciónEfecto
-C, --min-cycles <n>solo imprime resultados con min_cycles >= n
-T, --timemuestra nanosegundos junto a los ciclos (detecta la frecuencia TSC)
-N, --nanosecondcon --time, imprime nanosegundos crudos, sin escalado de unidades
-P, --progressprogreso de escaneo en vivo en stderr
-p, --processor <n>fija a la CPU lógica n (por defecto: 0) — reduce el ruido del temporizador
-u, --unboundno fijar a un núcleo
--lazy-mmapmapea en ventanas de 2 GB bajo demanda; requerido para regiones > 2 GB
--quiet-mmapsuprime el ruido de "mmap failed" de regiones inaccesibles
CampoSignificado
b/d/f.o.lbus/dispositivo/función, offset de registro, tamaño de acceso
offsetoffset desde la base MMIO — reemplaza a b/d/f.o.l cuando el objetivo provino de -o/-A/-a+-z
addressdirección física completa de 64 bits
min/maxacceso más rápido y más lento observado, en ciclos
stdevdesviación estándar de los conteos de ciclos muestreados
dynamic1 si el valor cambió en algún momento entre muestras
valuevalor leído — para tamaños superiores a 8 bytes, los primeros 32 bytes como qwords separados por espacios
faultsse agrega solo si un acceso falló