Output Formats
Stringy supports three output formats optimized for different use cases.
Table Format (Default)
TTY Mode
When stdout is a TTY, results are shown as an aligned table. Columns appear in this order:
String Tags Score Section
------ ---- ----- -------
https://api.example.com/v1/users Url 95 .rdata
{12345678-1234-1234-1234-123456789abc} guid 87 .rdata
/usr/local/bin/application filepath 82 __cstring
Error: %s at line %d fmt 78 .rdata
Features:
- Truncation: Long strings are truncated with
...indicator - Sorting: Results sorted by score (highest first)
- Alignment: Columns properly aligned for readability
Plain Text (Piped / Non-TTY)
When stdout is piped, output switches to plain text with one string per line and no headers or table formatting. This is designed for downstream tool consumption.
--summary Block
When --summary is passed (TTY mode only; conflicts with --json and --yara), a summary block is appended after the table showing aggregate statistics about the extraction.
JSON Lines Format
Machine-readable format with one JSON object per line (JSONL), ideal for automation and pipeline integration.
stringy --json binary
Example Output
{"text":"https://api.example.com/v1/users","encoding":"Ascii","offset":4096,"rva":4096,"section":".rdata","length":31,"tags":["Url"],"score":95,"confidence":1.0,"source":"SectionData"}
{"text":"{12345678-1234-1234-1234-123456789abc}","encoding":"Ascii","offset":8192,"rva":8192,"section":".rdata","length":38,"tags":["guid"],"score":87,"confidence":0.95,"source":"SectionData"}
Schema
Each JSON object contains:
| Field | Type | Description |
|---|---|---|
text | string | The extracted string (demangled if applicable) |
original_text | string or null | Original mangled form (present only when demangled) |
encoding | string | Encoding: Ascii, Utf8, Utf16Le, Utf16Be |
offset | number | File offset in bytes |
rva | number or null | Relative Virtual Address (if available) |
section | string or null | Section name where found |
length | number | String length in bytes |
tags | array | Semantic classification tags |
score | number | Internal relevance score |
display_score | number or null | Display score (0-100 band-mapped); only present with --debug |
confidence | number | Confidence score from noise filtering (0.0-1.0) |
source | string | Source type: SectionData, ImportName, ExportName, etc. |
Debug Fields
When --debug is passed, four additional fields appear:
| Field | Type | Description |
|---|---|---|
display_score | number or null | Display score (0-100 band-mapped) |
section_weight | number or null | Section weight contribution to score |
semantic_boost | number or null | Semantic classification boost |
noise_penalty | number or null | Noise penalty applied |
Raw Mode
With --raw --json, output contains extraction-only data: score is 0, tags is empty, and display_score is absent.
Processing Examples
# Extract only URLs
stringy --json binary | jq 'select(.tags[] == "Url") | .text'
# High-score strings only
stringy --json binary | jq 'select(.score > 80)'
# Group by section
stringy --json binary | jq -r '.section' | sort | uniq -c
# Find strings in specific section
stringy --json binary | jq 'select(.section == ".rdata")'
YARA Format
Specialized format for creating YARA detection rules with proper escaping and metadata.
stringy --yara binary
Example Output
// YARA rule generated by Stringy
// Binary: binary
// Generated: 1234567890
rule binary_strings {
meta:
description = "Strings extracted from binary"
generated_by = "stringy"
generated_at = "1234567890"
strings:
// tag: filepath
// score: 82
$filepath_1 = "/usr/local/bin/application" ascii
// tag: fmt
// score: 78
$fmt_1 = "Error: %s at line %d" ascii
// tag: Url
// score: 95
$Url_1 = "https://api.example.com/v1/users" ascii
// skipped (length > 200 chars): 245
condition:
any of them
}
Features
- Rule naming: Rule name is derived from the filename with non-alphanumeric characters replaced by
_and a_stringssuffix added - Tag grouping: Strings are grouped by their first tag with
// tag: <name>comments and per-string// score: <N>annotations - Variable naming: Variables use tag-derived names (e.g.,
$Url_1,$filepath_1,$fmt_1) rather than sequential$sN - Proper escaping: Handles special characters and binary data
- Long string handling: Strings over 200 characters are replaced with
// skipped (length > 200 chars): N(where N is the character count) - Modifiers: Appropriate
ascii/widemodifiers based on encoding
Score Behavior
Stringy uses a band-mapping system to convert internal scores to display scores (0-100):
| Internal Score | Display Score | Meaning |
|---|---|---|
| <= 0 | 0 | Low relevance |
| 1-79 | 1-49 | Low relevance |
| 80-119 | 50-69 | Moderate |
| 120-159 | 70-89 | Meaningful |
| 160-220 | 90-100 | High-value |
| > 220 | 100 (clamped) | High-value |
Format Comparison
| Feature | Table | JSON | YARA |
|---|---|---|---|
| Interactive use | Yes | No | No |
| Automation | No | Yes | No |
| Rule creation | No | No | Yes |
| Full metadata | No | Yes | No |
Output Customization
Filtering
All formats support the same filtering options:
# Limit results
stringy --top 50 --json binary
# Filter by tags
stringy --only-tags url --only-tags domain --yara binary
# Minimum score threshold (post-process)
stringy --json binary | jq 'select(.score >= 70)'
Redirection
# Save to file
stringy --json binary > strings.jsonl
stringy --yara binary > rules.yar
# Pipe to other tools
stringy --json binary | jq 'select(.tags[] == "Url")' | less