Extract readable strings out of a game binary, without the usual flood of hashes, padding, and one-off symbol fragments strings.exe/GNU strings leave behind.
Reads PE, ELF and Mach-O binaries directly (no OS-specific APIs to load them), pulls candidate strings out of the sections that actually hold them, drops anything that isn't a real word, demangles the C++ symbols that survive, and prints the result sorted and deduplicated.
- Format-aware section scanning - PE (
.data/.rdata, falls back to.text), ELF (.dynstr,.rodata,.rodata.str*,.data,.strtab, ...), Mach-O (__cstring,__const,__data, ...). No dependency on the host OS matching the binary's format - a.socan be scanned from Windows and vice versa. - Word filtering - every candidate string is run through a word-segmentation pass (à la wordninja) against a large dictionary; strings with no recognizable word anywhere in them (hashes, padding, random symbol soup) are dropped, even as a partial match inside a longer run.
- C++ demangling - both Itanium (
_Z...) and MSVC (?...,.?AV...) manglings, including the RTTI-only forms compilers emit without the usual mangling prefix, MSVC's array/pointer type descriptors, and nested lambda/local-class names. - Sorted, deduplicated output - one string per line, alphabetical, no repeats.
- Parallel multi-binary processing - pass several binaries at once and they're scanned concurrently, one worker per binary, each written to its own
<binary>.txt.
Grab an archive from the latest release:
| Archive | Needs .NET installed? | Use when |
|---|---|---|
strings-win-x64.zip |
No | Windows, just run it |
strings-linux-x64.zip |
No | Linux, just run it |
strings-win-x64-portable.zip |
.NET 10 runtime | Windows, smaller download |
strings-linux-x64-portable.zip |
.NET 10 runtime | Linux, smaller download |
Those links always resolve to the newest stable release. On Linux, chmod +x strings after unzipping. Keep data/all.gz next to the executable - it's the word dictionary and is required at runtime.
strings --binary=<path|glob>[,<path|glob>...] [options]
Results are written to <binary-filename-without-extension>.txt (one file per binary, next to each other) - not printed to stdout. Pass multiple binaries (comma-separated, or repeat --binary) and they're processed in parallel, one thread per binary. --binary also accepts glob patterns (*.dll, bin/**/*.so, ...) which get expanded to every matching file. While a binary is being scanned, the console prints its live throughput (strings/s) every half-second; as soon as a binary finishes, its output path and final string count are printed immediately - it doesn't wait for the others.
| Flag | Description |
|---|---|
--binary=<path|glob> |
Path(s)/glob(s) of the binaries to parse (required); comma-separated or repeat the flag, processed in parallel |
--target=<type> |
Binary format: pe, elf, or macho - auto-detected from magic bytes if omitted |
--demangle=<bool> |
Demangle C++ symbols (default true) |
--min-length=<n> |
Minimum string length to keep (default 3) |
--sym-length=<n> |
Strings at or under this length are dropped if they're majority non-alphanumeric (default 10) |
--print-sections |
List every section name in the binary and exit |
--output-dir=<path> |
Directory to write <binary-without-extension>.txt results to (default: current directory) |
Examples:
# Auto-detect format, demangle, write to libserver.txt
./strings --binary=libserver.so
# Multiple binaries at once, scanned in parallel, one .txt each
./strings --binary=client.dll,server.dll,libserver.so --output-dir=out
# Glob every DLL in a tree, scanned in parallel
./strings --binary='bin/**/*.dll' --output-dir=out
# Skip demangling
./strings --binary=client.dll --demangle=false
# See what sections exist before picking one to inspect further
./strings --binary=server.dll --print-sectionsRequires the .NET 10 SDK.
git clone https://github.com/Swiftly-Tracker/strings.git
cd strings
dotnet build strings.slnx -c ReleaseOutput lands in bin/Release/net10.0/.
To produce a standalone binary like the release archives:
dotnet publish strings.csproj -c Release \
-r linux-x64 --self-contained true \
-p:PublishSingleFile=true -p:PublishReadyToRun=true -p:PublishTrimmed=false \
-o out/linux-x64strings/
├── src/
│ ├── Entrypoint.cs # CLI entry point, per-format section lists, filter pipeline
│ ├── CliOptions.cs # Flag parsing
│ ├── FileReader.cs # Magic-byte format detection, dispatch, string extraction
│ ├── PeSections.cs # PE section-table reader
│ ├── ElfSections.cs # ELF32/64 section-table reader
│ ├── MachOSections.cs # Mach-O32/64 section-table reader
│ ├── Util.cs # Escaping, symbol-density filter, C++ demangling
│ └── WordList.cs # Word-segmentation dictionary and matcher
└── data/
└── all.gz # Word dictionary used by the word filter
- Issues: Report bugs and request features
GPL-3.0. See LICENSE.