petriage 0.1.0

Cross-platform PE file surface analysis tool for malware analysts
Documentation

petriage

Formerly readpe (renamed to avoid naming collisions with existing tools).

A fast, cross-platform PE (Portable Executable) file surface analysis tool with CLI and GUI, written in Rust.

Motivation

Malware analysts frequently examine Windows PE files, but the most capable surface analysis tools -- PEStudio and CFF Explorer -- only run on Windows. This forces analysts to maintain Windows VMs just for static triage, even when execution is unnecessary. Cross-platform alternatives are either GUI-only (PE-bear, XPEViewer), Python-based and slow (pefile, peframe), or unmaintained CLI tools with limited features (pev/readpe in C).

petriage fills this gap: a single compiled binary that runs natively on Linux, macOS, and Windows, providing comprehensive PE surface analysis from the command line with zero runtime dependencies.

Concept

  • No execution -- Pure static/surface analysis. The PE is never loaded or executed, making it safe for malware triage.
  • All-in-one -- Consolidates the features analysts typically need multiple tools for (headers, imports, strings, hashes, entropy) into one command.
  • Fast -- Native Rust binary. Processes files in milliseconds, suitable for batch analysis of large sample sets.
  • Composable -- JSON output (--json) enables piping to jq, integration with SIEMs, and scripting in automation pipelines.
  • Offline -- No network calls. No VirusTotal lookups, no update checks. Fully air-gapped friendly.

Features

Feature Description
DOS Header e_magic, e_lfanew
COFF Header Machine type, timestamp, characteristics
Optional Header Magic, entry point, image base, subsystem, DLL characteristics, data directories
Sections Name, virtual/raw size and address, characteristics, Shannon entropy
Imports DLL names and imported function names with suspicious API indicators
Exports Exported function names, ordinals, RVAs
Strings ASCII and UTF-16LE extraction with configurable minimum length
Hashes MD5, SHA1, SHA256 of the entire file, imphash (Mandiant-compatible import hash)
Overlay Detection of data appended beyond the PE structure
Suspicious API Indicators Auto-tags ~130 Windows APIs across 12 risk categories (Process Injection, Code Execution, Network, Evasion, etc.) with severity levels (high/medium/low)
Anomaly Detection 21 heuristic rules detecting packing indicators, W^X violations, missing security features (ASLR/DEP/CFG), timestamp anomalies, structural irregularities, suspicious API combos, OPSEC indicators (PDB path leakage), and Rich Header integrity (checksum tampering, missing Rich Header)
Resource Directory Resource tree enumeration, VS_VERSIONINFO parsing (FileVersion, CompanyName, OriginalFilename, etc.), manifest extraction (UAC requestedExecutionLevel), embedded icon extraction and display (GUI)
Rich Header XOR key extraction, Rich Hash (MD5, YARA/VirusTotal compatible), checksum verification (tampering detection), compiler/linker tool entries (comp_id, prod_id, build_id, count) with Product ID database (~70 entries, VS 6.0--2022). Enables compiler identification, build environment fingerprinting, and attribution
TLS Directory TLS callback detection with VA listing. Critical for malware — TLS callbacks execute before main() and are commonly used for anti-debug/unpacking
Debug Directory Debug entry enumeration, CodeView (RSDS) parsing with PDB path, GUID, and age extraction. PDB paths are always parsed and surfaced as OPSEC indicators (highlighted in CLI and GUI)
Authenticode Digital signature presence detection, PKCS#7/CMS parsing, X.509 certificate chain extraction (subject, issuer, serial, validity, SHA-1 thumbprint), signer identification, expiry/self-signed/chain warnings. Cross-platform — no Windows CryptoAPI required. Trust verification is not performed.
Output Human-readable tables (default), JSON (--json), NDJSON (--ndjson), file output (-o)
Batch Mode Analyze all PE files in a directory (--batch <dir>)
Fail-on Exit with code 3 if anomalies meet a severity threshold (--fail-on <severity>)
TUI Hex Viewer Interactive terminal hex viewer with region navigation — select PE structures (DOS Header, COFF, sections, overlay) and browse hex dumps with keyboard scrolling (opt-in via --features tui)
GUI egui-based GUI with tabbed views, drag & drop, filters, entropy color-coding, suspicious API highlighting, embedded icon display, PE header editor with Save As (opt-in via --features gui)

Installation

Build from source (CLI only)

git clone https://github.com/uky007/petriage.git
cd petriage
cargo build --release

The binary will be at target/release/petriage.

Build with TUI Hex Viewer

cargo build --release --features tui

Build with GUI

cargo build --release --features gui

GUI requires system libraries for the graphics backend (OpenGL/Vulkan). On Debian/Ubuntu:

sudo apt install libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev libxkbcommon-dev libssl-dev libgtk-3-dev

Cross-compilation

cargo build --release --target x86_64-unknown-linux-gnu
cargo build --release --target aarch64-apple-darwin
cargo build --release --target x86_64-pc-windows-gnu

Usage

CLI

petriage <file.exe>              # Show all information
petriage <file.exe> -H           # Headers only
petriage <file.exe> -i           # Imports only
petriage <file.exe> -e           # Exports only
petriage <file.exe> -s           # Sections only
petriage <file.exe> -S           # Strings only
petriage <file.exe> --hashes     # File hashes only
petriage <file.exe> --overlay    # Overlay only
petriage <file.exe> -r           # Resources only
petriage <file.exe> -c           # Authenticode / code signing info
petriage <file.exe> --json       # JSON output
petriage <file.exe> --json | jq '.suspicious_summary'              # Suspicious API summary
petriage <file.exe> --json | jq '.imports[].functions[] | select(.risk != null)'  # Risky APIs only
petriage <file.exe> --json | jq '.anomalies'                      # All anomalies
petriage <file.exe> --json | jq '.anomalies[] | select(.severity == "critical")'  # Critical anomalies only
petriage <file.exe> --json | jq '.resources'                                     # Resources
petriage <file.exe> --json | jq '.resources.version_info'                        # Version info
petriage <file.exe> --json | jq '.resources.manifest'                            # Manifest XML
petriage <file.exe> --json | jq '.authenticode'                                  # Authenticode info
petriage <file.exe> --json | jq '.authenticode.signer'                           # Signer certificate
petriage <file.exe> --json | jq '.rich_header'                                   # Rich Header info
petriage <file.exe> --json | jq '.rich_header.rich_hash'                         # Rich Hash (YARA/VT compatible)
petriage <file.exe> --ndjson       # Compact one-line JSON output
petriage --batch <dir> --ndjson   # Batch-analyze all PEs in a directory (NDJSON output)
petriage --batch <dir> --json     # Batch-analyze all PEs (JSON array output)
petriage <file.exe> --fail-on warning  # Exit code 3 if any warning+ anomaly found
petriage <file.exe> -o report.txt  # Write to file

TUI Hex Viewer (requires --features tui build)

petriage -x <file.exe>            # Interactive hex viewer (short form)
petriage --view <file.exe>        # Interactive hex viewer (long form)

The TUI provides:

  • Split-pane layout — Left pane lists PE regions (DOS Header, COFF, Optional Header, sections, overlay); right pane shows hex dump
  • Region navigation — Up/Down arrows to select regions; hex view updates instantly
  • Hex scrolling — j/k for line scroll, PgUp/PgDn for page scroll, Home/End for jump
  • Classic hex format — Offset | hex bytes | ASCII sidebar, 16 bytes per line
  • Alternate screen — Launches in alternate terminal screen; restores on exit (like git log)

GUI (requires --features gui build)

petriage-gui                     # Open with file dialog
petriage-gui <file.exe>          # Open file directly in GUI

The GUI provides:

  • Tabbed interface — File Info, Headers, Sections, Imports, Exports, Strings, Overlay, Resources, Rich, TLS, Debug, Signing, Editor
  • Drag & drop — Drop PE files onto the window to analyze
  • Left sidebar — Toggle analysis options and re-analyze without restarting
  • Import filter — Search API names across DLLs, "Suspicious only" toggle to surface risky APIs
  • String filter — Filter by text and encoding (ASCII / UTF-16)
  • Entropy color-coding — Section entropy highlighted green (<6) / yellow (6–7) / red (7–8)
  • Suspicious API indicators — Color-coded severity badges (red/yellow/cyan) on File Info and Imports tabs
  • Embedded icon display — Extracts and renders PE embedded icons (RT_GROUP_ICON / RT_ICON); primary icon shown on File Info tab, all icon groups on Resources tab. Useful for identifying malware impersonating legitimate software
  • OPSEC indicators — PDB path highlighted in orange on Debug tab and File Info tab with dedicated badge, surfacing developer environment leaks
  • PE Header Editor — Edit COFF header (TimeDateStamp, Characteristics), Optional header (AddressOfEntryPoint, ImageBase, DllCharacteristics flags, CheckSum, Subsystem, etc.), and Section headers (Name, VirtualSize, RawSize, Characteristics flags) with hex DragValue inputs and flag checkboxes. Modified fields highlighted. Save As writes patched PE to disk.
  • Hash copy buttons — One-click copy of MD5/SHA1/SHA256
  • Virtual scroll — Handles tens of thousands of strings without lag

Example output

=== File Info ===
  File:    sample.exe
  Size:    72704 bytes (71.00 KB)
  Type:    PE32 (32-bit)

=== OPSEC: PDB Path ===
  C:\Users\dev\source\repos\malware\x64\Release\payload.pdb

=== Hashes ===
  MD5:     a1b2c3d4e5f6...
  SHA1:    1234567890ab...
  SHA256:  abcdef012345...
  Imphash: 5a8e4dc5b6f7...

=== COFF Header ===
  Machine:              IMAGE_FILE_MACHINE_I386 (x86) (0x014c)
  NumberOfSections:     5
  TimeDateStamp:        0x65a1b2c3 (2024-01-12 15:30:27 UTC)
  Characteristics:      0x0102
                        - EXECUTABLE_IMAGE
                        - 32BIT_MACHINE

=== Sections (5) ===
  Name         VirtSize     VirtAddr    RawSize      RawAddr  Entropy Characteristics
  .text      0x00008a00 0x0000001000 0x00008c00 0x0000000400  6.4521 CODE | EXECUTE | READ
  .rdata     0x00002600 0x000000a000 0x00002800 0x0000009000  5.1032 INITIALIZED_DATA | READ
  ...

=== Imports (4 DLLs, 32 functions) ===
  KERNEL32.dll (18 functions)
    - CreateProcessW [HIGH] Code Execution
    - VirtualAllocEx [HIGH] Process Injection
    - WriteProcessMemory [HIGH] Process Injection
    - VirtualProtect [HIGH] Evasion
    - GetComputerNameA [MED] Info Gathering
    - CreateFileA [LOW] File / Registry
    - ReadFile
    - CloseHandle [LOW] Anti-Debug
    ...

=== Suspicious API Summary ===
  Total suspicious APIs: 14
  HIGH: 6 MEDIUM: 5 LOW: 3

  Category                 Count
  ------------------------ -----
  Process Injection            3
  Code Execution               2
  Network                      2
  ...

=== Anomaly Detection ===
  CRITICAL: 2 WARNING: 5 INFO: 4

  [CRITICAL] Code Integrity: Section '.xpack' is both writable and executable (W^X violation)
  [CRITICAL] Suspicious Combo: Process Injection + Evasion APIs both present — possible code injection technique
  [WARNING] Packing: Executable section '.text' has high entropy (6.8921)
  [WARNING] Security: ASLR (DYNAMIC_BASE) is disabled
  [WARNING] Security: DEP (NX_COMPAT) is disabled
  [WARNING] Timestamp: Timestamp (1998-03-15 00:00:00 UTC) is before year 2000 — possible forgery
  [WARNING] Structure: Overlay data detected (4096 bytes at offset 0x12000)
  [INFO] [OPSEC-001] OPSEC: PDB debug path found: C:\Users\dev\source\repos\malware\x64\Release\payload.pdb
  [INFO] Security: Control Flow Guard (GUARD_CF) is not enabled
  [INFO] Structure: Non-standard section name '.xpack'
  [INFO] [RICH-002] Rich Header: No Rich Header found — PE may not have been built with MSVC toolchain
  ...

=== Rich Header ===
  XOR Key:    0xaabbccdd
  Rich Hash:  a1b2c3d4e5f67890abcdef1234567890
  Checksum:   Valid

  CompID         ProdID  BuildID    Count  Description
  ------------ ------  -------  -------  ------------------------------
  0x01070042      263       66        7  [C++] VS 2005 (build 66)
  0x010a71b3      266    29107        1  [LNK] VS 2019 16.7 (build 29110)
  ...

=== Resources (12 entries) ===
  Version Info:
    FileVersion:    10.0.19041.1
    ProductVersion: 10.0.19041.1
    FileType:       Application (1)
    FileOS:         0x40004
    FileFlags:      0x0
    String Info:
      CompanyName:             Microsoft Corporation
      FileDescription:         Windows Notepad
      OriginalFilename:        NOTEPAD.EXE

  Manifest:
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
      <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
        <security>
          <requestedPrivileges>
            <requestedExecutionLevel level="asInvoker" uiAccess="false"/>
          </requestedPrivileges>
        </security>
      </trustInfo>
    </assembly>

  Type                 Name             Language       Size          RVA
  -------------------- ---------------- ---------- -------- ------------
  RT_ICON              #1               en-US          1128 0x00003a000
  RT_VERSION           #1               en-US           836 0x00003c000
  RT_MANIFEST          #1               en-US           522 0x00003d000
  ...

=== Authenticode / Code Signing ===
  Signed:          Yes
  Parse OK:        Yes
  Trust Verified:  No (not implemented)

  WIN_CERTIFICATE:
    Length:   9640 bytes
    Revision: WIN_CERT_REVISION_2_0 (0x0200)
    Type:     WIN_CERT_TYPE_PKCS_SIGNED_DATA (0x0002)

  Signer:
    Subject:    Microsoft Corporation
    Issuer:     Microsoft Code Signing PCA 2011
    Serial:     33:00:00:01:c4:22:b2:f7:9b:18:54:...
    Not Before: 2023-05-18 18:09:06 UTC
    Not After:  2024-05-16 18:09:06 UTC
    Thumbprint: a1:b2:c3:d4:e5:f6:...

  Certificate Chain (3 certificates):
    [0] (signer)
      Subject:    Microsoft Corporation
      ...
    [1]
      Subject:    Microsoft Code Signing PCA 2011
      ...
    [2]
      Subject:    Microsoft Root Certificate Authority 2011
      ...

Exit Codes

Code Meaning
0 Success
1 Input error (file not found, read failure, invalid PE)
2 Output error (file write failure)
3 Anomaly threshold exceeded (--fail-on)

When --json or --ndjson is used, errors are output to stderr as JSON: {"error": "message"}.

Known Limitations

  • Forwarded exports: Not detected; only name/ordinal/RVA are displayed.
  • Export ordinals: Computed as ordinal_base + address_table_index. goblin does not expose per-export ordinal fields, so PEs with non-contiguous ordinal assignments may show approximated values.
  • Import by ordinal: Deferred to goblin's output; ordinal-only imports may show as empty names.
  • String extraction: Capped at 100,000 strings to prevent excessive memory usage on large files.
  • Malformed PEs: Arithmetic operations on PE header fields use checked arithmetic to avoid panics on crafted inputs. goblin may silently accept structurally invalid files without error. Fuzz testing with adversarial PEs is ongoing.
  • Authenticode trust verification: Signature parsing and certificate extraction are supported, but trust verification (chain validation against a root store) is not performed. trust_verified is always false.
  • Authenticode dual-signing: Only the first WIN_CERTIFICATE entry and first SignerInfo are processed. Dual-signed PEs (e.g., SHA-1 + SHA-256) will only show one signature.
  • PE Header Editor: The Editor tab validates optional header size before displaying fields. Malformed PEs with truncated optional headers will show an error message instead of editable fields. Out-of-bounds edits are silently skipped during save.
  • Load Config directory: Not yet implemented.
  • RVA-to-offset conversion: Validated with overflow checks and file boundary verification; however, PEs with unusual section layouts may produce incorrect mappings.

Roadmap

  • v0.2: Load Config directory, packer detection
  • v0.3: .NET metadata, entropy histogram
  • Future: ELF format support

License

MIT