Files
3d84215bb2 feat(pe): inspect TLS callbacks and load configuration (#7008)
* feat(pe): inspect TLS callbacks and load configuration

Adds inspect-pe-load-config and inspect_pe_load_config for PE32 and
PE32+ images, with artifact hashes and file ranges in the returned
evidence. Reports callback addresses and mappings, plus size-covered
security-cookie, SafeSEH, CFG, EH-continuation and XFG fields;
flag-derived mitigation claims are explicitly labeled inferred. Missing
directories remain null, and malformed storage or exhausted read budgets
return errors without partial success. Adds documentation and tests for
service validation, CLI/MCP access, malformed inputs and stable-file
handling.

x86 images that declare the legacy 64-byte load-config directory are
read to the structure's own Size when those bytes are file-backed, as
the Windows loader does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016y53PdpyMAp9RSW65fatHe

* fix(pe): retain snapshot facts and bound load-config section lookup

Keep the completed stable-read path, SHA-256 and byte count as a
file-snapshot-hash partial observation when descriptor close fails or is
cancelled. Report the checked Size span as structure_location and add it
to Evidence locations beside the declared directory range. Resolve
callback sections through a sorted segment index built once per image,
keeping the ambiguity failure. Pin every load-config field to offsets
transcribed from the PE/COFF spec and llvm COFF.h at its exact Size
boundary for PE32 and PE32+.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016y53PdpyMAp9RSW65fatHe

---------

Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 22:06:41 +08:00

1.6 KiB

PE TLS/load-config verification - 2026-10-24

All runs used macOS arm64 and Node 26.5.0. No target was executed.

Cross-compiled lane

npm run verify:pe:load-config with Zig 0.16.0 compiled freestanding C samples for x86_64-windows-gnu and x86-windows-gnu, then invoked the public inspect-pe-load-config --json CLI.

Target Callback VA RVA File offset Section
PE32+ 0x140001000 0x1000 0x400 .text
PE32 0x401000 0x1000 0x400 .text

Both images declare one callback and no load-config directory.

Linker-produced and vendor images (not committed)

  • A MinGW-linked PE32+ sample with two .CRT$XL* callbacks (zig cc -target x86_64-windows-gnu): four callbacks reported in .text at 0x140001000, 0x140001020, 0x140001470 and 0x140001500, matching the callback array at AddressOfCallBacks 0x14002B8C8 shown by llvm-readobj --coff-tls-directory.
  • Sysinternals strings64.exe (PE32+, MSVC): load-config fields match llvm-readobj --coff-load-config.
  • Sysinternals strings.exe (PE32, MSVC): the data directory declares 64 bytes while the structure Size is 188 (0xBC). REA reports size: 188, security cookie 0x4560dc in .data, SafeSEH table 0x453b28 with 7 handlers and guard flags 0x100, matching llvm-readobj.

Sized fields beyond these samples, EH-continuation and XFG declarations, and malformed ranges are covered by synthetic fixtures. Runtime enforcement of any mitigation is not verified.