Skip to content

Add a reproducible MinGW PE EH-frame fixture - #196

Open
zardus wants to merge 2 commits into
masterfrom
feature/pe-eh-frame-function-boundaries
Open

Add a reproducible MinGW PE EH-frame fixture#196
zardus wants to merge 2 commits into
masterfrom
feature/pe-eh-frame-function-boundaries

Conversation

@zardus

@zardus zardus commented Aug 26, 2026

Copy link
Copy Markdown
Member

THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS

Problem

The coordinated CLE and angr regressions need a real PE whose wrapper at 0x401006 already owns the bytes of an unnamed six-byte function at 0x40100a. Binaries master has no tests/x86/windows/eh-frame-occupied-start.exe, so that GNU .eh_frame boundary cannot be exercised.

Root cause

Ordinary PE fixtures do not combine an occupied CFG range, no symbol for the inner target, and a GNU FDE that is the only metadata identifying the target as a function.

Fix

Add a source-built i386 MinGW PE together with its complete assembly source, BSD-2-Clause license, and deterministic build recipe. The sole GNU FDE starts at 0x40100a; the committed PE is timestamp-free and stripped of COFF symbols.

Testing

Exact-head readback reports PE32/i386, image base 0x400000, entry RVA 0x1000, zero timestamp, zero COFF symbols, and SHA-256 1cd9ae0b00d1c4cde4cd95579cf9aae14104d9f99031aab77b0116e4e9aa7c8a. Two documented GCC 15.3.0/Binutils 2.46 builds were byte-identical. Validation: #196 (comment)

session: sharpen

@zardus

zardus commented Aug 26, 2026

Copy link
Copy Markdown
Member Author

THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS

Validation record for head ffc011f3de013f23711ded6a05a48df5ea2f726f against baseline a87538bc248531d2a1d22434143e8b9752459bac.

  • Exact PR shape: the own-merge-base/head scan verifies the added compiler-produced fixture and its load-bearing format/address shape: PE32 i386 executable; .eh_frame carries an FDE for 0x40100a of size 6.
  • Provenance/reproduction: two fresh GCC 15.3.0 / GNU Binutils 2.46 builds with zero timestamp was rerun twice in separate fresh directories; both outputs byte-compare with each other and with the committed bytes.
  • Input/native identity: committed SHA-256 1cd9ae0b00d1c4cde4cd95579cf9aae14104d9f99031aab77b0116e4e9aa7c8a; angr rustylib mapped from the isolated consumer worktrees on both arms, SHA-256 d02d517eceb3e81de4a96330678444f0faf2c3b065953f0cb8e1813583a0380f; CLE is Python-only here.
  • Real consumer: PE: Separate GNU EH-frame hints from unwind entries cle#789 and CFGFast: Preserve authoritative function starts during reconstruction angr#6948 at baseline cle a4fb8003198229d33c84df6a82f749729232fd31; angr b0feae57a9e401292e03a6f9ffbd4b388d172bf5 and head cle 89ae8c133b4c9c2ba2921429d3504ac2a0624407; angr 1b99ccbe452ed556e79177c41e624093f26ad8ed loaded the committed fixture and produced the complete output linked in this PR's output record.
  • Repeat/order control: A/B/B/A, ASLR disabled and PYTHONHASHSEED=0 for the generated angr text; the CLE hint record is a static structural capture; same-arm output is byte-identical and the cross-arm delta is nonempty.
  • Local scope: this recapture validates fixture bytes, fixture shape, and the actual consumer path only. It does not claim a fresh full-workspace gate.
  • Hosted status: fresh hosted dependency validation for this exact binaries head has not been observed in this recapture; it remains pending and no hosted success is claimed here.

@zardus

zardus commented Aug 28, 2026

Copy link
Copy Markdown
Member Author

THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS

Exact fixture-shape and consumer-output record for #196.

  • Fixture comparison: own merge base a87538bc248531d2a1d22434143e8b9752459bac versus exact head ffc011f3de013f23711ded6a05a48df5ea2f726f. The target path/shape is absent on the merge base and present on the head. PE32 i386 executable; .eh_frame carries an FDE for 0x40100a of size 6.
  • Fixture identity: SHA-256 1cd9ae0b00d1c4cde4cd95579cf9aae14104d9f99031aab77b0116e4e9aa7c8a; source provenance: the adjacent complete assembly source at this exact binaries head (SHA-256 1b2246525aca4cddbb510b4836116cf4aa78d8d4722ff4cb58caf7e029dbd99b). The complete readelf/objdump scan is retained with the exact script. The recorded recipe (two fresh GCC 15.3.0 / GNU Binutils 2.46 builds with zero timestamp) was rerun twice in fresh directories; both runs are byte-identical to the committed fixture.
  • Actual consumer: PE: Separate GNU EH-frame hints from unwind entries cle#789 and CFGFast: Preserve authoritative function starts during reconstruction angr#6948, exact baseline cle a4fb8003198229d33c84df6a82f749729232fd31; angr b0feae57a9e401292e03a6f9ffbd4b388d172bf5 versus exact head cle 89ae8c133b4c9c2ba2921429d3504ac2a0624407; angr 1b99ccbe452ed556e79177c41e624093f26ad8ed; target CLE function hints and angr function 0x40100a; configuration CLE load plus full / SAILR.
  • Native identity: angr rustylib mapped from the isolated consumer worktrees on both arms, SHA-256 d02d517eceb3e81de4a96330678444f0faf2c3b065953f0cb8e1813583a0380f; CLE is Python-only here.
  • Determinism: fresh A/B/B/A order, ASLR disabled and PYTHONHASHSEED=0 for the generated angr text; the CLE hint record is a static structural capture; each same-arm pair is byte-identical and every base/head comparison below is nonempty. Absolute checkout prefixes in tracebacks are normalized to <workspace> for publication; raw output is retained unchanged.

Before — cle

Exact consumer baseline
sections=['.edata', '.eh_frame', '.idata', '.rdata', '.text']
function_hints=[]

After — cle

Exact consumer head
sections=['.edata', '.eh_frame', '.idata', '.rdata', '.text']
function_hints=[(4198410, 6, '0')]

Before — angr

Exact consumer baseline
Traceback (most recent call last):
  File "<workspace>/scratch/apply-latest-skills-pr-audit-20260828/output-regeneration-medium/capture_decompile.py", line 125, in <module>
    function = cfg.functions[int(args.function_address, 0)]
               ~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<workspace>/scratch/apply-latest-skills-pr-audit-20260828/fixture-output-recapture/consumers/worktrees/6948-base/angr/knowledge_plugins/functions/function_manager.py", line 1175, in __getitem__
    raise KeyError(k)
KeyError: 4198410

After — angr

Exact consumer head
unsigned int sub_40100a(void)
{
    return 42;
}

@zardus
zardus force-pushed the feature/pe-eh-frame-function-boundaries branch 2 times, most recently from ffc011f to c7383da Compare August 29, 2026 19:22
@zardus

zardus commented Aug 30, 2026

Copy link
Copy Markdown
Member Author

THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS

Rebased onto binaries master; git range-diff reports the commit unchanged (=), so this is a base move only.

The reason: angr/cle#789 pins this pull request with a sync: line, and CI resolves a sibling at refs/pull/N/head rather than merged with master. At three commits behind, this tree was missing tests/i386/deep_sp_chain, which tests/analyses/decompiler/test_block_simplifier.py loads. That test is not yet in the angr tree those shards resolve, so the failure was dormant rather than live — it would have appeared the moment the resolved angr tree gained it, on a diff that has nothing to do with it.

session: sharpen

@zardus
zardus force-pushed the feature/pe-eh-frame-function-boundaries branch from c7383da to ebb7fe0 Compare August 30, 2026 13:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant