Skip to content

Add ARM64, ARMNT and ReadyToRun PE fixtures - #183

Open
zardus wants to merge 1 commit into
masterfrom
feature/pe-loader-fixtures
Open

zardus wants to merge 1 commit into
masterfrom
feature/pe-loader-fixtures

Conversation

@zardus

@zardus zardus commented Aug 17, 2026 •

Copy link
Copy Markdown
Member

THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS

Problem

The repository has no Windows image for either ARM machine type and no .NET
ReadyToRun assembly, so nothing covers the PE structures whose layout depends
on the target: base relocations, the exception directory, and the machine type
a ReadyToRun image published for a non-Windows target carries. On master all
three paths are absent:

CLEFileNotFoundError: Could not find file .../tests/aarch64/windows/pe_reloc_arm64.exe
CLEFileNotFoundError: Could not find file .../tests/armel/windows/pe_reloc_armnt.exe
CLEFileNotFoundError: Could not find file .../tests/x86_64/readytorun_linux_x64.dll

Root cause

Every PE here is x86 or x86-64 and none is produced by dotnet publish, so the
machine-dependent directories have only ever been exercised in one shape.

Fix

pe_reloc_arm64.exe and pe_reloc_armnt.exe are freestanding 3072-byte images
built from one source, each carrying base relocations and an exception
directory in its architecture's shape. readytorun_linux_x64.dll comes
straight out of dotnet publish -r linux-x64 -p:PublishReadyToRun=true.
Sources and build scripts are in tests_src/windows; digests are in the
validation record.

Testing

Read back with cle at master: the ARM64 image reports
IMAGE_FILE_HEADER.Machine = 0xaa64 and the ARMNT one 0x01c4, both with a
non-empty EXCEPTION and BASERELOC directory and five sections. The
ReadyToRun DLL reports machine 0xfd1d and cle refuses it with
ArchNotFound: Can't find architecture info for architecture 0xfd1d, which is
the case its consumer fixes. Used by angr/cle#755 and by its two siblings on
the PE backend, both named in the validation comment.

Validation: #183 (comment)

session: sharpen

@zardus

zardus commented Aug 27, 2026 •

Copy link
Copy Markdown
Member Author

THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS

Validation record for head 4d025515ea7b693c5331a903f67f20f9bc844815 against baseline 003e82a2bfa641530924055695b36cec8af483ab. This is a fixture-only change, so the evidence is the images read back out of the branch with pefile rather than a test run.

tests/aarch64/windows/pe_reloc_arm64.exe — 3072 bytes, sha256 3aa284247bc5942c3d5c1739aab969de93caaf32820d6f7d45e7bbffdac78bb1

  • Machine 0xAA64 (IMAGE_FILE_MACHINE_ARM64), optional header magic 0x020B (PE32+), ImageBase 0x140000000
  • Exception directory (index 3): RVA 0x4000, size 24. Base relocation directory (index 5): RVA 0x5000, size 16 — one block, three DIR64 entries plus an ABSOLUTE pad
  • Sections: .text, .rdata, .data, .pdata, .reloc

tests/armel/windows/pe_reloc_armnt.exe — 3072 bytes, sha256 4b514db52ac60df2ff3c45e0a9a64d3523db87f004865135a1c959f859c77674

  • Machine 0x01C4 (IMAGE_FILE_MACHINE_ARMNT), optional header magic 0x010B (PE32), ImageBase 0x400000
  • Exception directory: RVA 0x4000, size 48. Base relocation directory: RVA 0x5000, size 28 — two blocks, six entries: two IMAGE_REL_BASED_THUMB_MOV32 (type 7) at page 0x1000, three IMAGE_REL_BASED_HIGHLOW plus a pad at page 0x2000. The THUMB_MOV32 entries are the point of this fixture

tests/x86_64/readytorun_linux_x64.dll — 4608 bytes, sha256 fe42accda919bccda1b4b7cfbf15020fc9e1252bef16b9dab4ded5106ba9066e

  • Machine 0xFD1D, which is not a standard value: it is IMAGE_FILE_MACHINE_AMD64 (0x8664) exclusive-ored with 0x7B79, the transformation a ReadyToRun image published for a non-Windows target carries. That is what the consumer has to resolve
  • Optional header magic 0x020B (PE32+), characteristics 0x2022 (DLL). Exception directory: RVA 0x30d8c, size 24. Base relocation directory: RVA 0x51000, size 12
  • COM descriptor (index 14): RVA 0x10530, size 72 — CLI header, runtime version 2.5, metadata RVA 0x106b0 size 1340. Its ManagedNativeHeader at RVA 0x30c00 size 148 begins 52 54 52 00 (RTR\0), ReadyToRun major 10 minor 1

Build inputs present in the branch: tests_src/windows/pe_reloc_arm.c, tests_src/windows/pe_reloc_arm.build.sh (clang 21.1.8 with lld-link, targets aarch64-pc-windows-msvc and thumbv7-pc-windows-msvc, /dynamicbase), tests_src/windows/readytorun_linux_x64.build.sh (.NET SDK 9.0.316, dotnet publish -r linux-x64 -p:PublishReadyToRun=true).

Caveats: no image was rebuilt here — neither the clang/lld-link toolchain nor the .NET SDK was exercised — so byte-for-byte reproducibility is unconfirmed, and all three images carry a non-zero TimeDateStamp (0x6A828CE7 on the two ARM images, 0x8C058AB8 on the DLL), so they are not timestamp-deterministic in any case. Consumers: angr/cle#755, angr/cle#756, angr/cle#757.

Re-keyed 2026-08-28. The figures above were measured at 25318d666b6464c5aa91f701e091a82d80c625dd on baseline 8646be4eafa4f1fc285d787fb2b73426a5e11d19, which is the head the opening line named until now; the branch is at 8159566adc4c1ae5128d6f4da0533be399486cb2 on de38bc3dbd052f7f9d2442cda0e43eee8e4263a8. git range-diff 8646be4eafa4f1fc285d787fb2b73426a5e11d19..25318d666b6464c5aa91f701e091a82d80c625dd de38bc3dbd052f7f9d2442cda0e43eee8e4263a8..8159566adc4c1ae5128d6f4da0533be399486cb2 reports every commit unchanged and git diff 25318d666b6464c5aa91f701e091a82d80c625dd 8159566adc4c1ae5128d6f4da0533be399486cb2 differs only by master's own advance (4 files changed, 42 insertions(+)). Master touched none of the files this change touches, and the three images are the same blobs before and after the move — pe_reloc_arm64.exe d7d57440, pe_reloc_armnt.exe c141b939, readytorun_linux_x64.dll bbac7553 — so the header readings above are readings of exactly these bytes.

Rebased 2026-08-29. Re-keyed onto binaries master d4ffa2f06ee274779244b95816a0a4fa739d262c. The opening named 8159566adc4c1ae5128d6f4da0533be399486cb2 on baseline de38bc3dbd052f7f9d2442cda0e43eee8e4263a8; the branch has since passed through 0883ef10e21295a86cd623c2c13607c7b0b6f77a on baseline 9d9d9e0079a1f67e99046f1ebb9d4625b41152de. git range-diff de38bc3dbd052f7f9d2442cda0e43eee8e4263a8..8159566adc4c1ae5128d6f4da0533be399486cb2 d4ffa2f06ee274779244b95816a0a4fa739d262c..fe84f5d78885a2375606078d6a6cf0df116c9d3f reports the commit unchanged and the two git diff <merge-base>..<head> outputs are byte-identical, so the three header readings above are readings of exactly these bytes on a new base. The branch was moved because a pull request that pins this one is checked out at its branch tip rather than merged with master, so being behind master was failing unrelated tests on the consumer. This repository schedules no checks: at the new head both check-runs and actions/runs report 0, as they do for every angr/binaries pull request.

Rebased 2026-09-04. Re-keyed onto binaries master 003e82a2bfa641530924055695b36cec8af483ab. The opening named fe84f5d78885a2375606078d6a6cf0df116c9d3f; the branch has since passed through d81abdd051527b0f70644d2a8fbb5a97d95ac23e and is now at 4d025515ea7b693c5331a903f67f20f9bc844815. git range-diff d4ffa2f06ee274779244b95816a0a4fa739d262c..fe84f5d78885a2375606078d6a6cf0df116c9d3f 003e82a2bfa641530924055695b36cec8af483ab..4d025515ea7b693c5331a903f67f20f9bc844815 reports the commit unchanged, the added/removed line lists of the two git diff <merge-base>..<head> outputs are byte-identical at 134 lines each, git diff --name-status is identical, and every touched path has the same blob at both heads — pe_reloc_arm64.exe d7d57440, pe_reloc_armnt.exe c141b939, readytorun_linux_x64.dll bbac7553, plus the three tests_src/ files. Master touched none of those paths in the range rebased over (git diff --quiet <old-base> <new-base> -- <files> passes), so the header readings above are readings of exactly these bytes. The replay was plain: no conflict, no hand resolution, no fixup. The move was needed because a pull request that pins this one is checked out at its branch tip rather than merged with master, so being behind master was failing unrelated tests on the consumers — cle #757 and #755 were failing tests/test_gopclntab.py and tests/test_macho.py on CLEFileNotFoundError for aarch64/langdetect_go.macho and aarch64/relocatable_object.macho, two fixtures that landed on binaries master after this branch was cut. This repository schedules no checks: at the new head both check-runs and actions/runs report total_count 0, as they do for every angr/binaries pull request.

@zardus
zardus force-pushed the feature/pe-loader-fixtures branch from 25318d6 to 8159566 Compare August 27, 2026 14:44
@zardus

zardus commented Aug 28, 2026

Copy link
Copy Markdown
Member Author

THIS MESSAGE WAS GENERATED BY AN AUTOMATED PROCESS

All three added images read back with cle at master (a4fb8003), against a
checkout of angr/binaries master and against this branch. The command is the
same on both sides:

import cle, pefile
ld = cle.Loader(path, auto_load_libs=False)
pe = pefile.PE(path, fast_load=True); pe.parse_data_directories()
print(hex(pe.FILE_HEADER.Machine), hex(ld.main_object.entry), len(ld.main_object.relocs))
print([d.name for d in pe.OPTIONAL_HEADER.DATA_DIRECTORY if d.Size])

Before — none of the three is in the repository:

angr/binaries master
tests/aarch64/windows/pe_reloc_arm64.exe:
  CLEFileNotFoundError: Could not find file .../tests/aarch64/windows/pe_reloc_arm64.exe
tests/armel/windows/pe_reloc_armnt.exe:
  CLEFileNotFoundError: Could not find file .../tests/armel/windows/pe_reloc_armnt.exe
tests/x86_64/readytorun_linux_x64.dll:
  CLEFileNotFoundError: Could not find file .../tests/x86_64/readytorun_linux_x64.dll

After — the two ARM images load with their machine-dependent directories
populated, and the ReadyToRun DLL reaches the machine type its consumer is
about:

with this change
tests/aarch64/windows/pe_reloc_arm64.exe:
  backend PE   arch <Arch AARCH64 (LE)>   3072 bytes
  IMAGE_FILE_HEADER.Machine = 0xaa64   entry 0x14000119c
  non-empty data directories: EXCEPTION, BASERELOC
  base relocations applied by cle: 1
  sections: .text@0x140001000, .rdata@0x140002000, .data@0x140003000, .pdata@0x140004000, .reloc@0x140005000
tests/armel/windows/pe_reloc_armnt.exe:
  backend PE   arch <Arch ARMEL (LE)>   3072 bytes
  IMAGE_FILE_HEADER.Machine = 0x01c4   entry 0x401125
  non-empty data directories: EXCEPTION, BASERELOC
  base relocations applied by cle: 1
  sections: .text@0x401000, .rdata@0x402000, .data@0x403000, .pdata@0x404000, .reloc@0x405000
tests/x86_64/readytorun_linux_x64.dll:
  ArchNotFound: Can't find architecture info for architecture 0xfd1d with '' bits and unsure endness

@zardus
zardus force-pushed the feature/pe-loader-fixtures branch from d81abdd to 4d02551 Compare September 4, 2026 16:43
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