Files
OpenMaidEngine/tools/frida/test_map_imports.py
gamer147 94a4763961 re(frida): import-map recon — export scan + clustering gate
GATE-PASS: 23342 exports mapped, 277 in-range pointer matches clustering
into a module-resident import table at RVA 0x16f000 (VA 0x56f000);
23 singletons. ~254 real imports vs pe-sieve's 17-in-noise.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 09:21:16 -04:00

73 lines
2.5 KiB
Python

"""Unit tests for the pure scan/match/cluster logic in map_imports.py.
Run: py -3.11 -X utf8 tools/frida/test_map_imports.py (plain runner, no pytest; frida not needed).
"""
import struct
import sys
from map_imports import build_export_index, scan_pointer_matches, cluster_runs
FAILS = []
def check(cond, msg):
if not cond:
FAILS.append(msg)
print("FAIL:", msg)
else:
print("ok:", msg)
def test_export_index_canonicalizes():
idx = build_export_index([
{"address": 0x76d80e70, "name": "LoadLibraryA", "module": "kernel32.dll"},
{"address": 0x76d7f7f0, "name": "GetProcAddress", "module": "kernel32.dll"},
])
check(idx[0x76d80e70] == "kernel32.dll!LoadLibraryA", "index maps addr -> dll!func")
def test_export_index_first_name_wins_and_skips_zero():
idx = build_export_index([
{"address": 0x1000, "name": "First", "module": "a.dll"},
{"address": 0x1000, "name": "Second", "module": "a.dll"}, # alias -> ignored
{"address": 0x0, "name": "Nope", "module": "a.dll"}, # null addr -> skipped
])
check(idx[0x1000] == "a.dll!First" and 0x0 not in idx, "first name wins; null addr skipped")
def test_scan_matches_little_endian_aligned():
idx = {0x76d80e70: "kernel32.dll!LoadLibraryA", 0x76d7f7f0: "kernel32.dll!GetProcAddress"}
mem = bytearray(0x20)
struct.pack_into("<I", mem, 0x10, 0x76d80e70)
struct.pack_into("<I", mem, 0x14, 0x76d7f7f0)
struct.pack_into("<I", mem, 0x18, 0x12345678) # not an export -> no match
m = scan_pointer_matches(bytes(mem), 0x400000, idx)
check([(r, v) for r, v, _ in m] == [(0x10, 0x76d80e70), (0x14, 0x76d7f7f0)],
"scan finds aligned LE pointer matches, skips non-exports")
def test_scan_ignores_unaligned():
idx = {0x76d80e70: "kernel32.dll!LoadLibraryA"}
mem = bytearray(0x10)
struct.pack_into("<I", mem, 0x2, 0x76d80e70) # unaligned -> ignored
check(scan_pointer_matches(bytes(mem), 0x400000, idx) == [], "unaligned pointer ignored")
def test_cluster_runs_groups_contiguous():
check(cluster_runs([0x100, 0x104, 0x108, 0x200]) == [(0x100, 3), (0x200, 1)],
"cluster groups contiguous aligned runs, isolates singleton")
def main():
test_export_index_canonicalizes()
test_export_index_first_name_wins_and_skips_zero()
test_scan_matches_little_endian_aligned()
test_scan_ignores_unaligned()
test_cluster_runs_groups_contiguous()
print("FAILURES:", len(FAILS))
return 1 if FAILS else 0
if __name__ == "__main__":
sys.exit(main())