Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
71e4c1c
feat(output): add JSON, table, and YARA formatters
unclesp1d3r Jan 18, 2026
4c4c955
Implement table output formatter with TTY and plain modes
unclesp1d3r Jan 18, 2026
b8bcc8e
Implement JSON and YARA output formatters
unclesp1d3r Jan 18, 2026
d2710e8
feat(output): add generated_at timestamp to output metadata
unclesp1d3r Jan 18, 2026
14c3d82
Enable superpowers plugin in Claude settings
unclesp1d3r Jan 18, 2026
de2e8d5
refactor(output): improve YARA formatter code quality and test coverage
unclesp1d3r Jan 18, 2026
6c1b531
fix(docs): clarify ASCII rule for Unicode handling
unclesp1d3r Jan 18, 2026
a122d32
fix(reviews): clarify ASCII rule for Unicode punctuation
unclesp1d3r Jan 18, 2026
3b9c618
chore(settings): remove enabled plugins from configuration
unclesp1d3r Jan 18, 2026
b6689ce
chore(contributing): add contributing guidelines document
unclesp1d3r Jan 18, 2026
bec8192
refactor: address code review findings and add project documentation
unclesp1d3r Jan 18, 2026
0c2744e
chore(devcontainer): add Rust devcontainer configuration
unclesp1d3r Jan 18, 2026
6510b90
refactor(output): split table.rs into module directory
unclesp1d3r Jan 18, 2026
5c53d91
fix(yara): correct UTF-16LE encoding and prevent injection attacks
unclesp1d3r Jan 18, 2026
f4388be
chore(tests): add comprehensive testing strategy analysis
unclesp1d3r Jan 18, 2026
7306f48
chore(devcontainer): update Docker features and remove unused ones
unclesp1d3r Jan 19, 2026
d52047a
chore(setup): update setup commands and add mise installation
unclesp1d3r Jan 19, 2026
1cb3744
chore(cleanup): remove megalinter configurations and references
unclesp1d3r Jan 19, 2026
3b821e5
chore(mise): add node version to tools configuration
unclesp1d3r Jan 19, 2026
704e7c5
refactor(yara): split module to stay under 500-line limit
unclesp1d3r Jan 19, 2026
c4ec73b
chore(agents): fix formatting in critical rules section
unclesp1d3r Jan 20, 2026
74c71bc
docs(AGENTS): improve AI agent guidelines with fixes and additions
unclesp1d3r Jan 24, 2026
9663556
fix: address PR review comments for output formatters
unclesp1d3r Jan 24, 2026
5ccbff1
chore: cleanup devcontainer, justfile, and AGENTS.md
unclesp1d3r Jan 24, 2026
e4d1e15
refactor(justfile): use mise exec for all tool commands
unclesp1d3r Jan 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .claude/settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"enabledPlugins": {
"commit@cc-marketplace": true
"commit@cc-marketplace": true,
"superpowers@claude-plugins-official": true
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
}
24 changes: 8 additions & 16 deletions src/classification/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,14 @@
//! use stringy::types::{FoundString, Encoding, StringSource, Tag};
//!
//! let classifier = SemanticClassifier::new();
//! let found_string = FoundString {
//! text: "C:\\Windows\\System32\\cmd.exe".to_string(),
//! original_text: None,
//! encoding: Encoding::Ascii,
//! offset: 0,
//! rva: None,
//! section: None,
//! length: 27,
//! tags: Vec::new(),
//! score: 0,
//! section_weight: None,
//! semantic_boost: None,
//! noise_penalty: None,
//! source: StringSource::SectionData,
//! confidence: 1.0,
//! };
//! let text = "C:\\Windows\\System32\\cmd.exe";
//! let found_string = FoundString::new(
//! text.to_string(),
//! Encoding::Ascii,
//! 0,
//! text.len() as u32,
//! StringSource::SectionData,
//! );
//!
//! let tags = classifier.classify(&found_string);
//! assert!(tags.contains(&Tag::FilePath));
Expand Down
24 changes: 8 additions & 16 deletions src/classification/semantic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,14 @@
//! use stringy::types::{FoundString, Encoding, StringSource};
//!
//! let classifier = SemanticClassifier::new();
//! let found_string = FoundString {
//! text: "https://example.com/api".to_string(),
//! original_text: None,
//! encoding: Encoding::Ascii,
//! offset: 0,
//! rva: None,
//! section: None,
//! length: 24,
//! tags: Vec::new(),
//! score: 0,
//! section_weight: None,
//! semantic_boost: None,
//! noise_penalty: None,
//! source: StringSource::SectionData,
//! confidence: 1.0,
//! };
//! let text = "https://example.com/api";
//! let found_string = FoundString::new(
//! text.to_string(),
//! Encoding::Ascii,
//! 0,
//! text.len() as u32,
//! StringSource::SectionData,
//! );
//!
//! let tags = classifier.classify(&found_string);
//! assert_eq!(tags.len(), 1);
Expand Down
49 changes: 17 additions & 32 deletions src/classification/symbols.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,17 @@
//! use stringy::types::{FoundString, Encoding, StringSource, Tag};
//!
//! let demangler = SymbolDemangler::new();
//! let mut found_string = FoundString {
//! text: "_ZN4core3fmt5Write9write_str17h1234567890abcdefE".to_string(),
//! original_text: None,
//! encoding: Encoding::Ascii,
//! offset: 0,
//! rva: None,
//! section: None,
//! length: 47,
//! tags: Vec::new(),
//! score: 0,
//! section_weight: None,
//! semantic_boost: None,
//! noise_penalty: None,
//! source: StringSource::ImportName,
//! confidence: 1.0,
//! };
//! let text = "_ZN4core3fmt5Write9write_str17h1234567890abcdefE";
//! let mut found_string = FoundString::new(
//! text.to_string(),
//! Encoding::Ascii,
//! 0,
//! text.len() as u32,
//! StringSource::ImportName,
//! );
//!
//! demangler.demangle(&mut found_string);
//! assert!(found_string.tags.contains(&Tag::DemangledSymbol));
//! // found_string.text now contains the demangled symbol
//! // found_string.original_text contains the original mangled form
//! // found_string.tags contains Tag::DemangledSymbol
Expand Down Expand Up @@ -129,22 +122,14 @@ impl SymbolDemangler {
/// use stringy::types::{FoundString, Encoding, StringSource, Tag};
///
/// let demangler = SymbolDemangler::new();
/// let mut found_string = FoundString {
/// text: "_ZN4core3fmt5Write9write_str17h1234567890abcdefE".to_string(),
/// original_text: None,
/// encoding: Encoding::Ascii,
/// offset: 0,
/// rva: None,
/// section: None,
/// length: 47,
/// tags: Vec::new(),
/// score: 0,
/// section_weight: None,
/// semantic_boost: None,
/// noise_penalty: None,
/// source: StringSource::ImportName,
/// confidence: 1.0,
/// };
/// let text = "_ZN4core3fmt5Write9write_str17h1234567890abcdefE";
/// let mut found_string = FoundString::new(
/// text.to_string(),
/// Encoding::Ascii,
/// 0,
/// text.len() as u32,
/// StringSource::ImportName,
/// );
///
/// demangler.demangle(&mut found_string);
/// assert!(found_string.tags.contains(&Tag::DemangledSymbol));
Expand Down
2 changes: 1 addition & 1 deletion src/extraction/ascii.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
//! is_writable: false,
//! weight: 1.0,
//! };
//! let strings = extract_from_section(&section, data, &config);
//! let strings = extract_from_section(&section, data, &config, None, false, 0.5);
//! ```

use crate::extraction::config::NoiseFilterConfig;
Expand Down
11 changes: 7 additions & 4 deletions src/extraction/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
//! and noise filtering. It implements byte-level scanning for contiguous UTF-16LE character
//! sequences, following the pattern established in the ASCII extractor.
//!
//! - `extract_utf16le_strings()`: Basic byte-level UTF-16LE string scanning
//! - `extract_utf16_strings()`: Basic byte-level UTF-16 string scanning
//! - `extract_from_section()`: Section-aware extraction with proper metadata population
//! - `Utf16ExtractionConfig`: Configuration for minimum/maximum character count and confidence thresholds
//!
Expand Down Expand Up @@ -89,6 +89,7 @@
//! use stringy::extraction::{BasicExtractor, ExtractionConfig, StringExtractor};
//! use stringy::container::{detect_format, create_parser};
//!
//! # fn example() -> stringy::Result<()> {
//! let data = std::fs::read("example.exe")?;
//! let format = detect_format(&data);
//! let parser = create_parser(format)?;
Expand All @@ -100,17 +101,17 @@
//!
//! // Format-specific extractors
//! use stringy::extraction::{
//! extract_ascii_strings, extract_utf16le_strings, extract_load_command_strings, extract_resources,
//! extract_ascii_strings, extract_utf16_strings, extract_load_command_strings, extract_resources,
//! extract_resource_strings, AsciiExtractionConfig, Utf16ExtractionConfig,
//! };
//!
//! // ASCII extraction
//! let ascii_config = AsciiExtractionConfig::default();
//! let ascii_strings = extract_ascii_strings(&data, &ascii_config);
//!
//! // UTF-16LE extraction
//! // UTF-16 extraction
//! let utf16_config = Utf16ExtractionConfig::default();
//! let utf16le_strings = extract_utf16le_strings(&data, &utf16_config);
//! let utf16_strings = extract_utf16_strings(&data, &utf16_config);
//!
//! // Phase 1: Get resource metadata
//! let metadata = extract_resources(&data);
Expand All @@ -121,6 +122,8 @@
//! // Mach-O load command extraction
//! let macho_data = std::fs::read("example.dylib")?;
//! let load_command_strings = extract_load_command_strings(&macho_data);
//! # Ok(())
//! # }
//! ```

use crate::classification::{SemanticClassifier, SymbolDemangler};
Expand Down
7 changes: 7 additions & 0 deletions src/extraction/pe_resources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@
//!
//! ```rust
//! use stringy::extraction::pe_resources::extract_resources;
//! use stringy::types::ResourceType;
//!
//! # fn example() -> stringy::Result<()> {
//! let pe_data = std::fs::read("example.exe")?;
//! let resources = extract_resources(&pe_data);
//!
Expand All @@ -65,6 +67,8 @@
//! _ => {}
//! }
//! }
//! # Ok(())
//! # }
//! ```
//!
//! ## Phase 2: Resource String Extraction
Expand All @@ -73,6 +77,7 @@
//! use stringy::extraction::pe_resources::extract_resource_strings;
//! use stringy::types::Tag;
//!
//! # fn example() -> stringy::Result<()> {
//! let pe_data = std::fs::read("example.exe")?;
//! let strings = extract_resource_strings(&pe_data);
//!
Expand All @@ -85,6 +90,8 @@
//! let ui_strings: Vec<_> = strings.iter()
//! .filter(|s| s.tags.contains(&Tag::Resource) && !s.tags.contains(&Tag::Version))
//! .collect();
//! # Ok(())
//! # }
//! ```

use crate::types::{
Expand Down
11 changes: 8 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@
//! println!("Found {} ASCII strings", ascii_strings.len());
//!
//! // UTF-16LE string extraction (Windows PE binaries)
//! use stringy::extraction::{extract_utf16le_strings, Utf16ExtractionConfig};
//! use stringy::extraction::{extract_utf16_strings, Utf16ExtractionConfig};
//! let utf16_config = Utf16ExtractionConfig::default();
//! let utf16le_strings = extract_utf16le_strings(&data, &utf16_config);
//! println!("Found {} UTF-16LE strings", utf16le_strings.len());
//! let utf16_strings = extract_utf16_strings(&data, &utf16_config);
//! println!("Found {} UTF-16 strings", utf16_strings.len());
//! # Ok(())
//! # }
//! ```
Expand Down Expand Up @@ -84,3 +84,8 @@ pub use extraction::{
AsciiExtractionConfig, BasicExtractor, CanonicalString, ExtractionConfig, StringExtractor,
StringOccurrence, Utf16ExtractionConfig, deduplicate,
};

// Re-export output infrastructure types
pub use output::{
OutputFormat, OutputMetadata, format_json, format_output, format_table_with_mode, format_yara,
};
Loading
Loading