"""Bounded frozen-byte oracle for ActorLooking direction decode + movement caller. The harness runs the January target, the first natural candidate, and the frozen ordinary-Ninja candidate. It enters the genuine private decoder ABI and the genuine public ``actor_look_affect_movement`` caller. The reached ``normalize3d``, ``vector_from_points3d``, and ``valid_real_normal3d`` COFF bodies execute as machine code. Only genuine outside engine/CRT APIs are modeled, with their stack arguments decoded and recorded. This is deliberately finite evidence. In particular, the January decoder inlines its first normal-vector validity test while the candidates call the byte-identical out-of-line helper. The corpus exercises both x87 control words but is not exhaustive proof at floating-point decision boundaries. The script writes only a new JSON path under ``scratch``. It never compiles, invokes Ninja, edits production/configuration files, or mutates input objects. Negative controls alter copies of already-relocated candidate bytes in memory. """ from __future__ import annotations import argparse from collections import Counter import hashlib import json import math from pathlib import Path import re import struct import sys import unicorn as u from unicorn.x86_const import ( UC_X86_REG_EAX, UC_X86_REG_EBP, UC_X86_REG_EBX, UC_X86_REG_ECX, UC_X86_REG_EDI, UC_X86_REG_EDX, UC_X86_REG_EFLAGS, UC_X86_REG_EIP, UC_X86_REG_ESI, UC_X86_REG_ESP, UC_X86_REG_FPCW, UC_X86_REG_FPSW, UC_X86_REG_FPTAG, ) SCRIPT = Path(__file__).resolve() ROOT = next(parent for parent in SCRIPT.parents if (parent / "tools/coff_compare.py").is_file()) sys.path.insert(0, str(ROOT)) from tools import coff_compare as cc # noqa: E402 from tools.campaign._coff_tools import function_sections # noqa: E402 from tools.regression_gate import _section_aux_selection # noqa: E402 TARGET = ROOT / "scratch/actor-looking-decoder-before-20260906/files/build/split/source/ai/actor_looking.obj" FIRST = ROOT / "scratch/actor-looking-decoder-first-20260906.obj" ACTUAL = ROOT / "scratch/actor-looking-decoder-first-20260906/source/ai/actor_looking.obj" BEFORE_MANIFEST = ROOT / "scratch/actor-looking-decoder-before-20260906.json" FIRST_MANIFEST = ROOT / "scratch/actor-looking-decoder-first-20260906.json" BEFORE_STABLE = ROOT / "scratch/actor-looking-decoder-before-stable-20260906.json" FIRST_STABLE = ROOT / "scratch/actor-looking-decoder-first-stable-20260906.json" CACHEBETA = ROOT / "cachebeta.exe" TARGET_ALERT = ROOT / "build/split/source/ai/action_alert.obj" TARGET_CHARGE = ROOT / "build/split/source/ai/action_charge.obj" TARGET_COMBAT = ROOT / "build/split/source/ai/actor_combat.obj" OUTPUT_DEFAULT = ROOT / "scratch/actor-looking-decoder-runtime-report.json" PINNED_HASHES = { "target": "443e269f49461dcaf5ff3804fc8770cc5579798427289c60f56a1ce533a226de", "first": "4dc689d2ca1e996ed9786915663ed0962dfbb8ef3556b6edb36d4bcd42f43387", "actual": "0d3378d771f780f909a6d7d29d2c9eec14cfd65f5901c6efbec82a5fd737b175", "before_manifest": "5edecbfb16f421a7eedafb89121ef42348cee3ecdbfe45ce8a0f272b6263e3ef", "first_manifest": "513b356efb3903cc6f3d0f012e5506e6152601c0d4a09c5843cb89d7346003e8", "before_stable": "b13c8826c3323d4a472bf46c94af12b818cc7b8d67fd402e0eb13aafe200b1a6", "first_stable": "edbbb60142e71b3132b38bc00563c945c4a06038c998a204c4685c4f25cdff98", "cachebeta": "4cc87b45f721270392a96f1674ed2b5cd4a7bb4355faeab4531d1cf1884d9520", "target_alert": "351ff0de9ddfea9b3c03a9038abab75b0c4b48290443b33e09c33105b41ab61a", "target_charge": "76c4c0b62850ffaa42fe5027c3e68b2cc42f7640c1156342c9a9cc4d1125afea", "target_combat": "6030e4891bf64d0cb0c41028a6c816ef07c4442f6c573ac70f37fb1e049ca45b", "coff_compare": "22f8e11c7b5b5b1e1cb9bc51d2e48c0fa4912def9c1d48bd09db80735ee8204e", "coff_tools": "6784bd1a1e241942f301e2691862af596554bf8fbf4333437c0451988660d3c5", "regression_gate": "299f15d1569096730508c85eee9271ba4798c8e4f42f51bdccb89f1c1d84ea3f", } DECODER = "_actor_look_decode_direction" AFFECT = "_actor_look_affect_movement" TARGET_DECODER = "_code_00016c70" HELPERS = ( "_square_root", "_vector_from_points3d", "_scale_vector3d", "_magnitude_squared3d", "_magnitude3d", "_normalize3d", "_valid_real", "_valid_realcmp", "_valid_real_normal3d", ) EXECUTED_HELPERS = { "_vector_from_points3d", "_normalize3d", "_valid_real_normal3d", } APIS = ( "_datum_get", "_datum_try_and_get", "_object_try_and_get_and_verify_type", "_unit_get_head_position", "_object_get_origin", "_actor_path_has_path", "_display_assert", "_system_exit", "_sprintf", "_csprintf", ) FUNCTION_FACTS = { "target": { DECODER: (1632, 98, "4f3714fab510f0c407dc0792b3cbea003ba4d1dfdb4aee74d201d9a9e5dc14a9", 2), AFFECT: (128, 4, "5d7d253b925542d2e1c1c21c83c6a2f2049df1a6fe051b6f713b377c47f85dde", 2), }, "first": { DECODER: (1616, 99, "bea2ec692aedec4276c07fb076ad2dd53888277627541c42fb56dea1670b3008", 3), AFFECT: (128, 4, "d096436ec233acf74823c8ce959e2ded832eb046b0c8b441be976c5e6cf5dafa", 2), }, "actual": { DECODER: (1616, 99, "bea2ec692aedec4276c07fb076ad2dd53888277627541c42fb56dea1670b3008", 3), AFFECT: (128, 4, "d096436ec233acf74823c8ce959e2ded832eb046b0c8b441be976c5e6cf5dafa", 2), }, } HELPER_FACTS = { "_square_root": (16, 0, "0717923dacb4356a94553a32f0ba8a314904fae6d7d0bfc42ecc4af6f10415b7"), "_vector_from_points3d": (48, 0, "905f56dbe4597d2bacc201456ffc33464b166e0b6392dda24a1a3e109b637aa2"), "_scale_vector3d": (48, 0, "6436919fbdc80b5d5fe76d9c92fa146e5ac7d3b4637c9b75aaa62401f0c54a3b"), "_magnitude_squared3d": (48, 0, "0d04579096eeab3a1c45f87774e1eb20ce4856dbac219f624a855e8c9ae99725"), "_magnitude3d": (48, 0, "114f10e7ee4543446daaaafc859a4ec729ba6c8c74c38825d05bd0f00a42352c"), "_normalize3d": (96, 3, "67fbd33f204d0c93cce135fcfd37d4ce5b443642edc6ad99230846b91c893e5b"), "_valid_real": (32, 0, "83977ed5f0ae820e1554588c354ae57295d798d933e591ee898dc39d29731d4f"), "_valid_realcmp": (64, 1, "af811d6df5f204708d247a7d50e091f7828989672ded12773edd93431f74852c"), "_valid_real_normal3d": (96, 2, "0958b20f958923b9a2b2561eebda24ae8838b04180389aaaf3926319b19599c0"), } CODE_ADDRESSES = {DECODER: 0x100000, AFFECT: 0x110000} CODE_ADDRESSES.update({name: 0x120000 + index * 0x2000 for index, name in enumerate(HELPERS)}) STUB_BASE = 0x200000 STUB_ADDRESSES = {name: STUB_BASE + 0x100 * (index + 1) for index, name in enumerate(APIS)} STOP = 0x20F000 RDATA = 0x300000 RDATA_SIZE = 0x40000 GLOBALS = 0x400000 ACTOR_DATA_SLOT = GLOBALS + 0x100 PROP_DATA_SLOT = GLOBALS + 0x104 ACTOR_DATA_VALUE = 0x2468ACE0 PROP_DATA_VALUE = 0x13579BDF ACTOR = 0x500000 SPEC = 0x502000 DIRECTION = 0x504000 PROP = 0x506000 OBJECT = 0x508000 TEMPORARY = 0x50A000 STACK = 0x600000 STACK_SIZE = 0x20000 ENTRY_SP = STACK + 0x10000 ACTOR_SIZE = 0x800 SMALL_SIZE = 0x200 TEMPORARY_SIZE = 0x1000 PAGE_SIZE = 0x1000 CALLER_FRAME_SIZE = 0x80 FPCW_VALUES = (0x027F, 0x037F) NONE = 0xFFFFFFFF HEAD_POSITION = 0x120 TARGET_PROP_INDEX = 0x270 DANGER_TYPE = 0x280 DANGER_POSITION = 0x2B0 PRIMARY_PRIORITY = 0x3E8 PRIMARY_DIRECTION = 0x3EC MOVING = 0x504 FORCED_BY_AIMING = 0x505 MOVING_POINT = 0x50C MOVING_VECTOR = 0x518 FORCED_DIRECTION = 0x524 FIRE_STATE = 0x5F2 FIRE_TARGET_TYPE = 0x60C AIMING_AT_FIRE_TARGET = 0x628 FIRE_AIM_VECTOR = 0x63C BURST_AIM_VECTOR = 0x68C PROP_OWNER = 0x04 PROP_CENTER = 0xC8 PROP_HEAD = 0x104 OBJECT_TYPE = 0x64 DIRECTION_MOVEMENT = 0 DIRECTION_PROP = 1 DIRECTION_TARGET = 2 DIRECTION_POINT = 3 DIRECTION_VECTOR = 4 DIRECTION_DANGER = 5 DIRECTION_OBJECT = 6 FIRE_BURSTING = 2 PRIMARY_AIMING = 3 NONVOLATILE = { "ebp": UC_X86_REG_EBP, "ebx": UC_X86_REG_EBX, "esi": UC_X86_REG_ESI, "edi": UC_X86_REG_EDI, } SAVED = { "ebp": 0x1122AABB, "ebx": 0x2233BBCC, "esi": 0x3344CCDD, "edi": 0x4455DDEE, } EXE_CONSTANTS = { "??_C@_00CNPNBAHC@?$AA@": (2372623, b""), "??_C@_0CL@GJIEKICC@?$CFs?3?5assert_valid_real_normal3d?$CI?$CF@": ( 2377156, b"%s: assert_valid_real_normal3d(%f, %f, %f)", ), } FORMAT_RE = re.compile(r"%(?P[-+ #0]*)(?P\d*)(?:\.(?P\d+))?(?P[fsdXu])") def sha256_bytes(raw: bytes) -> str: return hashlib.sha256(raw).hexdigest() def sha256_path(path: Path) -> str: return sha256_bytes(path.read_bytes()) def verify_hash(path: Path, expected: str, label: str) -> dict: actual = sha256_path(path) if actual.lower() != expected.lower(): raise AssertionError((label, "SHA-256 mismatch", str(path), actual, expected)) return {"path": str(path), "sha256": actual, "bytes": path.stat().st_size} def p16(value: int) -> bytes: return struct.pack(" bytes: return struct.pack(" int: return struct.unpack(" int: return struct.unpack(" float: return struct.unpack(" int: return struct.unpack(" float: return struct.unpack(" None: raw[offset : offset + 2] = p16(value) def write32(raw: bytearray, offset: int, value: int) -> None: raw[offset : offset + 4] = p32(value) def write_float(raw: bytearray, offset: int, value: float) -> None: raw[offset : offset + 4] = struct.pack(" None: for index, component in enumerate(value): write_float(raw, offset + 4 * index, component) def seeded_bytes(size: int, seed: int) -> bytes: return bytes(((index * 37 + seed * 53 + 11) & 0xFF) for index in range(size)) def changed_offsets(before: bytes, after: bytes) -> list[int]: if len(before) != len(after): raise AssertionError("change comparison length mismatch") return [index for index, (left, right) in enumerate(zip(before, after)) if left != right] def float_token(value: float) -> str: if math.isnan(value): return "nan" if math.isinf(value): return "+inf" if value > 0 else "-inf" return value.hex() class Owner: def __init__(self, label: str, path: Path, expected_hash: str): self.label = label self.path = path self.input = verify_hash(path, expected_hash, label) self.obj = cc.load(path) self.functions = function_sections(self.obj) class ConstantPool: def __init__(self, owners: list[Owner], cachebeta: bytes): self.owners = owners self.cachebeta = cachebeta self.section_addresses: dict[tuple[str, int], int] = {} self.blocks: dict[int, bytes] = {} self.records: list[dict] = [] self.next_slot = 0 def _find(self, name: str, preferred: Owner | None) -> tuple[Owner, dict] | None: ordered = ([preferred] if preferred is not None else []) + [ owner for owner in self.owners if owner is not preferred ] for owner in ordered: matches = [ symbol for symbol in owner.obj["symbols"] if symbol["name"] == name and symbol["section"] > 0 ] if len(matches) > 1: raise AssertionError((name, "ambiguous definition", owner.label, len(matches))) if matches: symbol = matches[0] section = owner.obj["sections"][symbol["section"] - 1] if section["flags"] & cc.IMAGE_SCN_CNT_CODE: raise AssertionError((name, "constant resolved to code", owner.label)) return owner, symbol return None def address(self, name: str, addend: int, preferred: Owner | None = None) -> int: found = self._find(name, preferred) if found is None: if name not in EXE_CONSTANTS: raise AssertionError((name, "no authenticated non-code owner")) offset, expected = EXE_CONSTANTS[name] end = self.cachebeta.find(b"\0", offset) if end < 0: raise AssertionError((name, "unterminated executable string")) raw = self.cachebeta[offset : end + 1] if raw[:-1] != expected: raise AssertionError((name, "executable string mismatch", raw[:-1], expected)) key = ("cachebeta.exe", offset) symbol_value = 0 provenance = {"kind": "cachebeta.exe", "file_offset": offset} else: owner, symbol = found section_number = symbol["section"] section = owner.obj["sections"][section_number - 1] raw = bytes(cc._section_bytes(owner.obj, section)) key = (owner.label, section_number) symbol_value = symbol["value"] provenance = { "kind": "coff-section", "owner": owner.label, "path": str(owner.path), "section": section_number, } if key not in self.section_addresses: if len(raw) > 0x1000 or (self.next_slot + 1) * 0x1000 > RDATA_SIZE: raise AssertionError((name, "constant arena bound", len(raw), self.next_slot)) base = RDATA + self.next_slot * 0x1000 self.next_slot += 1 self.section_addresses[key] = base self.blocks[base] = raw self.records.append( { "base": base, "bytes": len(raw), "sha256": sha256_bytes(raw), **provenance, } ) return self.section_addresses[key] + symbol_value + addend def direct_case(name: str, direction_type: int | None, expected_al: int | None, **values) -> dict: result = { "name": name, "entry": "decoder", "direction_type": direction_type, "expected_al": expected_al, "moving": 0, "movement_vector": (3.0, 4.0, 0.0), "movement_point": (11.0, 22.0, 33.0), "head": (1.0, 2.0, 3.0), "spec_vector": (0.6, 0.8, 0.0), "spec_point": (4.0, 6.0, 3.0), "prop_present": True, "prop_head": (4.0, 6.0, 3.0), "prop_center": (4.0, 6.0, 3.0), "prop_try_sequence": ["prop"], "target_prop": NONE, "fire_state": 0, "aiming": 0, "fire_vector": (0.0, 0.0, 1.0), "burst_vector": (0.6, 0.8, 0.0), "danger_type": 0, "danger_position": (4.0, 6.0, 3.0), "object_present": True, "object_type": 0, "object_point": (4.0, 6.0, 3.0), "null_spec": False, "null_direction": False, "expected_api": ["_datum_get"], "vector_calls": 0, "normalize_calls": 0, "decoder_result_true": expected_al == 1, "expected_direction": "unchanged", "expected_display": [], "terminated": False, } result.update(values) return result def affect_case(name: str, direction_type: int, priority: int, **values) -> dict: result = { "name": name, "entry": "affect", "direction_type": direction_type, "priority": priority, "path_result": False, "head": (1.0, 2.0, 3.0), "spec_vector": (0.6, 0.8, 0.0), "spec_point": (1.0, 2.0, 3.0), "expected_api": ["_datum_get"], "vector_calls": 0, "normalize_calls": 0, "decoder_result_true": False, "nested_decoder": False, "expected_priority": priority, "expected_flag": 0, "expected_forced_direction": "unchanged", "terminated": False, "expected_display": [], } result.update(values) return result def cases() -> list[dict]: diagnostic_tail = ["_sprintf", "_display_assert", "_csprintf", "_display_assert", "_system_exit"] direct = [ direct_case( "movement_success", DIRECTION_MOVEMENT, 1, moving=1, normalize_calls=1, expected_direction=(0.6, 0.8, 0.0), ), direct_case("movement_not_moving", DIRECTION_MOVEMENT, 0, moving=0), direct_case( "prop_success", DIRECTION_PROP, 1, expected_api=["_datum_get", "_datum_try_and_get"], vector_calls=1, normalize_calls=1, expected_direction=(0.6, 0.8, 0.0), ), direct_case( "prop_missing", DIRECTION_PROP, 0, prop_present=False, prop_try_sequence=[None], expected_api=["_datum_get", "_datum_try_and_get"], ), direct_case( "target_burst", DIRECTION_TARGET, 1, fire_state=FIRE_BURSTING, expected_direction=(0.6, 0.8, 0.0), ), direct_case( "target_fire_aim", DIRECTION_TARGET, 1, aiming=1, expected_direction=(0.0, 0.0, 1.0), ), direct_case( "target_prop", DIRECTION_TARGET, 1, target_prop="prop", expected_api=["_datum_get", "_datum_get"], vector_calls=1, normalize_calls=1, expected_direction=(0.6, 0.8, 0.0), ), direct_case("target_none", DIRECTION_TARGET, 0), direct_case( "point_success", DIRECTION_POINT, 1, vector_calls=0, normalize_calls=1, expected_direction=(0.6, 0.8, 0.0), ), direct_case( "point_zero", DIRECTION_POINT, 0, spec_point=(1.0, 2.0, 3.0), vector_calls=0, normalize_calls=1, decoder_result_true=False, expected_direction=(0.0, 0.0, 0.0), ), direct_case( "vector_success", DIRECTION_VECTOR, 1, expected_direction=(0.6, 0.8, 0.0), ), direct_case( "danger_success", DIRECTION_DANGER, 1, danger_type=1, vector_calls=1, normalize_calls=1, expected_direction=(0.6, 0.8, 0.0), ), direct_case("danger_none", DIRECTION_DANGER, 0), direct_case( "object_unit", DIRECTION_OBJECT, 1, object_type=0, expected_api=["_datum_get", "_object_try_and_get_and_verify_type", "_unit_get_head_position"], vector_calls=1, normalize_calls=1, expected_direction=(0.6, 0.8, 0.0), ), direct_case( "object_general", DIRECTION_OBJECT, 1, object_type=2, expected_api=["_datum_get", "_object_try_and_get_and_verify_type", "_object_get_origin"], vector_calls=1, normalize_calls=1, expected_direction=(0.6, 0.8, 0.0), ), direct_case( "object_missing", DIRECTION_OBJECT, 0, object_present=False, expected_api=["_datum_get", "_object_try_and_get_and_verify_type"], ), direct_case( "null_specification", None, None, null_spec=True, expected_api=["_datum_get", "_display_assert", "_system_exit"], expected_display=[["specification", 349, 1]], terminated=True, ), direct_case( "null_direction", DIRECTION_VECTOR, None, null_direction=True, expected_api=["_datum_get", "_display_assert", "_system_exit"], expected_display=[["direction", 350, 1]], terminated=True, ), direct_case( "invalid_type_7", 7, None, expected_api=["_datum_get", "_display_assert", "_system_exit"], expected_display=[[None, 449, 1]], terminated=True, ), direct_case( "vector_denormalized", DIRECTION_VECTOR, None, spec_vector=(2.0, 0.0, 0.0), expected_api=["_datum_get"] + diagnostic_tail, expected_direction=(2.0, 0.0, 0.0), decoder_result_true=True, expected_display=[["temporary", 526, 0], ["temporary", 529, 1]], terminated=True, ), direct_case( "vector_lower_boundary_outside_0x3f7fdf39", DIRECTION_VECTOR, None, spec_vector=(bits_f32(0x3F7FDF39), 0.0, 0.0), expected_api=["_datum_get"] + diagnostic_tail, expected_direction=(bits_f32(0x3F7FDF39), 0.0, 0.0), decoder_result_true=True, expected_display=[["temporary", 526, 0], ["temporary", 529, 1]], terminated=True, ), direct_case( "vector_lower_boundary_inside_0x3f7fdf3a", DIRECTION_VECTOR, 1, spec_vector=(bits_f32(0x3F7FDF3A), 0.0, 0.0), expected_direction=(bits_f32(0x3F7FDF3A), 0.0, 0.0), ), direct_case( "vector_upper_boundary_inside_0x3f801061", DIRECTION_VECTOR, 1, spec_vector=(bits_f32(0x3F801061), 0.0, 0.0), expected_direction=(bits_f32(0x3F801061), 0.0, 0.0), ), direct_case( "vector_upper_boundary_outside_0x3f801062", DIRECTION_VECTOR, None, spec_vector=(bits_f32(0x3F801062), 0.0, 0.0), expected_api=["_datum_get"] + diagnostic_tail, expected_direction=(bits_f32(0x3F801062), 0.0, 0.0), decoder_result_true=True, expected_display=[["temporary", 526, 0], ["temporary", 529, 1]], terminated=True, ), direct_case( "movement_infinite_diagnostic", DIRECTION_MOVEMENT, None, moving=1, movement_vector=(math.inf, 0.0, 0.0), normalize_calls=1, expected_api=["_datum_get"] + diagnostic_tail, expected_direction="nonfinite", decoder_result_true=True, expected_display=[["temporary", 526, 0], ["temporary", 529, 1]], terminated=True, ), direct_case( "prop_infinite_invalid_second_lookup", DIRECTION_PROP, None, head=(0.0, 0.0, 0.0), prop_head=(math.inf, 0.0, 0.0), prop_try_sequence=["prop", None], vector_calls=1, normalize_calls=1, expected_api=["_datum_get", "_datum_try_and_get", "_datum_try_and_get"] + diagnostic_tail, expected_direction="nonfinite", decoder_result_true=True, expected_display=[["temporary", 526, 0], ["temporary", 529, 1]], terminated=True, ), ] affect = [ affect_case( "affect_movement_no_path", DIRECTION_MOVEMENT, 4, expected_api=["_datum_get", "_actor_path_has_path"], expected_priority=0, ), affect_case( "affect_movement_has_path", DIRECTION_MOVEMENT, 4, path_result=True, expected_api=["_datum_get", "_actor_path_has_path"], expected_priority=4, ), affect_case("affect_vector_priority_2", DIRECTION_VECTOR, 2), affect_case( "affect_vector_priority_3", DIRECTION_VECTOR, 3, expected_api=["_datum_get", "_datum_get"], nested_decoder=True, decoder_result_true=True, expected_flag=1, expected_forced_direction=(0.6, 0.8, 0.0), ), affect_case( "affect_vector_priority_4", DIRECTION_VECTOR, 4, expected_api=["_datum_get", "_datum_get"], nested_decoder=True, decoder_result_true=True, expected_flag=1, expected_forced_direction=(0.6, 0.8, 0.0), ), affect_case( "affect_point_zero_priority_3", DIRECTION_POINT, 3, expected_api=["_datum_get", "_datum_get"], nested_decoder=True, vector_calls=0, normalize_calls=1, decoder_result_true=False, expected_flag=0, expected_forced_direction=(0.0, 0.0, 0.0), ), ] return direct + affect class RoleImage: def __init__(self, role: str, primary_path: Path, primary_hash: str): self.role = role self.primary = Owner(role + ":primary", primary_path, primary_hash) self.target_alert = Owner(role + ":target-alert", TARGET_ALERT, PINNED_HASHES["target_alert"]) self.target_charge = Owner(role + ":target-charge", TARGET_CHARGE, PINNED_HASHES["target_charge"]) self.target_combat = Owner(role + ":target-combat", TARGET_COMBAT, PINNED_HASHES["target_combat"]) self.cachebeta = CACHEBETA.read_bytes() if sha256_bytes(self.cachebeta) != PINNED_HASHES["cachebeta"]: raise AssertionError((role, "cachebeta SHA-256 mismatch")) self.constants = ConstantPool( [self.primary, self.target_alert, self.target_charge, self.target_combat], self.cachebeta, ) if role == "target": self.helper_owners = { "_square_root": self.target_charge, "_vector_from_points3d": self.target_alert, "_scale_vector3d": self.target_charge, "_magnitude_squared3d": self.target_alert, "_magnitude3d": self.target_charge, "_normalize3d": self.target_charge, "_valid_real": self.target_combat, "_valid_realcmp": self.target_combat, "_valid_real_normal3d": self.target_combat, } else: self.helper_owners = {name: self.primary for name in HELPERS} self.runtime_raw: dict[str, bytes] = {} self.section_raw: dict[str, bytes] = {} self.section_checks: dict[str, dict] = {} self.relocations: dict[str, list[dict]] = {} self.function_owner: dict[str, str] = {} decoder_owner_name = TARGET_DECODER if role == "target" else DECODER self._materialize(DECODER, self.primary, decoder_owner_name) self._materialize(AFFECT, self.primary, AFFECT) for name in HELPERS: self._materialize(name, self.helper_owners[name], name) self._cross_guards() def _destination(self, name: str, addend: int, owner: Owner) -> int: if name == "_actor_data": return ACTOR_DATA_SLOT + addend if name == "_prop_data": return PROP_DATA_SLOT + addend if name == "_temporary": return TEMPORARY + addend if name in STUB_ADDRESSES: return STUB_ADDRESSES[name] + addend if name in CODE_ADDRESSES: return CODE_ADDRESSES[name] + addend if name == TARGET_DECODER: return CODE_ADDRESSES[DECODER] + addend return self.constants.address(name, addend, owner) def _materialize(self, canonical_name: str, owner: Owner, owner_name: str) -> None: if owner_name not in owner.functions: raise AssertionError((self.role, owner.label, "missing function", owner_name)) function = owner.functions[owner_name] symbol = cc.symbol(owner.obj, owner_name) section = owner.obj["sections"][function.section_number - 1] raw = bytearray(cc._section_bytes(owner.obj, section)) base = CODE_ADDRESSES[canonical_name] relocations = [] for relocation in function.info["relocations"]: target = relocation["target"] if target[0] == "internal": destination = base + target[1] target_name = "$internal" addend = target[1] elif target[0] == "symbol": target_name, addend = target[1], target[2] destination = self._destination(target_name, addend, owner) elif target[0] == "defined-noncode": target_name, addend = target[2], target[3] destination = self.constants.address(target_name, addend, owner) else: raise AssertionError((self.role, canonical_name, "unsupported relocation", target)) if relocation["type"] == cc.IMAGE_REL_I386_REL32: patched = destination - (base + relocation["address"] + 4) elif relocation["type"] == cc.IMAGE_REL_I386_DIR32: patched = destination else: raise AssertionError((canonical_name, "unsupported relocation type", relocation)) raw[relocation["address"] : relocation["address"] + 4] = p32(patched) relocations.append( { "address": relocation["address"], "type": relocation["type"], "target": target_name, "addend": addend, "destination": destination & 0xFFFFFFFF, } ) if canonical_name in (DECODER, AFFECT): size, relocation_count, normalized_sha256, storage = FUNCTION_FACTS[self.role][canonical_name] expected_selection = 1 else: size, relocation_count, normalized_sha256 = HELPER_FACTS[canonical_name] storage = 2 expected_selection = 1 if self.role == "target" else 2 checks = { "size": function.info["size"] == size == len(raw), "relocation_count": function.info["relocation_count"] == relocation_count, "normalized_sha256": function.info["normalized_sha256"] == normalized_sha256, "storage": symbol["storage"] == storage, "function_type": symbol["type"] == 0x20, "comdat_selection": _section_aux_selection(owner.obj, symbol["section"]) == expected_selection, } if not all(checks.values()): raise AssertionError((self.role, canonical_name, "COFF guard", checks)) self.runtime_raw[canonical_name] = bytes(raw) self.section_raw[canonical_name] = bytes(cc._section_bytes(owner.obj, section)) self.section_checks[canonical_name] = checks self.relocations[canonical_name] = relocations self.function_owner[canonical_name] = owner.label def _cross_guards(self) -> None: valid_calls = Counter(item["target"] for item in self.relocations[DECODER])[ "_valid_real_normal3d" ] if valid_calls != (1 if self.role == "target" else 2): raise AssertionError((self.role, "valid_real_normal3d relocation count", valid_calls)) affect_decoder_targets = [ item["target"] for item in self.relocations[AFFECT] if item["target"] in (TARGET_DECODER, DECODER) ] expected = [TARGET_DECODER if self.role == "target" else DECODER] if affect_decoder_targets != expected: raise AssertionError((self.role, "public/private edge", affect_decoder_targets, expected)) def guards(self) -> dict: return { "sections": self.section_checks, "owners": self.function_owner, "relocations": self.relocations, "constant_sections": self.constants.records, "target_first_validity_boundary": ( "one out-of-line valid_real_normal3d relocation in target; two in candidate" ), } def run( self, scenario: dict, fpcw: int, seed: int, overrides: dict[str, bytes] | None = None, validate: bool = True, ) -> dict: machine = u.Uc(u.UC_ARCH_X86, u.UC_MODE_32) for address in CODE_ADDRESSES.values(): machine.mem_map(address, 0x1000) machine.mem_map(STUB_BASE, 0x10000) machine.mem_map(RDATA, RDATA_SIZE) machine.mem_map(GLOBALS, 0x1000) for address in (ACTOR, SPEC, DIRECTION, PROP, OBJECT, TEMPORARY): machine.mem_map(address, 0x1000) machine.mem_map(STACK, STACK_SIZE) selected_raw = dict(self.runtime_raw) if overrides: selected_raw.update(overrides) for name, raw in selected_raw.items(): machine.mem_write(CODE_ADDRESSES[name], raw) machine.mem_write(STUB_BASE, b"\xC3" * 0x10000) for address, raw in self.constants.blocks.items(): machine.mem_write(address, raw) machine.mem_write(ACTOR_DATA_SLOT, p32(ACTOR_DATA_VALUE)) machine.mem_write(PROP_DATA_SLOT, p32(PROP_DATA_VALUE)) actor_handle = (0xA5100000 | seed) & 0xFFFFFFFF prop_handle = (0xB6200000 | seed) & 0xFFFFFFFF object_handle = (0xC7300000 | seed) & 0xFFFFFFFF if scenario.get("target_prop") == "prop": target_prop_handle = prop_handle else: target_prop_handle = int(scenario.get("target_prop", NONE)) & 0xFFFFFFFF actor_before = bytearray(seeded_bytes(ACTOR_SIZE, seed)) write_vector(actor_before, HEAD_POSITION, tuple(scenario.get("head", (1.0, 2.0, 3.0)))) write32(actor_before, TARGET_PROP_INDEX, target_prop_handle) write16(actor_before, DANGER_TYPE, scenario.get("danger_type", 0)) write_vector(actor_before, DANGER_POSITION, tuple(scenario.get("danger_position", (4.0, 6.0, 3.0)))) write16(actor_before, PRIMARY_PRIORITY, scenario.get("priority", 0)) write16(actor_before, PRIMARY_DIRECTION, scenario["direction_type"] or 0) primary_value = ( scenario.get("spec_point", (1.0, 2.0, 3.0)) if scenario["direction_type"] == DIRECTION_POINT else scenario.get("spec_vector", (0.6, 0.8, 0.0)) ) write_vector(actor_before, PRIMARY_DIRECTION + 4, tuple(primary_value)) actor_before[MOVING] = scenario.get("moving", 0) & 0xFF actor_before[FORCED_BY_AIMING] = 0x7D write_vector(actor_before, MOVING_POINT, tuple(scenario.get("movement_point", (11.0, 22.0, 33.0)))) write_vector(actor_before, MOVING_VECTOR, tuple(scenario.get("movement_vector", (3.0, 4.0, 0.0)))) write_vector(actor_before, FORCED_DIRECTION, (9.0, 8.0, 7.0)) write16(actor_before, FIRE_STATE, scenario.get("fire_state", 0)) write16(actor_before, FIRE_TARGET_TYPE, 5) actor_before[AIMING_AT_FIRE_TARGET] = scenario.get("aiming", 0) & 0xFF write_vector(actor_before, FIRE_AIM_VECTOR, tuple(scenario.get("fire_vector", (0.0, 0.0, 1.0)))) write_vector(actor_before, BURST_AIM_VECTOR, tuple(scenario.get("burst_vector", (0.6, 0.8, 0.0)))) spec_before = bytearray(seeded_bytes(SMALL_SIZE, seed + 17)) write16(spec_before, 0, scenario["direction_type"] or 0) spec_value = ( scenario.get("spec_point", (4.0, 6.0, 3.0)) if scenario["direction_type"] == DIRECTION_POINT else scenario.get("spec_vector", (0.6, 0.8, 0.0)) ) if scenario["direction_type"] in (DIRECTION_PROP, DIRECTION_OBJECT): write32( spec_before, 4, prop_handle if scenario["direction_type"] == DIRECTION_PROP else object_handle, ) else: write_vector(spec_before, 4, tuple(spec_value)) direction_before = seeded_bytes(SMALL_SIZE, seed + 31) prop_before = bytearray(seeded_bytes(SMALL_SIZE, seed + 43)) write32(prop_before, PROP_OWNER, 0xD8400000 | seed) write_vector(prop_before, PROP_CENTER, tuple(scenario.get("prop_center", (4.0, 6.0, 3.0)))) write_vector(prop_before, PROP_HEAD, tuple(scenario.get("prop_head", (4.0, 6.0, 3.0)))) object_before = bytearray(seeded_bytes(SMALL_SIZE, seed + 59)) write16(object_before, OBJECT_TYPE, scenario.get("object_type", 0)) temporary_before = seeded_bytes(TEMPORARY_SIZE, seed + 71) globals_before = bytes(machine.mem_read(GLOBALS, 0x1000)) actor_page_before = bytearray(seeded_bytes(PAGE_SIZE, seed + 101)) actor_page_before[:ACTOR_SIZE] = actor_before spec_page_before = bytearray(seeded_bytes(PAGE_SIZE, seed + 103)) spec_page_before[:SMALL_SIZE] = spec_before direction_page_before = bytearray(seeded_bytes(PAGE_SIZE, seed + 107)) direction_page_before[:SMALL_SIZE] = direction_before prop_page_before = bytearray(seeded_bytes(PAGE_SIZE, seed + 109)) prop_page_before[:SMALL_SIZE] = prop_before object_page_before = bytearray(seeded_bytes(PAGE_SIZE, seed + 113)) object_page_before[:SMALL_SIZE] = object_before machine.mem_write(ACTOR, bytes(actor_page_before)) machine.mem_write(SPEC, bytes(spec_page_before)) machine.mem_write(DIRECTION, bytes(direction_page_before)) machine.mem_write(PROP, bytes(prop_page_before)) machine.mem_write(OBJECT, bytes(object_page_before)) machine.mem_write(TEMPORARY, temporary_before) stack_before = bytearray(seeded_bytes(STACK_SIZE, seed + 89)) write32(stack_before, ENTRY_SP - STACK, STOP) write32(stack_before, ENTRY_SP - STACK + 4, actor_handle) caller_before = bytes( stack_before[ENTRY_SP - STACK : ENTRY_SP - STACK + CALLER_FRAME_SIZE] ) machine.mem_write(STACK, bytes(stack_before)) for name, register in NONVOLATILE.items(): machine.reg_write(register, SAVED[name]) machine.reg_write(UC_X86_REG_EAX, 0x89ABCDEF) machine.reg_write(UC_X86_REG_ECX, 0x76543210) machine.reg_write(UC_X86_REG_EDX, 0x0BADF00D) machine.reg_write(UC_X86_REG_ESP, ENTRY_SP) machine.reg_write(UC_X86_REG_EFLAGS, 0x202 | (0x400 if seed & 1 else 0)) machine.reg_write(UC_X86_REG_FPCW, fpcw) machine.reg_write(UC_X86_REG_FPSW, 0) machine.reg_write(UC_X86_REG_FPTAG, 0xFFFF) initial_direction_flag = bool(machine.reg_read(UC_X86_REG_EFLAGS) & 0x400) initial_fptag = machine.reg_read(UC_X86_REG_FPTAG) & 0xFFFF if scenario["entry"] == "decoder": machine.reg_write(UC_X86_REG_EBX, 0 if scenario["null_spec"] else SPEC) machine.reg_write(UC_X86_REG_EDI, 0 if scenario["null_direction"] else DIRECTION) api_calls: list[dict] = [] math_calls: list[dict] = [] decoder_entries: list[dict] = [] writes: list[dict] = [] invalid_accesses: list[dict] = [] terminated = False try_index = 0 def argument(index: int) -> int: return r32(machine, machine.reg_read(UC_X86_REG_ESP) + 4 + 4 * index) def pointer_label(address: int) -> str: regions = ( (ACTOR, PAGE_SIZE, "actor"), (SPEC, PAGE_SIZE, "specification"), (DIRECTION, PAGE_SIZE, "direction"), (PROP, PAGE_SIZE, "prop"), (OBJECT, PAGE_SIZE, "object"), (TEMPORARY, TEMPORARY_SIZE, "temporary"), (STACK, STACK_SIZE, "stack"), (GLOBALS, 0x1000, "globals"), (RDATA, RDATA_SIZE, "rdata"), ) if address == 0: return "null" for base, size, label in regions: if base <= address < base + size: offset = address - base return label if offset == 0 else f"{label}+0x{offset:x}" return f"0x{address:08x}" def cstring(address: int, limit: int = 4096) -> str | None: if address == 0: return None raw = bytes(machine.mem_read(address, limit)) end = raw.find(b"\0") if end < 0: raise AssertionError((self.role, scenario["name"], "unterminated cstring", hex(address))) return raw[:end].decode("ascii") def return_from_stub(value: int = 0) -> None: esp = machine.reg_read(UC_X86_REG_ESP) return_address = r32(machine, esp) machine.reg_write(UC_X86_REG_EAX, value & 0xFFFFFFFF) machine.reg_write(UC_X86_REG_ESP, esp + 4) machine.reg_write(UC_X86_REG_EIP, return_address) def decode_format(format_address: int) -> tuple[str, list[dict], str]: pattern = cstring(format_address) assert pattern is not None offset_words = 2 typed: list[dict] = [] rendered_parts: list[str] = [] cursor = 0 for match in FORMAT_RE.finditer(pattern): rendered_parts.append(pattern[cursor : match.start()]) kind = match.group("kind") width = int(match.group("width") or 0) precision = int(match.group("precision") or 6) if kind == "f": low = argument(offset_words) high = argument(offset_words + 1) value = struct.unpack(" TEMPORARY_SIZE: raise AssertionError((scenario["name"], "modeled format overflow", len(encoded))) machine.mem_write(destination, encoded) api_calls.append( { "name": name, "destination": "temporary", "format": pattern, "typed_arguments": typed, "modeled_rendering": rendered, } ) return_from_stub(destination if name == "_csprintf" else len(rendered)) elif name == "_display_assert": info, file_address, line, fatal = (argument(index) for index in range(4)) api_calls.append( { "name": name, "info_pointer": pointer_label(info), "info": cstring(info), "file": cstring(file_address), "line": line, "fatal": fatal, } ) return_from_stub(0) elif name == "_system_exit": status = s32(argument(0)) api_calls.append({"name": name, "status": status}) terminated = True machine.reg_write(UC_X86_REG_EIP, STOP) machine.emu_stop() else: raise AssertionError(name) def on_write(_machine, _access, address, size, value, _user): for base, bound, label in ( (ACTOR, PAGE_SIZE, "actor"), (SPEC, PAGE_SIZE, "specification"), (DIRECTION, PAGE_SIZE, "direction"), (PROP, PAGE_SIZE, "prop"), (OBJECT, PAGE_SIZE, "object"), (TEMPORARY, TEMPORARY_SIZE, "temporary"), (GLOBALS, 0x1000, "globals"), ): if base <= address < base + bound: writes.append( { "region": label, "offset": address - base, "size": size, "value": value & ((1 << min(size * 8, 64)) - 1), } ) return def on_invalid(_machine, access, address, size, value, _user): invalid_accesses.append( {"access": access, "address": address, "size": size, "value": value} ) return False machine.hook_add(u.UC_HOOK_CODE, on_code) machine.hook_add(u.UC_HOOK_MEM_WRITE, on_write) machine.hook_add(u.UC_HOOK_MEM_INVALID, on_invalid) entry = CODE_ADDRESSES[DECODER if scenario["entry"] == "decoder" else AFFECT] try: machine.emu_start(entry, STOP, count=100000) except u.UcError as error: raise AssertionError( ( self.role, scenario["name"], "emulation error", repr(error), hex(machine.reg_read(UC_X86_REG_EIP)), invalid_accesses, ) ) from error buffers_before = { "actor": bytes(actor_page_before), "specification": bytes(spec_page_before), "direction": bytes(direction_page_before), "prop": bytes(prop_page_before), "object": bytes(object_page_before), "temporary": temporary_before, "globals": globals_before, } buffers_after = { "actor": bytes(machine.mem_read(ACTOR, PAGE_SIZE)), "specification": bytes(machine.mem_read(SPEC, PAGE_SIZE)), "direction": bytes(machine.mem_read(DIRECTION, PAGE_SIZE)), "prop": bytes(machine.mem_read(PROP, PAGE_SIZE)), "object": bytes(machine.mem_read(OBJECT, PAGE_SIZE)), "temporary": bytes(machine.mem_read(TEMPORARY, TEMPORARY_SIZE)), "globals": bytes(machine.mem_read(GLOBALS, 0x1000)), } changes = { name: changed_offsets(buffers_before[name], buffers_after[name]) for name in buffers_before } nonvolatile = { name: machine.reg_read(register) & 0xFFFFFFFF for name, register in NONVOLATILE.items() } fpsw = machine.reg_read(UC_X86_REG_FPSW) & 0xFFFF fptag = machine.reg_read(UC_X86_REG_FPTAG) & 0xFFFF final_direction_flag = bool(machine.reg_read(UC_X86_REG_EFLAGS) & 0x400) result = { "role": self.role, "case": scenario["name"], "entry": scenario["entry"], "fpcw_requested": fpcw, "fpcw_final": machine.reg_read(UC_X86_REG_FPCW) & 0xFFFF, "fpsw_final": fpsw, "fptag_initial": initial_fptag, "fptag_final": fptag, "x87_top": (fpsw >> 11) & 7, "direction_flag_initial": initial_direction_flag, "direction_flag_final": final_direction_flag, "terminated_by_system_exit": terminated, "eip": machine.reg_read(UC_X86_REG_EIP) & 0xFFFFFFFF, "esp": machine.reg_read(UC_X86_REG_ESP) & 0xFFFFFFFF, "al": machine.reg_read(UC_X86_REG_EAX) & 0xFF, "nonvolatile": nonvolatile, "caller_frame_exact": bytes(machine.mem_read(ENTRY_SP, CALLER_FRAME_SIZE)) == caller_before, "api_calls": api_calls, "math_calls": math_calls, "decoder_entries": decoder_entries, "writes": writes, "invalid_accesses": invalid_accesses, "changes": changes, "buffer_hashes": { name: {"before": sha256_bytes(buffers_before[name]), "after": sha256_bytes(buffers_after[name])} for name in buffers_before }, "direction_before_bits": [ struct.unpack_from(" None: api_names = [call["name"] for call in result["api_calls"]] math_names = [call["name"] for call in result["math_calls"]] displays = [ [ "temporary" if call["info_pointer"].startswith("temporary") else call["info"], call["line"], call["fatal"], ] for call in result["api_calls"] if call["name"] == "_display_assert" ] expected_valid = (1 if self.role == "target" else 2) if scenario["decoder_result_true"] else 0 expected_math = Counter( { "_vector_from_points3d": scenario["vector_calls"], "_normalize3d": scenario["normalize_calls"], "_valid_real_normal3d": expected_valid, } ) expected_math += Counter() actual_math = Counter(math_names) checks = { "api_order": api_names == scenario["expected_api"], "display_diagnostics": displays == scenario["expected_display"], "termination": result["terminated_by_system_exit"] == scenario["terminated"], "fpcw_preserved": result["fpcw_final"] == fpcw, "x87_top_balanced": result["x87_top"] == 0, "x87_tag_restored": result["fptag_final"] == result["fptag_initial"], "direction_flag_preserved": result["direction_flag_final"] == result["direction_flag_initial"], "no_unmapped_access": not result["invalid_accesses"], "math_helper_counts": actual_math == expected_math, "only_relevant_helpers_execute": set(math_names) <= EXECUTED_HELPERS, "globals_unchanged": not result["changes"]["globals"], "specification_unchanged": not result["changes"]["specification"], "prop_unchanged": not result["changes"]["prop"], "object_unchanged": not result["changes"]["object"], "caller_frame_exact": result["caller_frame_exact"], "direction_page_tail_unchanged": set(result["changes"]["direction"]) <= set(range(12)), "temporary_page_unchanged_without_format_call": ( True if any(name in ("_sprintf", "_csprintf") for name in api_names) else not result["changes"]["temporary"] ), } if scenario["terminated"]: system_calls = [call for call in result["api_calls"] if call["name"] == "_system_exit"] checks["fatal_system_exit_minus_one"] = system_calls == [{"name": "_system_exit", "status": -1}] checks["fatal_eip_stopped"] = result["eip"] == STOP else: checks["normal_eip_stop"] = result["eip"] == STOP checks["cdecl_return_esp"] = result["esp"] == ENTRY_SP + 4 if scenario["entry"] == "decoder": expected_spec = "null" if scenario["null_spec"] else "specification" expected_direction = "null" if scenario["null_direction"] else "direction" checks["private_entry_abi"] = result["decoder_entries"] == [ { "ebx_specification": expected_spec, "edi_direction": expected_direction, "actor_index": actor_handle, } ] checks["decoder_actor_read_only"] = not result["changes"]["actor"] checks["decoder_nonvolatile"] = ( result["nonvolatile"]["ebp"] == SAVED["ebp"] and result["nonvolatile"]["esi"] == SAVED["esi"] if not scenario["terminated"] else True ) checks["decoder_write_envelope"] = { item["region"] for item in result["writes"] } <= {"direction", "temporary"} if not scenario["terminated"]: checks["decoder_private_registers_preserved"] = ( result["nonvolatile"]["ebx"] == (0 if scenario["null_spec"] else SPEC) and result["nonvolatile"]["edi"] == (0 if scenario["null_direction"] else DIRECTION) ) checks["decoder_al"] = result["al"] == scenario["expected_al"] else: expected_entries = 1 if scenario["nested_decoder"] else 0 checks["public_real_decoder_edge"] = len(result["decoder_entries"]) == expected_entries if expected_entries: checks["public_private_abi"] = result["decoder_entries"] == [ { "ebx_specification": "actor+0x3ec", "edi_direction": "actor+0x524", "actor_index": actor_handle, } ] checks["public_nonvolatile_preserved"] = result["nonvolatile"] == SAVED checks["public_external_direction_unchanged"] = not result["changes"]["direction"] checks["public_write_envelope"] = set(result["changes"]["actor"]) <= ( {PRIMARY_PRIORITY, PRIMARY_PRIORITY + 1, FORCED_BY_AIMING} | set(range(FORCED_DIRECTION, FORCED_DIRECTION + 12)) ) checks["public_priority"] = result["primary_priority"] == scenario["expected_priority"] checks["public_forced_flag"] = result["forced_by_aiming"] == scenario["expected_flag"] failed = [name for name, passed in checks.items() if not passed] result["checks"] = checks if failed: raise AssertionError( ( self.role, scenario["name"], hex(fpcw), "failed runtime checks", failed, {"api": api_names, "math": math_names, "display": displays}, ) ) if scenario["entry"] == "decoder": expected = scenario["expected_direction"] actual_bits = result["direction_after_bits"] if expected == "unchanged": passed = actual_bits == result["direction_before_bits"] elif expected == "nonfinite": passed = any(not math.isfinite(bits_f32(value)) for value in actual_bits) else: passed = all( math.isclose(bits_f32(bits), f32(component), rel_tol=2e-6, abs_tol=1e-7) for bits, component in zip(actual_bits, expected) ) result["checks"]["direction_result"] = passed if not passed: raise AssertionError((self.role, scenario["name"], "direction result", actual_bits, expected)) else: expected = scenario["expected_forced_direction"] actual_bits = result["forced_direction_bits"] initial_bits = [f32_bits(value) for value in (9.0, 8.0, 7.0)] if expected == "unchanged": passed = actual_bits == initial_bits else: passed = all( math.isclose(bits_f32(bits), f32(component), rel_tol=2e-6, abs_tol=1e-7) for bits, component in zip(actual_bits, expected) ) result["checks"]["forced_direction_result"] = passed if not passed: raise AssertionError((self.role, scenario["name"], "forced direction", actual_bits, expected)) def typed_without_machine_words(value): if isinstance(value, list): return [typed_without_machine_words(item) for item in value] if isinstance(value, dict): return { key: typed_without_machine_words(item) for key, item in value.items() if key not in ("words", "modeled_rendering", "output", "pointer") } return value def semantic_signature(run: dict) -> dict: after_hashes = { name: hashes["after"] for name, hashes in run["buffer_hashes"].items() } result = { "entry": run["entry"], "fpcw": run["fpcw_final"], "fptag": run["fptag_final"], "x87_top": run["x87_top"], "direction_flag": run["direction_flag_final"], "terminated": run["terminated_by_system_exit"], "api_calls": typed_without_machine_words(run["api_calls"]), "decoder_entries": run["decoder_entries"], "after_hashes": after_hashes, "changes": run["changes"], "direction_bits": run["direction_after_bits"], "priority": run["primary_priority"], "forced_flag": run["forced_by_aiming"], "forced_direction_bits": run["forced_direction_bits"], } if not run["terminated_by_system_exit"] and run["entry"] == "decoder": result["al"] = run["al"] return result def exact_candidate_signature(run: dict) -> dict: return { key: value for key, value in run.items() if key not in ("role", "checks") } def validate_diagnostic_details(run: dict, scenario: dict, seed: int) -> dict: display_calls = [call for call in run["api_calls"] if call["name"] == "_display_assert"] checks = { "source_path_all_displays": all( call["file"] == "c:\\halo\\SOURCE\\ai\\actor_looking.c" for call in display_calls ), "expected_line_fatal_pairs": [ [call["line"], call["fatal"]] for call in display_calls ] == [[item[1], item[2]] for item in scenario["expected_display"]], } if [[item[1], item[2]] for item in scenario["expected_display"]] == [[526, 0], [529, 1]]: sprintf_calls = [call for call in run["api_calls"] if call["name"] == "_sprintf"] csprintf_calls = [call for call in run["api_calls"] if call["name"] == "_csprintf"] checks.update( { "one_primary_diagnostic_format": len(sprintf_calls) == 1, "one_final_assert_format": len(csprintf_calls) == 1, "final_assert_format": bool(csprintf_calls) and csprintf_calls[0]["format"] == "%s: assert_valid_real_normal3d(%f, %f, %f)", "final_assert_typed_arity": bool(csprintf_calls) and [item["kind"] for item in csprintf_calls[0]["typed_arguments"]] == ["string", "double", "double", "double"], "diagnostic_sequence_526_then_529": [call["line"] for call in display_calls] == [526, 529], } ) if scenario["name"] == "movement_infinite_diagnostic": call = next(call for call in run["api_calls"] if call["name"] == "_sprintf") typed = call["typed_arguments"] checks.update( { "movement_format_selected": "%smoving" in call["format"], "movement_typed_arity": len(typed) == 8, "movement_status_empty": typed[1]["kind"] == "string" and typed[1]["value"] == "", "movement_point_x_z_z": [typed[index]["value"] for index in (2, 3, 4)] == [float_token(11.0), float_token(33.0), float_token(33.0)], } ) if scenario["name"] == "prop_infinite_invalid_second_lookup": call = next(call for call in run["api_calls"] if call["name"] == "_sprintf") typed = call["typed_arguments"] actor_handle = (0xA5100000 | seed) & 0xFFFFFFFF checks.update( { "prop_format_selected": "prop 0x%08X%s" in call["format"], "prop_typed_arity": len(typed) == 5, "prop_invalid_status": typed[2]["kind"] == "string" and typed[2]["value"] == " (invalid)", "prop_null_owner_zero": typed[3]["kind"] == "unsigned" and typed[3]["raw"] == 0, "prop_actor_index_forwarded": typed[4]["kind"] == "unsigned" and typed[4]["raw"] == actor_handle, } ) failed = [name for name, passed in checks.items() if not passed] if failed: raise AssertionError((run["role"], scenario["name"], "diagnostic checks", failed)) return checks def compare_roles(target: dict, candidate: dict, scenario: dict) -> dict: target_signature = semantic_signature(target) candidate_signature = semantic_signature(candidate) if target_signature != candidate_signature: differing = sorted( key for key in set(target_signature) | set(candidate_signature) if target_signature.get(key) != candidate_signature.get(key) ) raise AssertionError( (scenario["name"], hex(target["fpcw_requested"]), "semantic differential", differing) ) target_math = Counter(call["name"] for call in target["math_calls"]) candidate_math = Counter(call["name"] for call in candidate["math_calls"]) return { "semantic_signature_equal": True, "target_fpsw": target["fpsw_final"], "candidate_fpsw": candidate["fpsw_final"], "fpsw_equal": target["fpsw_final"] == candidate["fpsw_final"], "target_math_calls": dict(target_math), "candidate_math_calls": dict(candidate_math), "expected_candidate_extra_validity_call": ( candidate_math["_valid_real_normal3d"] - target_math["_valid_real_normal3d"] == (1 if scenario["decoder_result_true"] else 0) ), } def scenario_by_name(name: str) -> dict: return next(item for item in cases() if item["name"] == name) def mutated(raw: bytes, offset: int, before: bytes, after: bytes) -> bytes: if raw[offset : offset + len(before)] != before: raise AssertionError(("negative-control preimage", hex(offset), raw[offset : offset + len(before)].hex(), before.hex())) if len(before) != len(after): raise AssertionError("negative-control mutation must preserve length") result = bytearray(raw) result[offset : offset + len(after)] = after return bytes(result) def run_negative_controls(actual: RoleImage) -> dict: results = {} threshold_case = scenario_by_name("affect_vector_priority_3") threshold_raw = actual.runtime_raw[AFFECT] threshold_pattern = bytes.fromhex("66 83 be e8 03 00 00 03") threshold_offset = threshold_raw.find(threshold_pattern) if threshold_offset < 0 or threshold_raw.find(threshold_pattern, threshold_offset + 1) >= 0: raise AssertionError(("threshold mutation pattern cardinality", threshold_offset)) baseline = actual.run(threshold_case, 0x037F, 0xD1) changed = mutated( threshold_raw, threshold_offset + 7, b"\x03", b"\x04", ) mutant = actual.run( threshold_case, 0x037F, 0xD1, overrides={AFFECT: changed}, validate=False, ) detected = ( baseline["forced_by_aiming"] == 1 and mutant["forced_by_aiming"] == 0 and len(baseline["decoder_entries"]) == 1 and not mutant["decoder_entries"] and semantic_signature(baseline) != semantic_signature(mutant) ) results["priority_threshold_3_to_4"] = { "function": AFFECT, "offset": threshold_offset + 7, "before": "03", "after": "04", "case": threshold_case["name"], "detected": detected, "observation": { "baseline_flag": baseline["forced_by_aiming"], "mutant_flag": mutant["forced_by_aiming"], "baseline_decoder_entries": len(baseline["decoder_entries"]), "mutant_decoder_entries": len(mutant["decoder_entries"]), }, } movement_case = scenario_by_name("movement_infinite_diagnostic") decoder_raw = actual.runtime_raw[DECODER] movement_offset = 0x2F7 before_instruction = bytes.fromhex("d9 86 14 05 00 00") after_instruction = bytes.fromhex("d9 86 10 05 00 00") baseline = actual.run(movement_case, 0x037F, 0xD2) changed = mutated(decoder_raw, movement_offset, before_instruction, after_instruction) mutant = actual.run( movement_case, 0x037F, 0xD2, overrides={DECODER: changed}, validate=False, ) baseline_typed = next( call["typed_arguments"] for call in baseline["api_calls"] if call["name"] == "_sprintf" ) mutant_typed = next( call["typed_arguments"] for call in mutant["api_calls"] if call["name"] == "_sprintf" ) baseline_point = [baseline_typed[index]["value"] for index in (2, 3, 4)] mutant_point = [mutant_typed[index]["value"] for index in (2, 3, 4)] detected = baseline_point == [ float_token(11.0), float_token(33.0), float_token(33.0), ] and mutant_point == [ float_token(11.0), float_token(22.0), float_token(33.0), ] results["movement_second_z_to_y"] = { "function": DECODER, "offset": movement_offset, "before": before_instruction.hex(), "after": after_instruction.hex(), "case": movement_case["name"], "detected": detected, "observation": {"baseline_point": baseline_point, "mutant_point": mutant_point}, } prop_case = scenario_by_name("prop_infinite_invalid_second_lookup") owner_offset = 0x34C baseline = actual.run(prop_case, 0x037F, 0xD3) changed = mutated(decoder_raw, owner_offset, bytes.fromhex("33 c0"), bytes.fromhex("40 90")) mutant = actual.run( prop_case, 0x037F, 0xD3, overrides={DECODER: changed}, validate=False, ) baseline_typed = next( call["typed_arguments"] for call in baseline["api_calls"] if call["name"] == "_sprintf" ) mutant_typed = next( call["typed_arguments"] for call in mutant["api_calls"] if call["name"] == "_sprintf" ) baseline_owner = baseline_typed[3]["raw"] mutant_owner = mutant_typed[3]["raw"] detected = baseline_owner == 0 and mutant_owner == 1 results["null_prop_owner_zero_to_one"] = { "function": DECODER, "offset": owner_offset, "before": "33c0", "after": "4090", "case": prop_case["name"], "detected": detected, "observation": {"baseline_owner": baseline_owner, "mutant_owner": mutant_owner}, } if not all(item["detected"] for item in results.values()): raise AssertionError(("negative controls", results)) return { "pass": True, "mutation_scope": "in-memory copies of relocated actual-candidate bytes only", "controls": results, } def inventory_counts(path: Path) -> dict: payload = json.loads(path.read_text(encoding="utf-8")) values = payload.values() if isinstance(payload, dict) else payload counts = Counter(item["status"] for item in values) return {"entries": len(payload), "statuses": dict(sorted(counts.items()))} def main() -> None: if not __debug__: raise RuntimeError("refusing optimized Python: assertions are part of the oracle") parser = argparse.ArgumentParser() parser.add_argument("--output", type=Path, default=OUTPUT_DEFAULT) args = parser.parse_args() output = args.output.resolve() if output.exists(): raise ValueError(f"refusing to overwrite output: {output}") if not output.is_relative_to((ROOT / "scratch").resolve()): raise ValueError(f"output must remain under scratch: {output}") pinned = { "target": verify_hash(TARGET, PINNED_HASHES["target"], "target"), "first": verify_hash(FIRST, PINNED_HASHES["first"], "first"), "actual": verify_hash(ACTUAL, PINNED_HASHES["actual"], "actual"), "before_manifest": verify_hash(BEFORE_MANIFEST, PINNED_HASHES["before_manifest"], "before_manifest"), "first_manifest": verify_hash(FIRST_MANIFEST, PINNED_HASHES["first_manifest"], "first_manifest"), "before_stable": verify_hash(BEFORE_STABLE, PINNED_HASHES["before_stable"], "before_stable"), "first_stable": verify_hash(FIRST_STABLE, PINNED_HASHES["first_stable"], "first_stable"), "cachebeta": verify_hash(CACHEBETA, PINNED_HASHES["cachebeta"], "cachebeta"), "target_alert": verify_hash(TARGET_ALERT, PINNED_HASHES["target_alert"], "target_alert"), "target_charge": verify_hash(TARGET_CHARGE, PINNED_HASHES["target_charge"], "target_charge"), "target_combat": verify_hash(TARGET_COMBAT, PINNED_HASHES["target_combat"], "target_combat"), "coff_compare": verify_hash(ROOT / "tools/coff_compare.py", PINNED_HASHES["coff_compare"], "coff_compare"), "coff_tools": verify_hash(ROOT / "tools/campaign/_coff_tools.py", PINNED_HASHES["coff_tools"], "coff_tools"), "regression_gate": verify_hash(ROOT / "tools/regression_gate.py", PINNED_HASHES["regression_gate"], "regression_gate"), } before_manifest = json.loads(BEFORE_MANIFEST.read_text(encoding="utf-8")) first_manifest = json.loads(FIRST_MANIFEST.read_text(encoding="utf-8")) manifest_checks = { "before_frozen_target_hash": before_manifest["frozen_files"][ "build/split/source/ai/actor_looking.obj" ]["sha256"] == PINNED_HASHES["target"], "first_phase": first_manifest["phase"] == "first", "first_head": first_manifest["head"] == "d2c0babb171a51de60fe0cb9ebba4bedab1c6f61", "first_capture_sha256": first_manifest["capture_sha256"] == "e2e301ff34d075482fdb0a305c0988eed978583e9548ab73c3baec9745625554", "first_ninja_deps_sha256": first_manifest["ninja_deps_sha256"] == "f3e21bdbea84da8f8edfa534e4ccdbd61077fc28d1a870ee16aaa97e79c132d1", } if not all(manifest_checks.values()): raise AssertionError(("manifest guards", manifest_checks)) target = RoleImage("target", TARGET, PINNED_HASHES["target"]) first = RoleImage("first", FIRST, PINNED_HASHES["first"]) actual = RoleImage("actual", ACTUAL, PINNED_HASHES["actual"]) if any(first.section_raw[name] != actual.section_raw[name] for name in (DECODER, AFFECT) + HELPERS): raise AssertionError("first/actual function or helper raw bytes differ") if any( not (target.section_raw[name] == first.section_raw[name] == actual.section_raw[name]) for name in HELPERS ): raise AssertionError("target/first/actual helper raw bytes differ") executions = [] fpsw_differences = [] for case_index, scenario in enumerate(cases()): for control_index, fpcw in enumerate(FPCW_VALUES): seed = case_index * len(FPCW_VALUES) + control_index + 1 target_run = target.run(scenario, fpcw, seed) first_run = first.run(scenario, fpcw, seed) actual_run = actual.run(scenario, fpcw, seed) diagnostic_checks = { role: validate_diagnostic_details(run, scenario, seed) for role, run in ( ("target", target_run), ("first", first_run), ("actual", actual_run), ) } target_first = compare_roles(target_run, first_run, scenario) target_actual = compare_roles(target_run, actual_run, scenario) if exact_candidate_signature(first_run) != exact_candidate_signature(actual_run): raise AssertionError((scenario["name"], hex(fpcw), "first/actual observation differs")) if target_first != target_actual: raise AssertionError((scenario["name"], hex(fpcw), "target comparison differs for actual")) if not target_first["fpsw_equal"]: fpsw_differences.append( { "case": scenario["name"], "fpcw": fpcw, "target": target_run["fpsw_final"], "candidate": first_run["fpsw_final"], } ) executions.append( { "case": scenario, "fpcw": fpcw, "target": target_run, "first": first_run, "actual": actual_run, "diagnostic_checks": diagnostic_checks, "comparison": target_first, } ) negative_controls = run_negative_controls(actual) decoder_cases = [item for item in cases() if item["entry"] == "decoder"] affect_cases = [item for item in cases() if item["entry"] == "affect"] helper_hashes = { name: { "size": len(target.section_raw[name]), "sha256": sha256_bytes(target.section_raw[name]), "executed_by_corpus": name in EXECUTED_HELPERS, "target_owner": target.function_owner[name], "candidate_owner": first.function_owner[name], "target_selection": 1, "candidate_selection": 2, } for name in HELPERS } report = { "pass": True, "scope": ( "frozen January target, first natural candidate, and frozen ordinary-Ninja actual; " "real private decoder and real public movement caller" ), "build_or_production_mutation": False, "script": {"path": str(SCRIPT), "sha256": sha256_path(SCRIPT)}, "pinned_inputs": pinned, "manifest_checks": manifest_checks, "stable_inventory": { "before": inventory_counts(BEFORE_STABLE), "first": inventory_counts(FIRST_STABLE), "expected_preserved_exact_count": 6261, }, "coff_guards": { "target": target.guards(), "first": first.guards(), "actual": actual.guards(), "first_actual_all_function_and_helper_raw_exact": True, "target_first_actual_all_nine_helper_raw_exact": True, "helpers": helper_hashes, "physical_target_helper_owner_note": ( "January physical COMDAT owners are action_alert/action_charge/actor_combat; " "real_math.obj is not asserted as the selected owner" ), }, "coverage": { "direct_decoder_cases": len(decoder_cases), "public_affect_cases": len(affect_cases), "case_count": len(cases()), "fpcw_values": list(FPCW_VALUES), "executions_per_role": len(executions), "total_real_function_executions": len(executions) * 3, "all_seven_direction_types": sorted( {item["direction_type"] for item in decoder_cases if isinstance(item["direction_type"], int) and item["direction_type"] <= 6} ), "false_and_zero_paths": True, "priorities_2_3_4_and_path_short_circuits": True, "object_unit_general_missing": True, "diagnostic_lines": [349, 350, 449, 526, 529], "adjacent_float32_validity_brackets": { "lower_outside": "0x3f7fdf39", "lower_inside": "0x3f7fdf3a", "upper_inside": "0x3f801061", "upper_outside": "0x3f801062", "tested_divergence": False, }, "movement_diagnostic_x_z_z": True, "invalid_prop_owner_zero": True, "real_public_caller_never_stubs_decoder": True, "real_machine_helpers_executed": sorted(EXECUTED_HELPERS), "loaded_but_not_reached_helpers": sorted(set(HELPERS) - EXECUTED_HELPERS), "modeled_genuine_external_apis": list(APIS), "guard_layout": "separate 4 KiB data maps with unmapped 4 KiB gaps; stack centered in bounded 128 KiB map", }, "comparison_summary": { "all_tested_semantic_signatures_equal": True, "first_actual_all_tested_observations_exact": True, "expected_candidate_extra_validity_call_checked": all( item["comparison"]["expected_candidate_extra_validity_call"] for item in executions ), "fpsw_difference_count": len(fpsw_differences), "fpsw_differences": fpsw_differences, "x87_top_tag_control_and_direction_flag_preserved_all_runs": True, }, "negative_controls": negative_controls, "limitations": [ "Finite authored corpus; not exhaustive input-space or floating-point proof.", "The target inlines the first normal-vector validity check while candidates call the real helper. Four adjacent-float32 points bracketing both 0.001 magnitude-squared limits showed no divergence, but the finite corpus does not exclude every boundary case.", "sprintf/csprintf text rendering is a stable Python model; machine stack words, parsed types, formats, and downstream display_assert arguments are the evidence, not host CRT byte identity.", "Engine data/object/path/head/origin/assert/exit APIs are typed behavioral models; only the three reached inline math helpers execute genuine COFF bytes.", "Masked x87 control words 0x027f and 0x037f are covered; unmasked exception modes and every FPSW flag combination are not.", "Data buffers are bounded seeded envelopes and do not claim full engine allocation validity or exhaustive pointer aliasing.", ], "executions": executions, "conclusion": ( "PASS for the bounded corpus: target, first, and actual agree on external API semantics, " "diagnostics, final memory, return behavior, private/public ABI observations, and guarded access. " "The result is runtime evidence only: the different first-check inline/call placement caused no tested precision divergence." ), } output.write_text(json.dumps(report, indent=2, sort_keys=True) + "\n", encoding="utf-8") print(f"PASS: {output}") print(f"sha256={sha256_path(output)}") print( f"cases={len(cases())} executions_per_role={len(executions)} " f"negative_controls={negative_controls['pass']} fpsw_differences={len(fpsw_differences)}" ) if __name__ == "__main__": main()