diff --git a/src/binwalk.rs b/src/binwalk.rs index 3a32c388b..678df9575 100644 --- a/src/binwalk.rs +++ b/src/binwalk.rs @@ -73,7 +73,7 @@ pub struct Binwalk { impl Binwalk { /// Create a new Binwalk instance with all default values. - /// Equivalent to `Binwalk::configure(None, None, None, None, None)`. + /// Equivalent to `Binwalk::configure(None, None, None, None, None, false)`. /// /// ## Example /// @@ -84,7 +84,7 @@ impl Binwalk { /// ``` #[allow(dead_code)] pub fn new() -> Binwalk { - Binwalk::configure(None, None, None, None, None).unwrap() + Binwalk::configure(None, None, None, None, None, false).unwrap() } /// Create a new Binwalk instance. @@ -111,7 +111,8 @@ impl Binwalk { /// None, /// None, /// Some(exclude_filters), - /// None)?; + /// None, + /// false)?; /// # Ok(binwalker) /// # } _doctest_main_src_binwalk_rs_102_0(); } /// ``` @@ -121,6 +122,7 @@ impl Binwalk { include: Option>, exclude: Option>, signatures: Option>, + full_search: bool, ) -> Result { let mut new_instance = Binwalk { ..Default::default() @@ -193,7 +195,7 @@ impl Binwalk { // Each signature may have multiple magic bytes associated with it for pattern in signature.magic.clone() { - if signature.short { + if signature.short && !full_search { // These are short patterns, and should only be searched for at the very beginning of a file new_instance.short_signatures.push(signature.clone()); } else { @@ -544,7 +546,8 @@ impl Binwalk { /// Some(extraction_directory), /// None, /// None, - /// None)?; + /// None, + /// false)?; /// /// let file_data = std::fs::read(&binwalker.base_target_file).expect("Unable to read file"); /// @@ -645,7 +648,8 @@ impl Binwalk { /// Some(extraction_directory), /// None, /// None, - /// None)?; + /// None, + /// false)?; /// /// let analysis_results = binwalker.analyze(&binwalker.base_target_file, true); /// diff --git a/src/cliparser.rs b/src/cliparser.rs index ae8461e26..e2aad1130 100644 --- a/src/cliparser.rs +++ b/src/cliparser.rs @@ -23,6 +23,10 @@ pub struct CliArgs { #[arg(short = 'M', long)] pub matryoshka: bool, + /// Search for all signatures at all offsets + #[arg(short = 'a', long)] + pub search_all: bool, + /// Plot the entropy of the specified file #[arg(short = 'E', long, conflicts_with = "extract")] pub entropy: bool, diff --git a/src/extractors/zlib.rs b/src/extractors/zlib.rs index e0c5aed90..513ade44a 100644 --- a/src/extractors/zlib.rs +++ b/src/extractors/zlib.rs @@ -1,6 +1,9 @@ use crate::extractors::common::{ExtractionResult, Extractor, ExtractorType}; use crate::extractors::inflate; +/// Size of the checksum that follows the ZLIB deflate data stream +pub const CHECKSUM_SIZE: usize = 4; + /// Defines the internal extractor function for decompressing zlib data pub fn zlib_extractor() -> Extractor { Extractor { @@ -17,8 +20,6 @@ pub fn zlib_decompress( ) -> ExtractionResult { // Size of the zlib header const HEADER_SIZE: usize = 2; - // Size of the checksum that follows the deflate data stream - const CHECKSUM_SIZE: usize = 4; // Do the decompression, ignoring the ZLIB header let mut result = diff --git a/src/main.rs b/src/main.rs index 65db04e52..69d78d45a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -95,6 +95,7 @@ fn main() { cliargs.include, cliargs.exclude, None, + cliargs.search_all, ) .expect("Binwalk initialization failed"); diff --git a/src/signatures/compressd.rs b/src/signatures/compressd.rs index b3ca915ea..66e8ae003 100644 --- a/src/signatures/compressd.rs +++ b/src/signatures/compressd.rs @@ -1,4 +1,6 @@ -use crate::signatures::common::{SignatureError, SignatureResult, CONFIDENCE_MEDIUM}; +use crate::signatures::common::{ + SignatureError, SignatureResult, CONFIDENCE_LOW, CONFIDENCE_MEDIUM, +}; /// Human readable description pub const DESCRIPTION: &str = "compress'd data"; @@ -14,17 +16,16 @@ pub fn compressd_parser( offset: usize, ) -> Result { // Successful return value; confidence is medium since this only matches magic bytes at the beginning of a file - let result = SignatureResult { + let mut result = SignatureResult { offset, description: DESCRIPTION.to_string(), - confidence: CONFIDENCE_MEDIUM, + confidence: CONFIDENCE_LOW, ..Default::default() }; - // This is enforced in magic.rs so this check is superfluous if offset == 0 { - return Ok(result); + result.confidence = CONFIDENCE_MEDIUM; } - Err(SignatureError) + Ok(result) } diff --git a/src/signatures/fat.rs b/src/signatures/fat.rs index 4aa91ca66..2e77b8f92 100644 --- a/src/signatures/fat.rs +++ b/src/signatures/fat.rs @@ -21,8 +21,8 @@ pub fn fat_parser(file_data: &[u8], offset: usize) -> Result= MAGIC_OFFSET { // FAT actually starts this may bytes before the magic bytes result.offset = offset - MAGIC_OFFSET; diff --git a/src/signatures/gpg.rs b/src/signatures/gpg.rs index 223e6bda4..001044773 100644 --- a/src/signatures/gpg.rs +++ b/src/signatures/gpg.rs @@ -1,4 +1,4 @@ -use crate::extractors::zlib::zlib_decompress; +use crate::extractors::zlib::{zlib_decompress, CHECKSUM_SIZE}; use crate::signatures::common::{SignatureError, SignatureResult, CONFIDENCE_HIGH}; /// Human readable description @@ -15,23 +15,26 @@ pub fn gpg_signed_parser( offset: usize, ) -> Result { // Success result; confidence is high since this signature is only reported what it starts at the beginning of a file - let result = SignatureResult { + let mut result = SignatureResult { offset, confidence: CONFIDENCE_HIGH, description: GPG_SIGNED_DESCRIPTION.to_string(), ..Default::default() }; - // This is enforced in magic.rs so this check is supurfulous - if offset == 0 { - /* - * GPG signed files are just zlib compressed files with the zlib magic bytes replaced with the GPG magic bytes. - * Decompress the signed file; no output directory specified, dry run only. - */ - let decompression_dry_run = zlib_decompress(file_data, offset, None); + /* + * GPG signed files are just zlib compressed files with the zlib magic bytes replaced with the GPG magic bytes. + * Decompress the signed file; no output directory specified, dry run only. + */ + let decompression_dry_run = zlib_decompress(file_data, offset, None); - // If the decompression dry run was a success, this signature is almost certianly valid - if decompression_dry_run.success { + // If the decompression dry run was a success, this signature is almost certianly valid + if decompression_dry_run.success { + if let Some(total_size) = decompression_dry_run.size { + // GPG doesn't include the trailing checksum + result.size = total_size - CHECKSUM_SIZE; + result.description = + format!("{}, total size: {} bytes", result.description, result.size); return Ok(result); } } diff --git a/src/signatures/zlib.rs b/src/signatures/zlib.rs index 171fb74cc..294d6532b 100644 --- a/src/signatures/zlib.rs +++ b/src/signatures/zlib.rs @@ -22,19 +22,16 @@ pub fn zlib_parser(file_data: &[u8], offset: usize) -> Result