capa 0.4.2

File capability extractor.
Documentation
[package]
name = "capa"
version = "0.4.2"
description = "File capability extractor."
authors = ["Marirs <marirs@gmail.com>", "Andrey Mnatsakanov <andrey@3ig.kiev.ua>", "Jorge Alejandro Durán Royo<jorge.duran.royo@gmail.com>"]
keywords = ["capa", "fce", "capability", "aslr", "reverse"]
readme = "README.md"
license-file = "LICENSE"
repository = "https://github.com/marirs/capa-rs"
homepage = "https://github.com/marirs/capa-rs"
# Drop `examples` from `exclude` so the [[example]] target below ships
# with the crate (was inconsistent: example target referenced an
# excluded path). `data/` stays excluded — those are test fixtures.
exclude = ["data"]
edition = "2024"
# 0.3.21: bumped from 1.85 → 1.95 because smda 0.5.x sets MSRV 1.95
# (needed for some 2024-edition features it leans on). Pure-Rust dep
# tree below — no aws-lc / openssl / native-tls.
rust-version = "1.95"

[dependencies]
hex = "0.4.3"
itertools = "0.14.0"
pdb = "0.8.0"
petgraph = "0.8"
regex = "1.11.1"
fancy-regex = "0.18"
serde = { version = "1", features = ["derive"] }
# 0.3.21: smda 0.2 → 0.5 picks up months of security fixes + the new
# function-name pipeline (Go pclntab, MinGW DWARF, Delphi VMT, Rust
# demangling), structural function hashes, and Mach-O loader.
smda = "0.5"
thiserror = "2.0.12"
walkdir = "2.5.0"
yaml-rust = "0.4.5"
goblin = { version = "0.10.0", features = ["alloc"] }
maplit = "1.0.2"
# 0.4.2: dnfile 0.4 → 0.5 picks up `Send + Sync` supertrait bounds on
# the public trait family (MDTableTrait, MDTableRowTrait,
# MDTableRowTraitT, CodedIndex) so `DnPe<'_>` — and the capa-rs
# `dnfile::Extractor<'_>` that wraps it — can cross thread
# boundaries. Required by the rayon-parallel function loop in
# `find_capabilities`. No runtime behaviour change.
dnfile = "0.5"
lazy_static = "1.5.0"
parking_lot = "0.12.3"
serde_json = "1.0.140"
memoffset = "0.9.1"
memmap2 = "0.9.5"
scroll = "0.13"
once_cell = "1.21.1"
dynamic-loader-cache = "0.2.2"
# 0.3.21 introduced ouroboros as a self-referential wrapper around
# `buf: Vec<u8>` + `DisassemblyReport<'_>` so the public Extractor::new
# could keep its 0.3.20 signature. 0.4.0 completes the zero-copy
# refactor — `Extractor<'a>` takes `&'a [u8]` from the caller and
# borrows the smda/dnfile reports directly. The ouroboros dep is gone.
# 0.3.21: iced-x86 is already in the transitive dep tree via smda.
# Pulling it in directly lets the smda extractor compare instructions
# against typed `Mnemonic` / `FlowControl` enums instead of re-formatting
# strings — the same hot-path perf win smda itself got from the iced
# decoder swap. Match the feature set smda uses to keep monomorphisation
# overhead identical.
iced-x86 = { version = "1", default-features = false, features = ["std", "decoder", "intel", "instr_info"] }
# 0.4.2: rayon for inter-function parallelism in `find_capabilities`.
# Each function's analysis is pure — reads the extractor, evaluates
# rules, returns matches. Parallelising the outer loop gives ~4-8×
# end-to-end speedup on multi-core machines for binaries with more
# than a handful of functions. Also used in `rules::get_rules` to
# parallelise YAML parsing across the rule corpus.
rayon = "1.10"

[dev-dependencies]
clap = { version = "4.5", features = ["cargo", "derive"] }

prettytable-rs = "0.10.0"

[lib]
name = "capa"
path = "src/lib.rs"

[features]
default = ["properties"]
verbose = []
properties = []

[[example]]
name = "capa_cli"
path = "examples/capa_cli.rs"
required-features = ["properties"]

[profile.dev]
opt-level = 3

[profile.release]
codegen-units = 1
debug-assertions = false
debug = false
opt-level = 3
lto = true