Fast, offline static triage for executables. Point it at an unknown ELF or PE and it infers what the binary can do from its imports, flags packing and suspicious sections, and surfaces the strings that matter — in milliseconds, with no sandbox and no network.
▶ Try it in your browser: https://nico-perales.github.io/binsight-web/ (runs via WebAssembly — the file never leaves your machine)
$ binsight suspicious.exe
binsight — Pe · x86-64 · 64-bit · executable
entry point: 0x1a40
verdict: HIGH
- High-entropy section(s), likely packed or encrypted: .text
- Process injection (writeprocessmemory, virtualallocex, createremotethread)
- Anti-debugging (isdebuggerpresent, ntqueryinformationprocess)
capabilities
[high] Process injection
Writes to and executes code in another process's memory.
evidence: writeprocessmemory, virtualallocex, createremotethread
[med] Anti-debugging
Detects or resists debuggers and analysis.
evidence: isdebuggerpresent, ntqueryinformationprocess
sections (name · size · entropy · flags)
.text 412.0 KB 7.91 [X]
.rdata 22.1 KB 5.30
strings of interest
[url] http://c2.example.com/gate.php
[ip] 185.220.101.44
[registry] HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
Important
binsight reports static indicators — signals for triage, not a
confirmation of malice. A packer or a WriteProcessMemory import is a reason to
look closer, not a verdict. It is defensive tooling: it parses bytes, it
never executes the target.
Triaging an unknown binary usually means either opening a heavyweight framework or running it in a sandbox. For a first pass — "is this worth a closer look, and what should I look at?" — that is overkill. binsight answers that first pass instantly:
- Imports become capabilities. A raw import table is noise. binsight maps it to human-readable capabilities ("process injection", "keylogging", "persistence") with the exact APIs as evidence.
- Entropy finds packing. Per-section Shannon entropy flags compressed or encrypted sections — the signature of a packer.
- Strings, triaged. Instead of dumping every string, it keeps only URLs, IPs, registry keys, file paths, and command markers.
- A verdict, honestly framed. Low / Medium / High from the combined signals, always labeled as an indicator rather than a conclusion.
From source (requires a Rust toolchain):
cargo install --path .binsight <FILE> # human-readable triage report
binsight <FILE> -o json # machine-readable JSON for pipelines
binsight <FILE> --fail-on high # exit 1 if verdict >= high (for CI)
binsight <FILE> --color never| Analysis | Signal |
|---|---|
| Capabilities | Process injection, keylogging, anti-debug, dynamic API resolution, cryptography, networking, persistence, process enumeration, recon — inferred from imports. |
| Crypto inventory (PQC) | Which primitives are used (RSA, ECDSA, AES, SHA-2, MD5, ML-KEM…), from imported symbols and embedded constants (AES S-box, SHA-256 constants — so it catches statically-linked crypto with no symbols). Each is flagged quantum-vulnerable / weakened / legacy / post-quantum — a lightweight crypto bill-of-materials. |
| Packing | High-entropy sections, known packer section names (UPX, ASPack, MPRESS…), and a small import table paired with high entropy. |
| Sections | Size, entropy, and permission flags — including writable and executable (W+X) sections. |
| Overlay & embedded PEs | Data appended past the last section, and executables carved from the file body — classic dropper hiding spots. |
| imphash | The pefile-compatible PE import hash, for pivoting and family clustering. |
| Strings | URLs, IPv4 addresses, registry keys, file paths, and command markers (powershell, rundll32, certutil…). |
- Static only. No unpacking, no emulation, no dynamic behavior. A packed sample hides its real imports until unpacked — binsight tells you it is packed, not what it does once unpacked.
- Indicators, not proof. Legitimate software uses these APIs too. The output is a triage signal.
- Analyze the target, not system DLLs. System libraries (e.g.
kernel32.dll) re-export dangerous APIs and will light up. Point binsight at the suspicious executable, not at the OS. - ELF and PE for now. Mach-O is detected but not yet fully analyzed.
- Crypto detection is best-effort. It identifies primitives by known symbol names and a few distinctive constants; hardware-accelerated AES (AES-NI, no S-box table) and generic crypto APIs (Windows CNG/CAPI, where the algorithm is a runtime parameter) may not name a specific primitive. Absence of a finding is not proof no crypto is present.
binsight is a library first; the CLI is a thin layer. Add it without the CLI deps:
[dependencies]
binsight = { version = "0.1", default-features = false }let bytes = std::fs::read("sample.bin")?;
let report = binsight::analyze(&bytes)?;
println!("{:?}: {} capabilities", report.verdict.level, report.capabilities.len());
# Ok::<(), binsight::Error>(())Licensed under either of Apache-2.0 or MIT at your option.