-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #733 from ReFirmLabs/dahua_zip
Added support for Dahua ZIP archives
- Loading branch information
Showing
7 changed files
with
125 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
use crate::extractors::common::{Chroot, ExtractionResult, Extractor, ExtractorType}; | ||
use crate::signatures::zip::find_zip_eof; | ||
|
||
/// Defines the internal extractor function for carving Dahua ZIP files | ||
/// | ||
/// ``` | ||
/// use std::io::ErrorKind; | ||
/// use std::process::Command; | ||
/// use binwalk::extractors::common::ExtractorType; | ||
/// use binwalk::extractors::dahua_zip::dahua_zip_extractor; | ||
/// | ||
/// match dahua_zip_extractor().utility { | ||
/// ExtractorType::None => panic!("Invalid extractor type of None"), | ||
/// ExtractorType::Internal(func) => println!("Internal extractor OK: {:?}", func), | ||
/// ExtractorType::External(cmd) => { | ||
/// if let Err(e) = Command::new(&cmd).output() { | ||
/// if e.kind() == ErrorKind::NotFound { | ||
/// panic!("External extractor '{}' not found", cmd); | ||
/// } else { | ||
/// panic!("Failed to execute external extractor '{}': {}", cmd, e); | ||
/// } | ||
/// } | ||
/// } | ||
/// } | ||
/// ``` | ||
pub fn dahua_zip_extractor() -> Extractor { | ||
Extractor { | ||
utility: ExtractorType::Internal(extract_dahua_zip), | ||
..Default::default() | ||
} | ||
} | ||
|
||
/// Carves out a Dahua ZIP file and converts it to a normal ZIP file | ||
pub fn extract_dahua_zip( | ||
file_data: &[u8], | ||
offset: usize, | ||
output_directory: Option<&String>, | ||
) -> ExtractionResult { | ||
const OUTFILE_NAME: &str = "dahua.zip"; | ||
const ZIP_HEADER: &[u8] = b"PK"; | ||
|
||
let mut result = ExtractionResult { | ||
..Default::default() | ||
}; | ||
|
||
// Locate the end of the zip archive | ||
if let Ok(zip_info) = find_zip_eof(file_data, offset) { | ||
// Calculate total size of the zip archive, report success | ||
result.size = Some(zip_info.eof - offset); | ||
result.success = true; | ||
|
||
// If extraction was requested, carve the zip archive to disk, replacing the Dahua ZIP magic bytes | ||
// with the standard ZIP magic bytes. | ||
if output_directory.is_some() { | ||
// Start and end offsets of the data to carve | ||
let start_data = offset + ZIP_HEADER.len(); | ||
let end_data = offset + result.size.unwrap(); | ||
|
||
let chroot = Chroot::new(output_directory); | ||
|
||
// Get the data to carve | ||
match file_data.get(start_data..end_data) { | ||
None => { | ||
result.success = false; | ||
} | ||
Some(zip_data) => { | ||
// First write the normal ZIP header magic bytes to disk | ||
if !chroot.create_file(OUTFILE_NAME, ZIP_HEADER) { | ||
result.success = false; | ||
} else { | ||
// Append the rest of the ZIP archive to disk | ||
result.success = chroot.append_to_file(OUTFILE_NAME, zip_data); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
result | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
use crate::signatures::common::{SignatureError, SignatureResult}; | ||
use crate::signatures::zip; | ||
|
||
/// Human readable description | ||
pub const DESCRIPTION: &str = "Dahua ZIP archive"; | ||
|
||
/// Dahua ZIP file entry magic bytes | ||
pub fn dahua_zip_magic() -> Vec<Vec<u8>> { | ||
// The first ZIP file entry in the Dahua ZIP file is has "DH" instead of "PK". | ||
// Otherwise, it is a normal ZIP file. | ||
vec![b"DH\x03\x04".to_vec()] | ||
} | ||
|
||
/// Validates a Dahua ZIP file entry signature | ||
pub fn dahua_zip_parser( | ||
file_data: &[u8], | ||
offset: usize, | ||
) -> Result<SignatureResult, SignatureError> { | ||
// Parse & validate the Dahua ZIP file like a normal ZIP file | ||
if let Ok(mut result) = zip::zip_parser(file_data, offset) { | ||
// Replace the normal ZIP description string with our description string | ||
result.description = result.description.replace(zip::DESCRIPTION, DESCRIPTION); | ||
return Ok(result); | ||
} | ||
|
||
Err(SignatureError) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters