Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

strings

License: GPL v3 Build Status Release

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.

What it does

  • 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 .so can 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.

Install

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.

Usage

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-sections

Building from source

Requires the .NET 10 SDK.

git clone https://github.com/Swiftly-Tracker/strings.git
cd strings
dotnet build strings.slnx -c Release

Output 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-x64

Architecture

strings/
├── 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

Community

License

GPL-3.0. See LICENSE.


Made with ❤️ by the Swiftly Development team

About

Dump strings from binaries

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages