Conversation
|
THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS Validation record for head
Corpus A/B, 1,557 PE objects, one process per object per side, with the
The issue proposed masking that bit off. Measured, keeping it is better on every
Both images are Thumb only, so an ARM-mode node at a hint address is a CFG effect of the hints themselves.
That gain is ARM64, and it concentrates: the four largest are ARM64 images whose On ARMNT the hints are close to neutral for Nine of the 22 lose at most four blocks or six functions, which is a hint at a
Caveats: the corpus is a private dataset, so objects are named by machine type and count rather than by path; angr/binaries#183 reproduces both architectures publicly. CI on this PR: all 20 checks are green at head Correction, 2026-09-03. An earlier version of this comment said that Re-keyed 2026-08-28. The figures above were measured at CI status, head
The repair belongs on the sibling. CI disposition, head
Those 39 of the 52 pre-existing errors come from
The macOS and Windows legs failed on Re-keyed 2026-08-29. The branch was rebased from
The 2026-08-28 note above argued the figures carried over because master had touched none of this change's files. That argument does not hold at this baseline: At the new head: |
|
Corpus decompilation diffs can be found at angr/dec-snapshots@master...angr/cle_756 |
b205ac2 to
340bbea
Compare
340bbea to
69a3907
Compare
|
THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS The function hints cle derives from the exception directory of the two ARM PE fixtures, before and after this change. The fixtures come from the angr/binaries pull request linked from the description. the reproducerimport logging, os
logging.getLogger("cle").setLevel(logging.CRITICAL)
import cle
BIN = os.environ["BINARIES"] # a checkout of angr/binaries
T = lambda *p: os.path.join(BIN, "tests", *p)
for name, path in (("ARM64", T("aarch64", "windows", "pe_reloc_arm64.exe")),
("ARMNT", T("armel", "windows", "pe_reloc_armnt.exe"))):
obj = cle.Loader(path, auto_load_libs=False).main_object
hints = obj.function_hints
print(f"{name} {os.path.basename(path)}: {len(hints)} function hints")
names = {0: "EH_FRAME", 1: "EXTERNAL_EH_FRAME", 2: "EXPORT_TABLE"}
for h in hints:
print(f" {h.addr:#x} size={h.size} source={names[int(h.source)]}")Before — the ARM64 and ARMNT exception directories are never parsed, so CFGFast gets nothing to seed from: cle master at
|
|
THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS Two red attempts on run 33021253016, two unrelated causes, neither of them in this diff. Attempt 2 --
|
_handle_seh took the exception directory from pefile, which parses it for x86-64 and Itanium only, so an ARM64 or ARMNT image produced no function hints at all even though its ABI requires an unwind entry for every non-leaf function. Read the eight-byte record for those two machines directly: the function's start RVA, then either an .xdata RVA or unwind data packed into the second word, which is where the function length comes from. Records that describe a fragment of a function beginning elsewhere are not function starts and are skipped, and an ARMNT start address keeps its Thumb bit, which is what selects the decoder.
The Typecheck job scores each changed file against master's copy of it: badness is (10*errors + warnings)/lines and must not increase. Its environment installs types-pefile, whose stub types OPTIONAL_HEADER.DATA_DIRECTORY as a list of entries carrying VirtualAddress and Size. _meta_dd declared pefile.Structure, the base class that has neither, which threw that away for every caller: 39 of pe.py's 52 errors are a caller reading VirtualAddress or Size off the result. _handle_seh_arm reads exc_dd.VirtualAddress and exc_dd.Size to find the exception directory, so it added the 53rd and 54th. Leaving the return type to inference gives the entry type where the stub is installed and an unknown one where it is not, so the callers type-check and nothing about them changes at run time. pe.py goes from 54 errors to 13. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
7b7746e to
c138179
Compare
THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS
Problem
An ARM64 or ARMNT PE reaches CFGFast with no function hints at all. On
binaries/tests/aarch64/windows/pe_reloc_arm64.exeandbinaries/tests/armel/windows/pe_reloc_armnt.exe:Both ABIs require an unwind entry for every non-leaf function, so the exception
directory is the most complete function-start table these images carry, and on a
stripped one it is the only one. The data is in the file: the exception data
directory of the ARM64 image is 0x18 bytes at rva 0x4000, three eight-byte
records, and the ARMNT image's is 0x30, six records.
Root cause
_handle_sehreaches the directory only through pefile:pefile 2024.8.26 builds
DIRECTORY_ENTRY_EXCEPTIONfromIMAGE_RUNTIME_FUNCTION_ENTRYrecords, which it parses for x86-64 and Itaniumonly. On both fixtures the attribute is absent although the directory is
populated:
The
hasattris therefore false for every ARM image and the hint loop never runs.Fix
Dispatch on
FILE_HEADER.Machineand read the eight-byte ARM64/ARMNT recorddirectly: function start rva, then either a packed unwind word or an
.xdatapointer, told apart by the low two bits. The function length comes from the
packed word or from the
.xdataheader, and a record describing a fragment of afunction that begins elsewhere is skipped. An ARMNT start address keeps its Thumb
bit, as an ARM function address does everywhere else in cle, because that bit
selects the decoder.
Testing
tests/test_pe_function_hints.pypins the hints of both fixtures --test_aarch64,test_armntandtest_armnt_matches_the_function_pointer_table,which cross-checks the ARMNT starts against the image's own function pointer
table -- and
test_x86_64_matches_pefilechecks the x86-64 path still agrees withpefile's parse. The three ARM tests see 0 hints on the merge base.
TheCorrected: both jobs domacosandwindowsjobs check out binaries master,so they stay red until the fixture pull request merges.
resolve the referenced fixture pull request -- the
windowslog recordsChecking out angr/binaries at refs/pull/183/head-- and both are green.Fixes #753. Validation: #756 (comment)
sync: angr/binaries#183
session: sharpen