[GH-ISSUE #4539] [Feature] Triage PE imports: ATT&CK-tagged capabilities and a pefile-identical imphash #2363

Open
opened 2026-10-17 21:03:46 +00:00 by bsakaguchi · 1 comment
Owner

Originally created by @FerroLx on GitHub (Oct 16, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/4539

Before submitting

  • I searched the open and closed issues and pull requests for a related proposal.
  • I understand the contribution scope must be reviewed before integration; open questions are welcome here.
  • This request does not include credentials, private samples, or sensitive target data.

Area

Native analysis or decompilation

Current limitation

The first triage question for a Windows binary is what its imports say it can do: process injection, persistence, service control, keyboard capture, credential access, anti-debug, download, driver loading. Today that needs a disassembler session or external tooling such as pefile/capa. REA's inspect_pe_resources reads resources but not imports, and there is no import hash to pivot on threat intelligence. Related: #3413 (static packer identification) and #2729 (static PE provider) overlap on packing facts.

Use cases

  • An automated (LLM) triage step that needs a few KB of behaviour facts, not a disassembly.
  • Pivoting on the import hash (imphash) as pefile and VirusTotal compute it.
  • Spotting crafted images whose import tables disagree (what the loader binds vs what other tools show).

Desired outcome and success criteria

A read-only inspect_pe_imports tool (CLI and MCP) for a local PE32/PE32+ image. It returns:

  • imported APIs grouped into behaviour categories with MITRE ATT&CK technique IDs and strong/medium/weak confidence tiers;
  • the imphash exactly as pefile computes it;
  • DLLs, runtime-resolution hints and basic packing facts;
  • the complete import and export tables as retained Evidence, using REA's standard detail contract.

Success means imports, exports, ordinal resolution and imphash match pefile on real and crafted images. Capabilities are stated as "imports consistent with", never as a verdict.

Expected interaction with targets

Read existing files or captured data

Target and scope details (optional)

Static parsing only; no execution, no disassembly. The ATT&CK taxonomy is a new interpretive surface (versioned, built from Microsoft API names and ATT&CK IDs, no third-party rule text). The maintainers' view on whether and how it belongs is welcome. ELF and Mach-O are out of scope for now.

Verification available so far

I have a prototype or observed results

Verification

Prototype on the fork branch feat/binary-imports. A real-toolchain lane builds mingw-w64 x86/x64 fixtures and compares every import, delay import, export, ordinal resolution and imphash with pefile 2024.8.26, and the DLL set with llvm-readobj, through CLI and MCP. Seven adversarial review rounds. The imphash matches pefile on 104 of 107 real and crafted images; the remaining 3 are malformed and refused.

Originally created by @FerroLx on GitHub (Oct 16, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/4539 ### Before submitting - [x] I searched the open and closed issues and pull requests for a related proposal. - [x] I understand the contribution scope must be reviewed before integration; open questions are welcome here. - [x] This request does not include credentials, private samples, or sensitive target data. ### Area Native analysis or decompilation ### Current limitation The first triage question for a Windows binary is what its imports say it can do: process injection, persistence, service control, keyboard capture, credential access, anti-debug, download, driver loading. Today that needs a disassembler session or external tooling such as pefile/capa. REA's `inspect_pe_resources` reads resources but not imports, and there is no import hash to pivot on threat intelligence. Related: #3413 (static packer identification) and #2729 (static PE provider) overlap on packing facts. ### Use cases - An automated (LLM) triage step that needs a few KB of behaviour facts, not a disassembly. - Pivoting on the import hash (imphash) as pefile and VirusTotal compute it. - Spotting crafted images whose import tables disagree (what the loader binds vs what other tools show). ### Desired outcome and success criteria A read-only `inspect_pe_imports` tool (CLI and MCP) for a local PE32/PE32+ image. It returns: - imported APIs grouped into behaviour categories with MITRE ATT&CK technique IDs and strong/medium/weak confidence tiers; - the imphash exactly as pefile computes it; - DLLs, runtime-resolution hints and basic packing facts; - the complete import and export tables as retained Evidence, using REA's standard `detail` contract. Success means imports, exports, ordinal resolution and imphash match pefile on real and crafted images. Capabilities are stated as "imports consistent with", never as a verdict. ### Expected interaction with targets Read existing files or captured data ### Target and scope details (optional) Static parsing only; no execution, no disassembly. The ATT&CK taxonomy is a new interpretive surface (versioned, built from Microsoft API names and ATT&CK IDs, no third-party rule text). The maintainers' view on whether and how it belongs is welcome. ELF and Mach-O are out of scope for now. ### Verification available so far I have a prototype or observed results ### Verification Prototype on the fork branch `feat/binary-imports`. A real-toolchain lane builds mingw-w64 x86/x64 fixtures and compares every import, delay import, export, ordinal resolution and imphash with pefile 2024.8.26, and the DLL set with llvm-readobj, through CLI and MCP. Seven adversarial review rounds. The imphash matches pefile on 104 of 107 real and crafted images; the remaining 3 are malformed and refused.
Author
Owner

@FerroLx commented on GitHub (Oct 25, 2026):

#6509 now covers the import tables and the pefile-compatible imphash, and inspect_pe_certificates covers the Authenticode certificate table. Thanks @mvanhorn. My draft branch (FerroLx/rea:feat/binary-imports) overlaps both, so I won't open it as written.

Two parts of this issue are not in main yet. I'd like to propose each as a small follow-up PR that builds on #6509's parsed import facts rather than adding a second parser:

  1. Capability tags on imports: a static table that maps imported APIs to behaviour categories and ATT&CK technique IDs (for example VirtualAllocEx + WriteProcessMemory + CreateRemoteThread → process injection, T1055). It would be reported as derived from observed imports, never as observed behaviour, and unknown APIs would stay untagged rather than read as benign.
  2. API-name strings outside the import table: API names that appear as strings, the usual sign of GetProcAddress-style dynamic resolution. They'd be paged with explicit coverage, so a binary that resolves APIs at runtime isn't reported as importing nothing.

Neither executes the target, and both read the same caller-selected local file. Is either one in scope? If yes, which should come first? I'll wait for a maintainer decision before porting anything.

<!-- gh-comment-id:6396997669 --> @FerroLx commented on GitHub (Oct 25, 2026): #6509 now covers the import tables and the pefile-compatible imphash, and `inspect_pe_certificates` covers the Authenticode certificate table. Thanks @mvanhorn. My draft branch (`FerroLx/rea:feat/binary-imports`) overlaps both, so I won't open it as written. Two parts of this issue are not in `main` yet. I'd like to propose each as a small follow-up PR that builds on #6509's parsed import facts rather than adding a second parser: 1. **Capability tags on imports:** a static table that maps imported APIs to behaviour categories and ATT&CK technique IDs (for example `VirtualAllocEx` + `WriteProcessMemory` + `CreateRemoteThread` → process injection, T1055). It would be reported as *derived* from observed imports, never as observed behaviour, and unknown APIs would stay untagged rather than read as benign. 2. **API-name strings outside the import table:** API names that appear as strings, the usual sign of `GetProcAddress`-style dynamic resolution. They'd be paged with explicit coverage, so a binary that resolves APIs at runtime isn't reported as importing nothing. Neither executes the target, and both read the same caller-selected local file. Is either one in scope? If yes, which should come first? I'll wait for a maintainer decision before porting anything.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#2363
No description provided.