stng is strings(1) for people who read malware: it pulls URLs,
IPs, commands and credentials out of binaries and scripts, even when they're
encoded or encrypted, for triage and YARA signatures. v2.0.0 finds strings
that earlier versions missed: XOR-encrypted payloads in droppers, the custom ciphers macOS stealers use, and obfuscated
VBScript and batch files. Hostile files can no longer crash or stall it. If
you embed the Rust library, check the breaking changes below: caching and
rizin/radare2 support have moved out of it.
Features
- Recovers dropper-embedded PE payloads encrypted with a short repeating XOR key.
- Decodes strings from x86 PE repeating-key XOR routines via a bounded interpreter.
- Adds --xor-lcg for analyst-supplied LCG-XOR ranges; Mach-O LCG loaders decode automatically.
- Extracts strings from single-byte-XOR universal Mach-O payloads hidden in __const sections.
- ARM64: recovers XOR literals with pointer-derived keys and Rust heap-array XOR loops.
- Decrypts macOS stealer strings sealed with a MurmurHash3-finalizer keystream.
- Recovers Swift small strings assembled with ARM64 move-wide instructions.
- Go: extracts Mach-O __gopclntab function names and struct tags via reflection metadata.
- Go/Rust: recovers string headers stored into literal tables on ARM64 and x86-64.
- Rust: detects stripped executables and recovers PIE literals via RELATIVE relocations.
- Scripts: decodes VBScript.Encode blocks and expands cmd.exe batch variable-splicing obfuscation.
- Decrypts legacy ColdFusion CFCRYPT (cfencode) templates back to CFML source.
- Hex-encoded blobs are now scanned for single-byte-XOR strings hidden inside.
- Decodes Base64 with omitted padding, and UTF-8 text behind a bogus UTF-16 BOM.
- Flags credential stores, wallets, browser data and shell history as suspicious paths.
- New cli feature: default-features = false builds the library without CLI dependencies.
Fixes
- ELF Go and Rust strings now report file offsets instead of virtual addresses.
- Go funcnametab recovery no longer drops long module paths or generic instantiations.
- Platform-signature check reads only the embedded signature, so Developer ID malware gets scanned.
- Rust Mach-O string tables in __DATA,__const from older linkers are now extracted.
- Crafted Mach-O bind opcodes no longer panic extraction; only imports are lost.
- Script decompression is capped at 10 MiB while inflating, blocking decompression bombs.
- Hardened header-offset arithmetic; a new mutation test asserts hostile files never panic.
- Injection detection requires whole-word commands after ;/|, cutting false ShellCmd hits.
- Strings with @ that aren't emails now fall through to URL/path/command classification.
Optimizations
- XOR pattern scan finds each printable run once per alignment, removing quadratic blowups.
- Hostname expansion is bounded by DNS name length, avoiding quadratic walks on long runs.
- CLI caps rayon at 16 threads: 15–40% faster, 4–8× less CPU on 128 cores.
- Dropped hex and urlencoding deps; library builds skip clap, sha2, jemalloc, tracing-subscriber.
- Published crate ships only src/, excluding ~90 MB of test data.
Breaking
- String cache and cache sweeper removed; caching now belongs to callers like filefacts.
- rizin/radare2 integration moved into the CLI; with_removed.
- Section-info collectors return Vec<SectionInfo>, since names repeat across segments.
Full notes on GitHub.
brew upgrade atomdrift-project/tap/stng