# ELFGuard — Rust executable hardening inspection

I built ELFGuard as an **offline, dependency-free Rust security inspector**. It never executes its input and makes no network requests. It reads ELF64 little-endian program headers and dynamic tags, identifies PIE evidence, executable stacks, writable-and-executable load segments, RELRO and eager dynamic binding.

## Run

```sh
cargo test --offline
cargo clippy --all-targets -- -D warnings
cargo run --release -- /path/to/owned-or-authorized/elf
```

### Attack surfaces and what the evidence means

- Writable + executable PT_LOAD segments can undermine W^X; the tool identifies suspicious memory mapping flags rather than claiming a working exploit.
- Executable PT_GNU_STACK can make code injection easier depending on other runtime controls. If absent, the report shows **unknown** rather than silently claiming NX is present.
- Full RELRO depends on both PT_GNU_RELRO and eager binding (DT_BIND_NOW, DF_BIND_NOW or DF_1_NOW). Merely finding a RELRO header is insufficient.
- ET_DYN plus PT_INTERP is treated as PIE evidence. Standalone shared objects and unusual loaders are reported as **unknown**, rather than simply called PIE.

### Constraints

Supports **ELF64 little-endian** only, including common Linux x86-64 and AArch64 binaries. It does not resolve symbolic debug information, verify a stack canary, report CET/BTI/PAC coverage, disassemble instructions, check signatures, or prove ASLR was enabled by the host. Extended program header counts are refused. Files over 64 MiB are refused by the CLI. Program headers and referenced file segments are range-checked, and malformed inputs are rejected.

Test fixtures include full/partial RELRO, non-PIE, suspicious RWX load segments, executable stack, ambiguous evidence, truncation and overflow. A deterministic 10,000-case mutation regression checks that malformed input does not panic; this is not a coverage-guided fuzzing campaign. This is an implementable building block for local reverse-engineering and defensive binary review—not a substitute for a full binary-analysis pipeline.
