Sign in

    moon-pe-inspect

    Safe PE/COFF inspection, import/export extraction, and security metadata auditing for MoonBit.

    pe
    coff
    binary-analysis
    security
    windows
    Download zip
    Author
    Version
    0.1.0
    License
    Apache-2.0
    Last updated
    2 days ago
    Downloads
    15

    #moon-pe-inspect

    A pure MoonBit PE/COFF inspector for build artifacts and security metadata.

    moon-pe-inspect parses Windows PE files without loading or executing them. It extracts PE32/PE32+ headers, sections, imports, exports, and hardening-related metadata, then reports structural and security diagnostics. The core is a bounds-checked MoonBit library; the CLI adds text and JSON output for CI and analysis workflows.

    #Why this project

    PE files are produced by Windows build pipelines, shipped as DLLs and EXEs, and examined during vulnerability triage. Existing generic binary readers stop at byte access. This project owns the domain logic:

    • validate DOS, PE, COFF, and optional-header structures;
    • map RVAs to section file offsets;
    • walk import descriptors and thunk tables;
    • resolve export names, ordinals, and forwarders;
    • detect missing hardening flags and writable-executable sections;
    • return bounded errors instead of panicking on malformed input.

    #Features

    • PE32 and PE32+ support.
    • Machine, subsystem, image base, entry point, checksum, and image-size metadata.
    • Section table parsing with virtual/file ranges and characteristics.
    • Imported DLL and function extraction, including ordinal imports.
    • Export extraction with ordinal and forwarder resolution.
    • Security diagnostics for ASLR, NX, CFG, high-entropy VA, RWX sections, executable entry points, and certificate-table presence.
    • CLI commands with human-readable and JSON output.
    • Reproducible synthetic PE fixtures for tests and demonstrations.

    #Quick start

    Install from mooncakes.io:

    moon add 404-32/moon-pe-inspect@0.1.0

    Package page: https://mooncakes.io/docs/404-32/moon-pe-inspect/0.1.0

    Build and test from source:

    git clone https://github.com/404-32/byc001.git cd byc001 moon test --target wasm

    Inspect the included PE32 fixture:

    moon run cmd/main -- inspect examples/minimal-pe32.exe

    List imports and exports:

    moon run cmd/main -- imports examples/minimal-pe32.exe moon run cmd/main -- exports examples/minimal-pe32.exe

    Produce JSON for CI:

    moon run cmd/main -- inspect examples/minimal-pe32plus.exe --json moon run cmd/main -- security examples/minimal-pe32plus.exe --json

    Inspect a real Windows binary:

    moon run cmd/main -- sections C:\Windows\System32\notepad.exe

    #Library API

    ///|
    let image = @pe.PEImage::parse(file_bytes)

    ///|
    let sections = image.sections

    ///|
    let imports = image.imports()

    ///|
    let exports = image.exports()

    ///|
    let diagnostics = image.security_diagnostics()

    ///|
    let offset = image.rva_to_offset(0x1000UL)

    Parsing is read-only. All binary reads are checked against the available byte range, and malformed files produce a PeError containing a file offset and message.

    #Security checks

    • pe.no-aslr: DYNAMIC_BASE is missing.
    • pe.no-nx: NX_COMPAT is missing.
    • pe.no-cfg: GUARD_CF is missing.
    • pe.no-high-entropy-va: 64-bit image lacks high-entropy VA.
    • pe.rwx-section: a section is writable and executable.
    • pe.entrypoint-not-executable: entry point is outside executable sections.
    • pe.unsigned: no certificate table is present.
    • pe.certificate-table: certificate data exists, but the tool does not verify it.

    The last distinction is intentional: detecting an Authenticode certificate table is not the same as validating a signature.

    #Scope

    This project inspects static PE metadata. It does not load or execute images, perform disassembly, unpack compressed binaries, validate certificate chains, or parse every Windows-specific data directory. New formats and checks can be added without changing the safe binary-reader foundation.

    #Development

    python scripts/generate_fixtures.py moon check --target wasm --deny-warn moon test --target wasm --deny-warn moon fmt --check moon run cmd/main -- inspect examples/minimal-pe32.exe

    License: Apache-2.0.

    PeError

    pub(all) suberror PeError {
    PeError(Int, String)
    }

    DataDirectory

    pub(all) struct DataDirectory {
    index : Int
    name : String
    virtual_address : UInt64
    size : Int
    }

    Diagnostic

    pub(all) struct Diagnostic {
    severity : Severity
    code : String
    message : String
    }

    ExportSymbol

    pub(all) struct ExportSymbol {
    name : String
    ordinal : Int
    rva : UInt64
    forwarder : String?
    }

    ImportLibrary

    pub(all) struct ImportLibrary {
    name : String
    symbols : Array[ImportSymbol]
    }

    ImportSymbol

    pub(all) struct ImportSymbol {
    name : String?
    ordinal : Int?
    hint : Int?
    }

    PEFormat

    pub(all) enum PEFormat {
    PE32
    PE32Plus
    }

    PEImage

    pub(all) struct PEImage {
    data : Bytes
    pe_offset : Int
    format : PEFormat
    machine : Int
    number_of_sections : Int
    timestamp : UInt64
    symbol_table_pointer : UInt64
    number_of_symbols : UInt64
    size_of_optional_header : Int
    characteristics : Int
    entry_point : UInt64
    image_base : UInt64
    section_alignment : Int
    file_alignment : Int
    size_of_image : Int
    size_of_headers : Int
    checksum : UInt64
    subsystem : Int
    dll_characteristics : Int
    sections : Array[Section]
    directories : Array[DataDirectory]
    }

    PEImage::directory

    fn PEImage::directory(self : PEImage, index : Int) -> DataDirectory?

    PEImage::exports

    fn PEImage::exports(self : PEImage) -> Array[ExportSymbol] raise PeError

    PEImage::imports

    fn PEImage::imports(self : PEImage) -> Array[ImportLibrary] raise PeError

    PEImage::is_64_bit

    fn PEImage::is_64_bit(self : PEImage) -> Bool

    PEImage::parse

    fn PEImage::parse(data : Bytes) -> PEImage raise PeError

    PEImage::read_c_string

    fn PEImage::read_c_string(self : PEImage, rva : UInt64, max_length : Int) -> String raise PeError

    PEImage::rva_to_offset

    fn PEImage::rva_to_offset(self : PEImage, rva : UInt64) -> Int raise PeError

    PEImage::section_by_name

    fn PEImage::section_by_name(self : PEImage, name : String) -> Section?

    PEImage::security_diagnostics

    fn PEImage::security_diagnostics(self : PEImage) -> Array[Diagnostic]

    Section

    pub(all) struct Section {
    name : String
    virtual_size : Int
    virtual_address : UInt64
    raw_size : Int
    raw_offset : Int
    characteristics : UInt64
    }

    Severity

    pub(all) enum Severity {
    Info
    Warning
    Critical
    }

    architecture_name

    fn architecture_name(machine : Int) -> String

    subsystem_name

    fn subsystem_name(subsystem : Int) -> String

    Powered by MoonBit

    Site sourceReport issuePackagesBuild queueSkillsStatistics

    © 2026 mooncakes.io