Skip to content

sebafvs/carcass

Repository files navigation


  ▄████▄   ▄▄▄       ██▀███   ▄████▄   ▄▄▄        ██████   ██████ 
 ▒██▀ ▀█  ▒████▄    ▓██ ▒ ██▒▒██▀ ▀█  ▒████▄    ▒██    ▒ ▒██    ▒ 
 ▒▓█    ▄ ▒██  ▀█▄  ▓██ ░▄█ ▒▒▓█    ▄ ▒██  ▀█▄  ░ ▓██▄   ░ ▓██▄   
 ▒▓▓▄ ▄██▒░██▄▄▄▄██ ▒██▀▀█▄  ▒▓▓▄ ▄██▒░██▄▄▄▄██   ▒   ██▒  ▒   ██▒
 ▒ ▓███▀ ░ ▓█   ▓██▒░██▓ ▒██▒▒ ▓███▀ ░ ▓█   ▓██▒▒██████▒▒▒██████▒▒
 ░ ░▒ ▒  ░ ▒▒   ▓▒█░░ ▒▓ ░▒▓░░ ░▒ ▒  ░ ▒▒   ▓▒█░▒ ▒▓▒ ▒ ░▒ ▒▓▒ ▒ ░
   ░  ▒     ▒   ▒▒ ░  ░▒ ░ ▒░  ░  ▒     ▒   ▒▒ ░░ ░▒  ░ ░░ ░▒  ░ ░
 ░          ░   ▒     ░░   ░ ░          ░   ▒   ░  ░  ░  ░  ░  ░  
 ░ ░            ░  ░   ░     ░ ░            ░  ░      ░        ░  
 ░                           ░                                    

 v1.0.0

A Windows CLI tool for static analysis of PE (Portable Executable) files. Carcass parses and exposes PE internals — headers, imports, exports, and sections — without executing the binary. Built for red teamers, malware analysts, and reverse engineers who want a fast, dependency-free tool they can drop on any Windows box.


Table of Contents


Overview

Carcass reads a PE file from disk into memory and parses it entirely statically — no execution, no injection, no runtime dependencies beyond the Windows SDK. It is structured as independent modules, each targeting a specific part of the PE format:

Module What it parses
headers DOS header, NT headers, File header, Optional header
imports Import Address Table (IAT) — DLLs and function names
exports Export Address Table (EAT) — named, ordinal-only, and forwarded exports
sections Section table — virtual / raw sizes, permissions, Shannon entropy

All output goes to stdout by default. The imports and exports modules support JSON output via -o.


Use Cases

Red team / pre-engagement recon

  • Identify what APIs a target binary imports to understand its capabilities before execution
  • Spot process injection primitives (VirtualAlloc, WriteProcessMemory, CreateRemoteThread), credential access APIs (LsaOpenPolicy, SamConnect), or network indicators
  • Check if a DLL exposes functions you can hijack or proxy

Malware analysis / triage

  • Get a fast read on an unknown binary before detonating it in a sandbox
  • Identify packing or obfuscation via section entropy
  • Find forwarded exports that redirect to other DLLs, a common technique in malware loaders
  • Dump imports to JSON and feed them into a pipeline or grep across samples

Reverse engineering

  • Confirm entry point, image base, and architecture before opening in a disassembler
  • Enumerate exports of a DLL you want to call or hook
  • Verify section layout matches what your disassembler shows

Building

Carcass targets Windows and requires the Windows SDK for PE struct definitions (windows.h). It has no other external dependencies.

MSVC (recommended)

cl main.c parser.c imports.c exports.c sections.c /Fe:carcass.exe /link /out:carcass.exe

MinGW / GCC on Windows

gcc main.c parser.c imports.c exports.c sections.c -o carcass.exe -lm

-lm is required for sections.c which uses log() for entropy calculation.


Modules

headers

Parses the PE header chain and prints key fields from each layer.

What it reads:

  • DOS Headere_magic (must be MZ / 0x5A4D) and e_lfanew (offset to NT headers)
  • NT Headers — the PE\0\0 signature that confirms this is a valid PE
  • File Header — target architecture (x86 / x64), section count, compile timestamp, and characteristics flags
  • Optional Header — entry point RVA, image base, section/file alignment, image size, and subsystem type (GUI vs console)

Why it matters for recon: The compile timestamp can indicate when the binary was built (though it can be faked). The image base tells you where it expects to be loaded. The entry point RVA is where execution starts. Subsystem tells you if it will spawn a visible window.


imports

Walks the Import Address Table and prints every DLL the binary depends on, along with each imported function name or ordinal.

What it reads:

  • Each IMAGE_IMPORT_DESCRIPTOR entry (one per DLL)
  • For each DLL: the Original First Thunk (falls back to First Thunk if OFT is null, common in packed/bound binaries)
  • Each IMAGE_IMPORT_BY_NAME entry for named imports, or raw ordinal values for ordinal-only imports

Flags:

  • --clean — strips api-ms-win-* and ext-ms-* API set forwarder DLLs from the output. These are Windows internal abstraction layers that add noise when you're looking for meaningful capability indicators
  • -all — explicit show-everything mode, overrides --clean if previously set
  • -o <file.json> — writes output as JSON instead of stdout

Why it matters for recon: The import table is one of the highest-signal parts of a PE for triage. A binary importing VirtualAllocEx + WriteProcessMemory + CreateRemoteThread is almost certainly doing process injection. CryptEncrypt or BCryptEncrypt alongside FindFirstFile suggests ransomware-like behavior. WNetAddConnection or InternetOpenUrl reveals network capability.


exports

Walks the Export Address Table and prints every exported function, covering three cases the original PE format supports:

  • Named exports — functions exported by name and ordinal
  • Ordinal-only exports — functions exported purely by ordinal with no name (shown as [unnamed / ordinal-only])
  • Forwarded exports — exports whose RVA points back into the export directory itself, redirecting callers to a function in another DLL (shown as Forwarded to: DLL.FunctionName)

What it reads:

  • IMAGE_EXPORT_DIRECTORY for DLL name, function count, and named export count
  • The three parallel arrays: function RVAs, name RVAs, and name-ordinal mappings
  • Builds a reverse map from ordinal index to name, then walks all function slots to catch ordinal-only entries the original code missed

Flag:

  • -o <file.json> — writes output as JSON

Why it matters for recon: When targeting a DLL for hijacking or proxying, you need the full export list including ordinal-only entries — otherwise your proxy DLL will be missing exports and the loader will fail. Forwarded exports are also worth noting: they tell you the actual implementation lives elsewhere.


sections

Enumerates the section table and computes per-section Shannon entropy from the raw bytes on disk.

What it reads:

  • Each IMAGE_SECTION_HEADER entry
  • Virtual size, virtual address, raw size, raw offset, and characteristics flags
  • Reads raw section bytes from the file buffer and computes Shannon entropy (0.0–8.0 scale)
  • Decodes the R, W, X memory permission bits from the characteristics field

Entropy scale:

Range Interpretation
0.0 – 1.0 Near-empty or highly repetitive (e.g. zero-filled BSS)
4.0 – 6.5 Normal compiled code or data
7.0 – 7.2 Compressed resources, dense data tables
7.2 – 8.0 Strong indicator of encryption or packing

Why it matters for recon: High entropy in a .text section or a strangely named section is a strong indicator the binary is packed or the code is encrypted. A section with both W and X permissions (RWX or -WX) is a classic shellcode staging area or a sign of self-modifying code.


Arguments & Flags

carcass <module> <target> [flags]
Argument Description
module One of: headers, imports, exports, sections
target Path to the PE file (.exe, .dll, .sys, etc.)
Flag Module Description
--clean imports Filter out api-ms-win-* and ext-ms-* forwarder DLLs
-all imports Show all DLLs including forwarder entries
-o <file.json> imports, exports Write output to a JSON file instead of stdout

--clean and -all are mutually exclusive. Passing both will produce an error.


Usage Examples

# Parse PE headers of a binary
carcass headers malware.exe

# List all imports
carcass imports malware.exe

# List imports, filter out Windows API set noise
carcass imports malware.exe --clean

# Dump all imports to JSON for further processing
carcass imports malware.exe -o imports.json

# Dump cleaned imports to JSON
carcass imports malware.exe --clean -o imports.json

# List all exports of a DLL
carcass exports target.dll

# Dump exports to JSON
carcass exports target.dll -o exports.json

# Enumerate sections with entropy and permissions
carcass sections malware.exe

Output Examples

headers

[+] DOS Header
    e_magic: 0x5A4D
    e_lfanew: 0xE8

[+] NT Headers
    Signature: 0x4550

[+] File Header
    Machine: 0x8664 (x64)
    NumberOfSections: 6
    TimeDateStamp: 0x6324A192
    Characteristics: 0x22

[+] Optional Header
    AddressOfEntryPoint: 0x1430
    ImageBase: 0x0000000140000000
    SectionAlignment: 0x1000
    FileAlignment: 0x200
    SizeOfImage: 0x14000
    Subsystem: 3 (Console)

imports

[+] Imports
    KERNEL32.DLL
        VirtualAlloc
        VirtualFree
        CreateThread
        GetProcAddress

    ntdll.dll
        NtAllocateVirtualMemory
        NtWriteVirtualMemory

exports

[+] Exports
    DLL Name:          example.dll
    NumberOfFunctions: 4
    NumberOfNames:     3

    ExportedFunction
        Ordinal: 1
        RVA: 0x00001020

    [unnamed / ordinal-only]
        Ordinal: 2
        RVA: 0x00001080

    ForwardedFunc
        Ordinal: 3
        Forwarded to: NTDLL.RtlAllocateHeap

sections

[+] Sections
    Count: 5

    [1] .text
        VirtualSize:      0x6A30
        VirtualAddress:   0x1000
        SizeOfRawData:    0x6C00
        PointerToRawData: 0x400
        Characteristics:  0x60000020
        Entropy:          6.1042
        Permissions:      R-X

    [2] .data
        VirtualSize:      0x310
        VirtualAddress:   0x8000
        SizeOfRawData:    0x400
        PointerToRawData: 0x7000
        Characteristics:  0xC0000040
        Entropy:          2.4817
        Permissions:      RW-

    [3] .packed
        VirtualSize:      0xF200
        VirtualAddress:   0x9000
        SizeOfRawData:    0xF200
        PointerToRawData: 0x7400
        Characteristics:  0xE0000020
        Entropy:          7.9341
        Permissions:      RWX

About

Static PE analysis tool for red teamers. Parses headers, imports, exports, and sections.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages