Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ description = "Analyzes data for embedded file types"
keywords = ["binwalk", "firmware", "analysis"]

[dependencies]
ar = "0.9"
log = "0.4.22"
base64 = "0.22.1"
chrono = "0.4.38"
Expand All @@ -29,7 +30,7 @@ adler32 = "1.2.0"
md5 = "0.7.0"
miniz_oxide = "0.8.0"
aho-corasick = "1.1.3"
serde = { version = "1.0", features = ["derive"]}
serde = { version = "1.0", features = ["derive"] }
clap = { version = "4.5.16", features = ["derive"] }
xxhash-rust = { version = "0.8.12", features = ["xxh32"] }
hex = "0.4.3"
Expand Down
1 change: 1 addition & 0 deletions src/extractors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@

pub mod androidsparse;
pub mod apfs;
pub mod ar;
pub mod arcadyan;
pub mod autel;
pub mod bmp;
Expand Down
63 changes: 63 additions & 0 deletions src/extractors/ar.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
use std::io::{Cursor, Read};

use crate::extractors::{
self,
common::{Chroot, ExtractionResult},
};

/// Describes how to run the ar utility to extract GNU/BSD/DEB archives
///
/// ```
/// use std::io::ErrorKind;
/// use std::process::Command;
/// use binwalk::extractors::common::ExtractorType;
/// use binwalk::extractors::deb::deb_extractor;
///
/// match ar_extractor().utility {
/// ExtractorType::Internal(func) => func(file_data, offset, Some(output_directory)),
/// _ => unreachable!("Invalid extractor type"),
/// }
/// ```
pub fn ar_extractor() -> extractors::common::Extractor {
extractors::common::Extractor {
utility: extractors::common::ExtractorType::Internal(extract_ar_file),
extension: "deb".to_string(),
do_not_recurse: false,
..Default::default()
}
}

pub fn extract_ar_file(
file_data: &[u8],
offset: usize,
output_directory: Option<&str>,
) -> ExtractionResult {
let mut result = ExtractionResult {
success: true,
size: Some(0),
do_not_recurse: false,
..Default::default()
};

let mut reader = Cursor::new(file_data);
reader.set_position(offset as u64);
let mut archive = ar::Archive::new(reader);
while let Some(entry_result) = archive.next_entry() {
if let Ok(mut entry) = entry_result {
if !output_directory.is_none() {
let chroot = Chroot::new(output_directory);

// it would be nicer if Chroot::create_file were to take a impl Cursor<u8> instead
// of a Vec<u8>, then we would use less memory:
let mut data = vec![];
if let Ok(size) = entry.read_to_end(&mut data) {
result.size.as_mut().map(|x| *x += size);
result.success &= chroot
.create_file(String::from_utf8_lossy(entry.header().identifier()), &data);
}
}
}
}

result
}
2 changes: 1 addition & 1 deletion src/magic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub fn patterns() -> Vec<signatures::common::Signature> {
magic: signatures::deb::deb_magic(),
parser: signatures::deb::deb_parser,
description: signatures::deb::DESCRIPTION.to_string(),
extractor: None,
extractor: Some(extractors::ar::ar_extractor()),
},
// 7-zip
signatures::common::Signature {
Expand Down