Skip to content

Latest commit

 

History

History
130 lines (96 loc) · 3.45 KB

File metadata and controls

130 lines (96 loc) · 3.45 KB

gostrings

Extracts usable strings from Go binaries, regardless of file format, architecture, or endian-ness.

Why?

Have you ever run strings(1) on a go binary, only to be presented with a bunch of concatenated gobbledy-gook?

That's because Go has a super-efficient way to represent strings in a binary, using pointer+length instead of null-terminated strings.

This tool understands Go binary formats and extracts strings more accurately, inspired by flare-floss which only supports Windows PE binaries, this tool extends support to every executable format supported by Go, no matter how rare.

Features

  • Supports multiple binary formats:
    • ELF (Linux)
    • Mach-O (macOS)
    • PE (Windows)
    • Plan 9 (Plan 9)
    • XCOFF (AIX)
    • WebAssembly (WASM)
      • Full support for GOOS=js GOARCH=wasm
      • Partial support for GOOS=wasip1 GOARCH=wasm (compiler optimizations may eliminate some string structures)
  • Extracts strings from Go-specific sections:
    • .rodata / __rodata - read-only data
    • .gopclntab / __gopclntab - program counter line table
    • .typelink / __typelink - type information
    • .go.buildinfo - build information (Go 1.18+)
  • UTF-8 aware string extraction
  • Configurable minimum string length
  • Deduplication option

Installation

go install github.com/HEXXDECIMAL/gostrings@latest

Usage

# Extract strings from a Go binary
gostrings /path/to/binary

# Set minimum string length (default: 4)
gostrings -n 8 /path/to/binary

# Output only unique strings
gostrings -u /path/to/binary

# Verbose output showing which section each string came from
gostrings -v /path/to/binary

# Combine options
gostrings -v -u -n 6 /path/to/binary

Verbose Mode Output

When using -v, strings are grouped by their source section:

__rodata:
  strings: illegal use of non-zero Builder copied by value
  fmt: unknown base; can't happen
  unexpected call to os.Exit(0) during test
.gopclntab:
  runtime.Gosched
  runtime.goexit

Library Usage

import "github.com/HEXXDECIMAL/gostrings/pkg/gostrings"

opts := gostrings.Options{
    MinLength: 4,
    Unique:    true,
    Verbose:   false,
}

sections, err := gostrings.Extract("/path/to/binary", opts)
if err != nil {
    log.Fatal(err)
}

// Access strings by section
for _, sec := range sections {
    fmt.Printf("Section: %s\n", sec.Name)
    for _, str := range sec.Strings {
        fmt.Printf("  %s\n", str)
    }
}

// Or flatten to a simple string list
strings := gostrings.Flatten(sections)

How it Works

This tool:

  1. Detects the binary format (ELF/Mach-O/PE/Plan 9/XCOFF/WASM) by examining magic bytes
  2. Locates Go-specific sections (.rodata, .gopclntab, .typelink, etc.)
  3. Extracts strings using Go's internal struct{ptr *byte, len int} representation
  4. Groups strings by their source section
  5. Filters by minimum length and optionally deduplicates results globally

Development

# Run tests
make test

# Run linters
make lint

# See a comparison with standard strings command
make demo

References

License

Apache 2.0