<div align="center">
# π BinSleuth
**A fast, zero-dependency CLI tool for static binary security analysis.**
Inspect ELF & PE binaries for hardening flags and detect packed/encrypted sections β in milliseconds.

[](https://crates.io/crates/binsleuth)
[](https://crates.io/crates/binsleuth)
[](https://docs.rs/binsleuth)
[](https://github.com/long-910/BinSleuth/actions/workflows/ci.yml)
[](https://github.com/long-910/BinSleuth/actions/workflows/release.yml)
[](LICENSE)
[](https://www.rust-lang.org)
[](#)
[](https://github.com/sponsors/long-910)
[](https://ko-fi.com/long910)
**Language / θ¨θͺ / θ―θ¨:**
[English](README.md) Β· [ζ₯ζ¬θͺ](README.ja.md) Β· [δΈζ](README.zh.md)
</div>
---
## What is BinSleuth?
BinSleuth is a **security-focused static binary analyzer** written in Rust.
It acts as a quick health-check for compiled executables β answering:
- *"Does this binary have modern security protections enabled?"*
- *"Could this section be packed or encrypted malware?"*
- *"Does this binary import dangerous OS-level functions?"*
It is designed for **security engineers, malware researchers, and developers** who need instant answers without launching a full reverse-engineering suite.
---
## Features
### 1. Security Hardening Checks
| **NX** | Non-executable stack/data β prevents code injection | `PT_GNU_STACK` | `NX_COMPAT` |
| **PIE** | Position-Independent Executable β enables ASLR | `ET_DYN` | `DYNAMIC_BASE` |
| **RELRO** | Read-Only Relocations β prevents GOT overwrite | `PT_GNU_RELRO` + `BIND_NOW` | N/A |
| **Stack Canary** | Buffer-overflow tripwire symbol present | `__stack_chk_fail` | `__security_cookie` |
| **FORTIFY_SOURCE** | Fortified libc wrappers (`__*_chk`) β compile-time bounds checks on unsafe string/memory calls | `__memcpy_chk`, β¦ | `__memcpy_chk`, β¦ |
| **No RPATH/RUNPATH** | Absence of embedded library search paths β prevents library-injection via writable/relative RPATH | `DT_RPATH` / `DT_RUNPATH` | N/A |
| **Stripped** | Debug symbols / DWARF info absent β limits reverse-engineering | `.debug_*` sections | Debug directory |
Each check reports one of: **Enabled** / **Partial** / **Disabled** / **N/A**
### 2. Section Entropy Analysis
BinSleuth computes the [Shannon entropy](https://en.wikipedia.org/wiki/Entropy_(information_theory)) of every section:
```
H = -Ξ£ P(x) Β· logβ(P(x)) range: [0.0 β 8.0]
```
| 0.0 β 4.0 | Normal code / data |
| 4.0 β 7.0 | Compressed resources (normal) |
| **> 7.0** | **β Packed / Encrypted β investigate** |
### 3. Dangerous Symbol Detection
BinSleuth flags symbols that commonly appear in malicious or insecure binaries, and reports each one with a **category**:
| **Code execution** | `exec` | `system`, `execve`, `popen`, `WinExec`, `CreateProcess` |
| **Network** | `net` | `connect`, `socket`, `gethostbyname`, `WinHttpOpen` |
| **Memory manipulation** | `mem` | `mprotect`, `mmap`, `VirtualAlloc`, `VirtualProtect` |
### 4. Security Score
Every report includes a numeric **security score from 0 to 100**, computed from the weighted hardening results:
| NX | 20 |
| PIE | 20 |
| RELRO (Full) | 15 Β· Partial: 7 Β· N/A: 15 |
| Stack Canary | 15 |
| FORTIFY_SOURCE | 10 |
| No RPATH/RUNPATH | 10 |
| Stripped | 5 |
| No dangerous symbols | 5 (β1 per symbol) |
---
## Installation
### From crates.io (recommended)
```bash
cargo install binsleuth
```
### From source
```bash
git clone https://github.com/long-910/BinSleuth.git
cd BinSleuth
cargo build --release
# Binary output: ./target/release/binsleuth
```
### Requirements
- Rust **1.85** or later
- No system libraries required β pure Rust
---
## Usage
```
binsleuth [OPTIONS] <FILE>
Arguments:
<FILE> Path to the ELF or PE binary to analyze
Options:
-v, --verbose Show all sections, even those with normal entropy
--json Output results as JSON instead of the colored terminal report
--strict Exit with code 2 if any hardening protection is missing or
dangerous symbols are found (useful in CI pipelines)
-h, --help Print help
-V, --version Print version
```
### Basic analysis
```bash
binsleuth /usr/bin/ls
binsleuth ./myapp.exe
binsleuth ./suspicious_binary
```
### Show all sections (including low-entropy ones)
```bash
binsleuth --verbose /usr/bin/python3
```
### JSON output (for scripting / CI integration)
```bash
### CI pipeline β fail if hardening issues are found
```bash
```
### Example output β hardened binary
```
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β BinSleuth β Binary Analyzer β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
File: /usr/bin/ls
Format: ELF
Arch: X86_64
ββ Security Hardening ββββββββββββββββββββββββββββββββββ
[ ENABLED ] NX (Non-Executable Stack)
[ ENABLED ] PIE (ASLR-compatible)
[ ENABLED ] RELRO (Read-Only Relocations)
[ ENABLED ] Stack Canary
[ ENABLED ] FORTIFY_SOURCE
[ ENABLED ] No RPATH/RUNPATH
[ ENABLED ] Debug Symbols Stripped
ββ Section Entropy βββββββββββββββββββββββββββββββββββββ
Section Size (B) Entropy Status
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
All sections within normal entropy range.
(run with --verbose to show all sections)
ββ Dangerous Symbol Usage ββββββββββββββββββββββββββββββ
No dangerous symbols detected.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Analysis complete.
```
### Example output β suspicious / packed binary
```
ββ Section Entropy βββββββββββββββββββββββββββββββββββββ
Section Size (B) Entropy Status
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
UPX0 491520 7.9981 β Packed/Encrypted suspected
UPX1 32768 7.9912 β Packed/Encrypted suspected
2 section(s) with entropy > 7.0 detected!
ββ Dangerous Symbol Usage ββββββββββββββββββββββββββββββ
3 dangerous symbol(s) found:
βΆ execve [exec]
βΆ mprotect [mem]
βΆ socket [net]
```
---
## Library Usage
`binsleuth` can be used as a Rust library crate in addition to the CLI β for example as the core analysis engine of a VS Code extension.
Add to your `Cargo.toml`:
```toml
[dependencies]
binsleuth = "0.4"
```
### Unified API (recommended)
```rust
// Single call β returns hardening, sections, and security score together
let data = std::fs::read("path/to/binary")?;
let report = binsleuth::analyze(&data)?;
println!("Score: {}/100", report.security_score);
println!("PIE: {:?}", report.hardening.pie);
for sec in &report.sections {
println!("{}: va={:#x} entropy={:.4} rwx={}{}{}",
sec.name, sec.virtual_address, sec.entropy,
if sec.permissions.read { 'r' } else { '-' },
if sec.permissions.write { 'w' } else { '-' },
if sec.permissions.execute { 'x' } else { '-' },
);
}
for sym in &report.hardening.dangerous_symbols {
println!(" {:?} {}", sym.category, sym.name);
}
// Serialize to JSON string (no stdout side-effect)
let json: String = report.to_json_pretty();
```
### Lower-level API
```rust
use binsleuth::analyzer::hardening::HardeningInfo;
use binsleuth::analyzer::entropy::SectionEntropy;
let hardening = HardeningInfo::analyze(&data)?;
let sections = SectionEntropy::analyze(&data)?;
```
See the [API documentation on docs.rs](https://docs.rs/binsleuth) and [`examples/basic.rs`](examples/basic.rs) for a complete runnable example.
---
## Project Structure
```
BinSleuth/
βββ Cargo.toml
βββ README.md β English (default)
βββ README.ja.md β Japanese
βββ README.zh.md β Chinese (Simplified)
βββ CHANGELOG.md
βββ LICENSE
βββ examples/
β βββ basic.rs # Library usage example
βββ src/
βββ lib.rs # Library crate root (public API)
βββ main.rs # CLI entry point (clap)
βββ analyzer/
β βββ mod.rs
β βββ entropy.rs # Shannon entropy + SectionEntropy
β βββ hardening.rs # NX / PIE / RELRO / Canary / symbols
βββ report/
βββ mod.rs
βββ terminal.rs # Colored terminal renderer
βββ json.rs # JSON output serializer
```
### Key types
| `AnalysisReport` | `analyzer/mod.rs` | Unified result: hardening + sections + security score |
| `HardeningInfo` | `analyzer/hardening.rs` | Aggregated hardening check results |
| `CheckResult` | `analyzer/hardening.rs` | `Enabled` / `Partial(msg)` / `Disabled` / `N/A` |
| `DangerousSymbol` | `analyzer/hardening.rs` | Symbol name + `SymbolCategory` (Exec / Net / Mem) |
| `SectionEntropy` | `analyzer/entropy.rs` | Section name, virtual address, file offset, size, entropy, permissions |
| `SectionPermissions` | `analyzer/entropy.rs` | `read`, `write`, `execute` bool flags |
| `TerminalReporter` | `report/terminal.rs` | Colored terminal output renderer |
---
## Supported Formats
| ELF 32-bit | x86, ARM, MIPS, β¦ | β
| β
| β
| β
| β
| β
|
| ELF 64-bit | x86-64, AArch64, β¦ | β
| β
| β
| β
| β
| β
|
| PE 32-bit (PE32) | x86 | β
| β
| N/A | β
| β
| N/A |
| PE 64-bit (PE32+) | x86-64 | β
| β
| N/A | β
| β
| N/A |
---
## Exit Codes
| `0` | Analysis completed successfully |
| `1` | File not found, parse error, or unsupported format |
| `2` | `--strict` mode: analysis succeeded but hardening issues were found |
---
## Testing
```bash
# All tests (unit + integration)
cargo test
# Unit tests only
cargo test --lib
# Integration tests only (requires compiled binary)
cargo test --test cli
# Lint
cargo clippy -- -D warnings
# Format check
cargo fmt --check
```
The test suite includes **56 unit tests**, **26 integration tests**, and **3 doc tests** (85 total):
| `analyzer::entropy` | 17 | Shannon formula, edge cases, monotonicity, `extract_permissions` (ELF/COFF flags), section metadata |
| `analyzer::hardening` | 23 | PE header parsing, RELRO states, FORTIFY_SOURCE, RPATH, ELF self-analysis, dangerous symbol categorization |
| `analyzer` (mod) | 16 | `compute_score` boundary values and per-check deductions, `AnalysisReport` API, JSON serialization |
| `tests::cli` | 26 | CLI flags, JSON output, strict mode, stripped detection, error handling, `security_score`, section metadata, dangerous symbol categories |
| doc tests | 3 | Library API smoke tests |
---
## Contributing
Contributions are welcome!
1. Fork the repository
2. Create a feature branch: `git checkout -b feat/your-feature`
3. Write tests where applicable
4. Run `cargo test && cargo clippy -- -D warnings` before submitting
5. Open a Pull Request
Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details *(coming soon)*.
---
## Roadmap
- [x] JSON output mode (`--json`)
- [x] DWARF / PDB debug-info / stripped detection
- [x] Strict mode for CI pipelines (`--strict`, exit code 2)
- [x] FORTIFY_SOURCE detection (`__*_chk` symbol scan)
- [x] RPATH/RUNPATH detection (library-injection risk)
- [x] Library API β `AnalysisReport::analyze()` unified entry point
- [x] Security score (0β100) for dashboard/badge display
- [x] Per-section virtual address, file offset, and rwx permissions
- [x] Dangerous symbol categories (Exec / Net / Mem) for colour-coded visualisation
- [ ] VS Code extension (visualisation front-end)
- [ ] SARIF output format
- [ ] macOS Mach-O support
- [ ] Import table diff between two binaries (`binsleuth diff a.out b.out`)
- [ ] Yara-rule-style byte-pattern matching
---
## License
This project is licensed under the **MIT License** β see [LICENSE](LICENSE) for details.
---
## Acknowledgements
- [object](https://crates.io/crates/object) β cross-platform binary parsing
- [clap](https://crates.io/crates/clap) β CLI argument parsing
- [anyhow](https://crates.io/crates/anyhow) β ergonomic error handling
- [colored](https://crates.io/crates/colored) β terminal color output
---
<div align="center">
Made with β€οΈ and Rust
</div>