Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
mmiotic — 문서화되지 않은 하드웨어의 지연 시간 엑스레이 | Kitploit
도구/GitHubGitHub/xoreaxeaxeax/mmiotic
ReconnaissanceReverse EngineeringInformation GatheringHardware HackingHardware Security
GitHubxoreaxeaxeax/mmiotic

mmiotic

문서화되지 않은 하드웨어의 지연 시간 엑스레이

저장소 보기
133910일 전Kitploit 검토 완료

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

mmiotic

MMIO 타이밍을 탐구하는 도구 — 임의의 물리 주소를 타이밍하고, 레이턴시로부터 하드웨어를 분석한다.

MMIO latency heatmap

하드웨어 리버스 엔지니어링, 하이퍼바이저 핑거프린팅, 장치 활동의 사이드 채널링, 레지스터 특성 규명, 악성 트리거 보정, 그리고 터무니없이 긴 머신 명령어 제작에 의외로 유용하다.

예제

메모리 범위 리버스 엔지니어링

물리 메모리의 첫 1MB는 구조가 이미 잘 알려져 있더라도 시작하기 쉬운 예제다.

first megabyte heatmap

레이턴시 경계를 통해 보고된 레이아웃에 의존하지 않고 주소 공간을 분할할 수 있다.

  1. 간단한 레이턴시 스캔으로 시작: sudo ./mmiotic --start-address 0x0 --end-address 0x100000 --stride 4 --count 20 --quiet-mmap
  2. 레이턴시는 전형적인 경계에 위치한다 — 0x9FFFF까지 DRAM이 약 380 cy, 그 다음 128KB 비디오 홀(video hole)이 0xB0000에서 둘로 나뉜다. 0x20000에서의 분산 변화는 널 페이지에 대한 서로 다른 페이지 워크를 나타낼 수 있다.
  3. A0000–AFFFF: 느리고 지터가 큼 (996 cy, stdev 327), 전원은 켜졌지만 유휴 상태인 Radeon으로 라우팅됨. B0000–BFFFF: 빠르고 일정함 (780 cy, stdev 3.2, ffffffff 읽음), 아무도 사용하지 않음. 유사해 보이는 데이터지만 100배의 분산 차이가 있다.
  4. C0000–FFFFF: /proc/iomem은 "System ROM"이라고 말하지만, 스캔 결과는 플래시 속도가 아닌 DRAM 레이턴시를 보여준다 — BIOS가 DRAM에 섀도잉되어 있다.

문서화되지 않은 메일박스 레지스터

루트 컴플렉스 구성 공간(00:00.0, 4KB)을 스캔하여 약 675사이클 평탄층 대비 레이턴시 이상치를 찾는다:

mailbox register heatmap

메일박스 레이턴시는 주변 데이터보다 상당히 높으며, 중복된 스파이크와 동등한 분산 덕분에 기능적으로 유사한 레지스터를 서로 매칭할 수 있다.

  1. 루트 컴플렉스 구성 공간 스캔: sudo ./mmiotic --start-address 0xf8000000 --end-address 0xf8001000 --stride 4 --count 200
  2. 두 개의 dword가 이상치다: 오프셋 0xe4 (1218 cy, 값 80e3110b)와 0xa4 (1199 cy, 값 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, 256KB)의 머리를 스윕한다. 0x90e00008은 110,152 cy가 소요되고, 16바이트 떨어진 0x90e00018은 다시 빠르게 1,523이다 — 페이지 단위가 아닌 레지스터 단위다.
  2. sudo ./mmiotic --start-address 0x90e00000 --end-address 0x90e40000 --stride 4 --count 1 --binary — --binary는 비트 역순으로 프로브하므로 1,012회 프로브 후 전체 256KB 에퍼처가 균일하게 커버되며, 모든 레지스터가 느린 연속 48KB 블록이 매핑된다.
  3. 아마도 레이턴시는 클록/전력 게이트 영역의 게이트를 해제하기 위한 SMU 라운드트립 때문일 것이다 — 따라서 레이턴시 맵은 드라이버나 데이터시트 없이 GPU의 전력 레이아웃을 추출한다.

킬러 엿보기

이상적으로는 물리 주소를 읽는 것이 비교적 안전한 작업이어야 하지만, mmiotic은 우연히 예외를 찾아내는 데 특히 뛰어나다:

killer peek heatmap

예를 들어 위 플랫폼에서 1바이트 읽기 0xdc5003b0 — 드라이버가 없는 Zen 4 iGPU 레지스터 BAR(Region 5, 0xdc500000, 512KB)의 오프셋 0x3b0 — 은 시스템을 확실하게 리셋시킨다.

  1. sudo ./mmiotic --address 0xdc5003b0 --size 1 --count 1. 출력 없음; 박스가 재부팅된다.
  2. 정확히 하나의 dword: 양쪽의 0x3ac와 0x3b4는 약 3,200 cy로 00000000을 읽으며 무해하다.
  3. 0x3a0–0x3fc를 dword 단위로 스윕하면 17개의 안전한 dword 사이에 7개의 독 dword가 섞여 있다.
  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

/dev/mem에 접근하려면 root로 실행한다.

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은 성능 비최적화(deoptimization)라는 중요한 문제를 위해 광범위하게 사용된다.

저자

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 vs 0x000–0xfff)
-e, --skip오프셋 0에서 0xffffffff를 읽는 함수(부재 장치) 건너뜀
-I, --iomem/proc/iomem의 모든 비-System-RAM 최상위 영역 스캔
-R, --ioregion <name>레이블이 <name>과 일치하는 /proc/iomem 영역을 모든 깊이에서 스캔
옵션효과
-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이전 게시된 쓰기를 관찰해야 하는 읽기의 타이밍으로 쓰기 레이턴시 캡처 — 아래 참조
-E, --enter (--enter-2, --enter-3)하나의 enter $0, $31에서 최대 30회 액세스 버스트 구동 — 아래 참조
-k, --continuefxrstor 폴트 시 해당 샘플을 버리고 스캔 계속
옵션효과
-C, --min-cycles <n>min_cycles >= n인 결과만 출력
-T, --time사이클 옆에 나노초 표시 (TSC 주파수 감지)
-N, --nanosecond--time과 함께, 단위 스케일링 없이 원시 나노초 출력
-P, --progressstderr에 실시간 스캔 진행률 표시
-p, --processor <n>논리 CPU n에 고정 (기본값: 0) — 타이머 노이즈 감소
-u, --unbound코어에 고정하지 않음
--lazy-mmap2GB 창을 요청 시 매핑; 2GB를 초과하는 영역에 필요
--quiet-mmap접근 불가 영역의 "mmap failed" 노이즈 억제
필드의미
b/d/f.o.l버스/디바이스/펑션, 레지스터 오프셋, 액세스 크기
offsetMMIO 베이스로부터의 오프셋 — 대상이 -o/-A/-a+-z에서 비롯된 경우 b/d/f.o.l을 대체
address전체 64비트 물리 주소
min/max관측된 가장 빠른/가장 느린 액세스 (사이클)
stdev샘플링된 사이클 카운트의 표준 편차
dynamic샘플 전반에 걸쳐 값이 변경된 적이 있으면 1
value읽은 값 — 8바이트를 초과하는 크기의 경우 처음 32바이트를 공백으로 구분된 qword로 표시
faults액세스에 폴트가 발생한 경우에만 추가