Files
apk-reverse/tests/unit/test_verify_ref_claims_10c.py
root 90d9bd3e57 Audit the ref drop folder a third time, and measure what it can measure
ref/ still held the sixteen write-ups absorbed on 2026-10-24, with unchanged mtimes, so this pass
re-read them instead of re-absorbing. Nine generalisable mechanisms were still missing: Pyarmor's
outer container layer and its three nonce scopes (plus the live dump being structurally incomplete),
fixed-width arithmetic in the 12-byte key VM, Python compiled to native extensions, the rebuilt
libil2cpp ELF fingerprint (JNI_OnLoad / own DT_INIT / SHT_LOUSER), a container VM's block schedule,
driving String::NewLen over every literal index as an oracle, VMs that live in the managed layer,
array literals materialised by InitializeArray instead of .rodata, framework crypto primitives as
the hook target, a comparison gate as a prefix oracle, and the debugger's own stop policy
(SIGPWR/SIGXCPU suspend-to-crash, one database per activity).

One absorbed claim was wrong and is corrected: python-bytecode-recovery section 5 said an unset
nonce[15] decrypts the first block plausibly and then diverges. Counter mode has no such state --
the same nonce differing in that one byte changes the keystream from block 0, measured at 16/16
bytes.

verify_ref_claims_10c.py carries the three device-free checks. Its first draft was decorative -- the
comparison check counted work inside the loop it was measuring -- so the comparators are now
compiled at -O2, every check has a negative control that must come out empty, and the verdict
travels as a return value rather than through a global list. tests/unit/test_verify_ref_claims_10c.py
injects the wrong claim into each check and requires the failure.

Registration: two capability rows (il2cpp-managed-layer-bytecode-vm unverified,
comparison-cost-oracle observed for the host half), two evidence-summary rows, one new and three
extended route-inventory rows, three coverage bullets. SKILL.md and routing.md unchanged; the record
is EXTENSION-ref-absorption-2026-10c.md. Gates and pytest green (796 passed).
2026-10-27 00:33:49 +08:00

94 lines
3.3 KiB
Python

"""The 2026-10-27 host fixture must be able to fail.
`docs/tool-verification/fixtures/verify_ref_claims_10c.py` is the only thing standing behind three
`observed` labels, so its checks are as load-bearing as a gate. The first draft failed the rule this
repository applies to gates: the comparison check counted iterations inside the Python loop it was
measuring, so `n == k + 1` restated its own source and could never fail for a real reason. It now
compiles the two comparators and measures the compiler's output.
Each test here injects the wrong claim and requires the check to reject it, plus one test that the
process exit code follows the verdict. `observed` on a host with neither `openssl` nor a C compiler
is a skip, not a pass.
"""
from __future__ import annotations
import importlib.util
import shutil
import pytest
from conftest import REPO_ROOT
pytestmark = pytest.mark.unit
FIXTURE = REPO_ROOT / "docs" / "tool-verification" / "fixtures" / "verify_ref_claims_10c.py"
@pytest.fixture(scope="module")
def claims():
spec = importlib.util.spec_from_file_location("verify_ref_claims_10c", str(FIXTURE))
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
def _need_openssl():
if not shutil.which("openssl"):
pytest.skip("no openssl on this host: the CTR check degrades to SKIP")
def _need_cc():
if not (shutil.which("gcc") or shutil.which("cc") or shutil.which("clang")):
pytest.skip("no C compiler on this host: the comparison check degrades to SKIP")
def test_checks_pass_on_the_claim(claims):
_need_openssl()
_need_cc()
assert claims.ctr_nonce_tail() is True
assert claims.comparison_oracle() is True
assert claims.header_walk() is True
def test_ctr_check_rejects_an_unchanged_nonce(claims):
_need_openssl()
base = bytes(range(12)) + b"\x00\x00\x00"
same = base + b"\x02"
assert claims.ctr_nonce_tail(nonce_a=same, nonce_b=same) is False
def test_comparison_check_rejects_a_full_pass_mislabelled_early(claims):
_need_cc()
assert claims.comparison_oracle(early_source=claims.C_FULL) is False
def test_comparison_check_rejects_an_early_exit_mislabelled_constant(claims):
_need_cc()
assert claims.comparison_oracle(full_source=claims.C_EARLY) is False
def test_header_check_rejects_an_off_grid_start(claims):
assert claims.header_walk(start=0x110) is False
def test_header_check_rejects_ground_truth_that_disagrees(claims):
# the tail-most pair no longer sits at the largest offset, so "declared" and the forward scan
# cannot both be the file length
pairs = [(0x1100, 0x08), (0x1300, 0x10), (0x10A0, 0x10)]
assert claims.header_walk(pairs=pairs) is False
def test_main_exit_code_follows_the_verdict(claims, monkeypatch):
# a check that returns False without printing must still fail the run
monkeypatch.setattr(claims, "ctr_nonce_tail", lambda: False)
monkeypatch.setattr(claims, "comparison_oracle", lambda: True)
monkeypatch.setattr(claims, "header_walk", lambda: True)
assert claims.main() == 1
def test_main_treats_a_skip_as_not_a_failure(claims, monkeypatch):
monkeypatch.setattr(claims, "ctr_nonce_tail", lambda: None)
monkeypatch.setattr(claims, "comparison_oracle", lambda: True)
monkeypatch.setattr(claims, "header_walk", lambda: True)
assert claims.main() == 0