Repository navigation
Description
Summary
Extend the UTF-16 string extractor to support big-endian byte order (UTF-16BE) with confidence scoring to distinguish legitimate UTF-16BE strings from binary data that coincidentally resembles UTF-16 encoding.
Background
While UTF-16LE (little-endian) is dominant in Windows PE binaries, UTF-16BE appears in:
- Network protocol payloads and packet captures
- Java .class files and serialized objects
- Some file formats (certain PDFs, XML with BOM markers)
- Cross-platform binaries targeting big-endian architectures (SPARC, PowerPC, some ARM)
Without UTF-16BE support, Stringy would miss meaningful strings in these binaries. However, naive UTF-16BE extraction can produce false positives since certain binary data patterns can resemble valid UTF-16BE sequences.
Problem Statement
The current extraction framework (src/extraction/mod.rs) lacks UTF-16BE support entirely. Additionally, both UTF-16LE and UTF-16BE extractors need confidence scoring to avoid extracting garbage that looks like valid UTF-16:
False Positive Scenarios:
- Binary tables with null bytes in predictable positions
- Numeric data that happens to have zeros in high/low byte positions
- Padding or alignment bytes creating null-interleaved patterns
- Compressed or encrypted data with statistical byte patterns
Requirements
- Req 2.3: UTF-16BE extraction with byte-order awareness
- Req 2.4: Confidence scoring for both UTF-16LE and UTF-16BE
Proposed Solution
1. Extend src/extraction/utf16.rs
Create a unified UTF-16 extractor that handles both byte orders:
pub struct Utf16Extractor {
min_length: usize,
confidence_threshold: f32,
}
impl Utf16Extractor {
// Scan for UTF-16LE and UTF-16BE sequences
pub fn extract(&self, data: &[u8], byte_order: ByteOrder) -> Vec<RawString>
// Calculate confidence score (0.0 - 1.0)
fn calculate_confidence(&self, chars: &[u16]) -> f32
}2. Confidence Scoring Algorithm
Score UTF-16 candidates based on multiple heuristics:
Positive Indicators (+):
- Valid Unicode code points (especially ASCII range U+0020-U+007E)
- Common punctuation and whitespace
- Consistent byte order throughout the string
- Presence of word boundaries (spaces, newlines)
- Character distribution matching natural language
Negative Indicators (-):
- Invalid or private-use Unicode ranges
- Excessive control characters (except \n, \r, \t)
- Suspicious null byte patterns (every other byte, or repeating sequences)
- High concentration of bytes outside printable ranges
- Characters from mixed/incompatible Unicode blocks
Confidence Formula:
confidence = (valid_chars_weight × valid_ratio)
+ (printable_weight × printable_ratio)
+ (language_weight × word_boundary_score)
- (null_pattern_penalty)
- (control_char_penalty)
- (entropy_anomaly_penalty)
3. Null-Interleaved Pattern Detection
Implement specific checks for false-positive patterns:
- Every-other-null: could be UTF-16LE "AB" or coincidental
- Fixed-offset nulls: Nulls appearing at consistent intervals suggesting tables/structures
- Run-length encoding artifacts: Repeated null sequences that aren't valid UTF-16
4. Integration Points
- Wire into the main extraction pipeline (task 16)
- Ensure proper handling of section boundaries
- Support configurable confidence threshold via CLI (--utf16-confidence)
- Add encoding detection heuristics to auto-select LE vs BE when unspecified
Implementation Checklist
- Extend utf16.rs with ByteOrder enum (LE, BE, Auto)
- Implement UTF-16BE byte sequence scanning
- Create confidence scoring function with weighted heuristics
- Add null-pattern detection and scoring penalties
- Implement configurable confidence threshold
- Add unit tests for UTF-16BE extraction
- Add unit tests for confidence scoring edge cases
- Add tests for false positive prevention (binary tables, numeric data)
- Add integration test with real-world UTF-16BE samples
- Document confidence scoring algorithm in code comments
Test Cases
- Legitimate UTF-16BE: Java .class constant pool strings
- False Positive: Null-interleaved numeric table data
- Edge Case: Mixed ASCII and Unicode characters
- Boundary: Minimum length UTF-16BE strings at section edges
- Performance: Large binary with scattered null bytes
Dependencies
- Blocked by: Implement UTF-16LE String Extraction with Confidence Scoring and Minimum Length Filtering #11 (UTF-16LE String Extraction) - Need base UTF-16 framework first
- Related to: Implement Encoding Confidence Scoring and Integrate Section Weights into Ranking System #22 (Encoding Confidence Scoring and Ranking System)
Success Criteria
- Correctly extracts UTF-16BE strings from Java .class files
- Rejects false positives from binary data with <10% false positive rate
- Confidence scores correlate with human assessment (validated against test corpus)
- Performance impact: <20% overhead compared to basic UTF-16 scanning
- Integration with ranking system properly weighs UTF-16BE confidence
Task ID
stringy-analyzer/utf16be-support-confidence-scoring
Activity
unclesp1d3r commentedon Nov 10, 2025
@coderabbitai Enhance this issue body with additional context and a proposed solution. Improve the issue title and assign the proper labels and other metadata.
[-]UTF-16BE Support and Confidence Scoring[/-][+]Implement UTF-16BE String Extraction with Confidence Scoring and False Positive Prevention[/+]traycerai commentedon Nov 10, 2025
Plan
Observations
The codebase has a well-established extraction framework with ASCII extraction fully implemented, including confidence scoring via noise filters. UTF-16LE decoding exists in
pe_resources.rsbut only for resource extraction, not general section scanning. TheEncodingenum already includesUtf16LeandUtf16Bevariants. TheExtractionConfighasmin_wide_length(default 3) ready for UTF-16 use. TheBasicExtractororchestrates extraction by calling format-specific extractors and applying noise filtering with configurable confidence thresholds.Approach
Create a new
utf16.rsmodule following the ASCII extractor pattern. Implement byte-order-aware scanning for both UTF-16LE and UTF-16BE with aByteOrderenum (LE, BE, Auto). Add UTF-16-specific confidence scoring to detect false positives from null-interleaved binary data, then integrate with existing noise filters. Wire intoBasicExtractor::extract_from_sectionto enable UTF-16 extraction alongside ASCII/UTF-8. Add comprehensive tests covering legitimate UTF-16 strings, false positive scenarios, and edge cases.Reasoning
Listed the repository structure to understand the project layout. Read the extraction module files to understand the current architecture and patterns. Examined the ASCII extractor implementation to understand the extraction and confidence scoring approach. Reviewed the noise filtering framework to understand how confidence scores are calculated and combined. Checked the PE resources module to see existing UTF-16LE decoding logic. Searched for UTF-16 references to understand current usage. Reviewed integration tests to understand testing patterns and expectations.
Proposed File Changes
📄 src/extraction/utf16.rs (NEW) 🔗
📄 src/extraction/mod.rs (MODIFY) 🔗
📄 tests/test_utf16_extraction.rs (NEW) 🔗
📄 tests/integration_extraction.rs (MODIFY) 🔗
📄 src/extraction/pe_resources.rs (MODIFY) 🔗
📄 docs/src/string-extraction.md (MODIFY) 🔗
Diagram
sequenceDiagram participant User participant BasicExtractor participant Utf16Module participant ConfidenceScorer participant NoiseFilter participant FoundString User->>BasicExtractor: extract_from_section(data, section, config) BasicExtractor->>BasicExtractor: Check if UTF-16 enabled in config alt UTF-16LE or UTF-16BE enabled BasicExtractor->>Utf16Module: extract_from_section(section, data, utf16_config) alt ByteOrder::Auto Utf16Module->>Utf16Module: extract_utf16le_strings(data) Utf16Module->>Utf16Module: extract_utf16be_strings(data) else ByteOrder::LE Utf16Module->>Utf16Module: extract_utf16le_strings(data) else ByteOrder::BE Utf16Module->>Utf16Module: extract_utf16be_strings(data) end loop For each candidate string Utf16Module->>ConfidenceScorer: calculate_utf16_confidence(chars, byte_order) ConfidenceScorer->>ConfidenceScorer: check_valid_unicode_range() ConfidenceScorer->>ConfidenceScorer: check_null_pattern() ConfidenceScorer->>ConfidenceScorer: check_ascii_ratio() ConfidenceScorer->>ConfidenceScorer: check_printable_ratio() ConfidenceScorer-->>Utf16Module: utf16_confidence (0.0-1.0) alt utf16_confidence >= threshold Utf16Module->>Utf16Module: decode_to_utf8(chars) opt Noise filtering enabled Utf16Module->>NoiseFilter: calculate_confidence(text, context) NoiseFilter-->>Utf16Module: noise_confidence (0.0-1.0) Utf16Module->>Utf16Module: final_confidence = min(utf16_conf, noise_conf) end alt final_confidence >= min_threshold Utf16Module->>FoundString: Create with metadata FoundString-->>Utf16Module: found_string end end end Utf16Module-->>BasicExtractor: Vec<FoundString> BasicExtractor->>BasicExtractor: Merge with ASCII/UTF-8 results end BasicExtractor-->>User: Vec<FoundString>Import In IDE
🤖 Prompt for AI Agents
Developer Humor
Execution Information
Branch: main
Commit: c50e9b6
💡 Tips
Supported Commands (Inside Comments)
@traycerai generateto iterate on the previous version of the implementation plan.Supported Commands (Inside Description)
@traycerai ignoreanywhere in the ticket description to prevent this ticket from being processed.@traycerai branch:<branch-name>anywhere in the ticket description to specify the target branch for the implementation plan.Community
coderabbitai commentedon Nov 10, 2025
Tip
For best results, initiate chat on the files or code changes.
🧩 Analysis chain
🏁 Script executed:
Length of output: 1334
🏁 Script executed:
Length of output: 277
🏁 Script executed:
Length of output: 0
🏁 Script executed:
Length of output: 0
🏁 Script executed:
Length of output: 1765
🏁 Script executed:
Length of output: 26
🏁 Script executed:
Length of output: 28
🏁 Script executed:
Length of output: 7196
🏁 Script executed:
Length of output: 422
🏁 Script executed:
Length of output: 5122
🏁 Script executed:
Length of output: 6081
🏁 Script executed:
Length of output: 11166
🏁 Script executed:
Length of output: 11157
🏁 Script executed:
Length of output: 2427
🏁 Script executed:
Length of output: 702
🏁 Script executed:
Length of output: 106
🏁 Script executed:
Length of output: 61
🏁 Script executed:
Length of output: 6261
@unclesp1d3r I've successfully enhanced issue #12 with comprehensive details. Here's what was improved:
✅ Enhanced Title
Before: "UTF-16BE Support and Confidence Scoring"
After: "Implement UTF-16BE String Extraction with Confidence Scoring and False Positive Prevention"
✅ Enhanced Content
The issue body now includes:
Background Context
Problem Statement
Proposed Solution
Implementation Details
✅ Updated Metadata
priority:medium(joins existing area:analyzer, type:enhancement, status:backlog, lang:rust, needs:tests)The issue is now ready for implementation with clear technical guidance and acceptance criteria. You can view the updated issue here: #12
unclesp1d3r commentedon Nov 13, 2025
@traycerai generate branch:implement-utf-16le-string-extraction-with-confidence-scoring-and-minimum-length-filtering
traycerai commentedon Nov 13, 2025
Hi @unclesp1d3r, I have updated the Implementation Plan to reflect the recent changes in the ticket.