-
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 #759 from ReFirmLabs/dlke_firmware
DLKE firmware
- Loading branch information
Showing
7 changed files
with
151 additions
and
9 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,86 @@ | ||
use crate::extractors::common::{Chroot, ExtractionResult, Extractor, ExtractorType}; | ||
use crate::structures::jboot::parse_jboot_arm_header; | ||
|
||
/// Defines the internal extractor function for carving out D-Link TLV firmware images | ||
/// | ||
/// ``` | ||
/// use std::io::ErrorKind; | ||
/// use std::process::Command; | ||
/// use binwalk::extractors::common::ExtractorType; | ||
/// use binwalk::extractors::dlke::dlke_extractor; | ||
/// | ||
/// match dlke_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 dlke_extractor() -> Extractor { | ||
Extractor { | ||
utility: ExtractorType::Internal(extract_dlke_image), | ||
..Default::default() | ||
} | ||
} | ||
|
||
/// Internal extractor for carve pieces of encrypted DLKE firmware images to disk | ||
pub fn extract_dlke_image( | ||
file_data: &[u8], | ||
offset: usize, | ||
output_directory: Option<&String>, | ||
) -> ExtractionResult { | ||
const ENCRYPTED_FILE_NAME: &str = "encrypted.bin"; | ||
const SIGNATURE_FILE_NAME: &str = "signature.bin"; | ||
|
||
let mut result = ExtractionResult { | ||
..Default::default() | ||
}; | ||
|
||
// Parse the first header, which describes the size of the firmware signature | ||
if let Some(dlke_sig_header_data) = file_data.get(offset..) { | ||
if let Ok(dlke_signature_header) = parse_jboot_arm_header(dlke_sig_header_data) { | ||
// Second header should immediately follow the first | ||
if let Some(dlke_crypt_header_data) = file_data | ||
.get(offset + dlke_signature_header.header_size + dlke_signature_header.data_size..) | ||
{ | ||
// Parse the second header, which describes the size of the encrypted data | ||
if let Ok(dlke_crypt_header) = parse_jboot_arm_header(dlke_crypt_header_data) { | ||
result.success = true; | ||
result.size = Some( | ||
dlke_signature_header.header_size | ||
+ dlke_signature_header.data_size | ||
+ dlke_crypt_header.header_size | ||
+ dlke_crypt_header.data_size, | ||
); | ||
|
||
if output_directory.is_some() { | ||
let chroot = Chroot::new(output_directory); | ||
|
||
if !chroot.carve_file( | ||
SIGNATURE_FILE_NAME, | ||
dlke_sig_header_data, | ||
dlke_signature_header.header_size, | ||
dlke_signature_header.data_size, | ||
) || !chroot.carve_file( | ||
ENCRYPTED_FILE_NAME, | ||
dlke_crypt_header_data, | ||
dlke_crypt_header.header_size, | ||
dlke_crypt_header.data_size, | ||
) { | ||
result.success = false; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
use crate::signatures::common::{SignatureError, SignatureResult, CONFIDENCE_HIGH}; | ||
use crate::structures::jboot::parse_jboot_arm_header; | ||
|
||
/// Human readable description | ||
pub const DESCRIPTION: &str = "DLK encrypted firmware"; | ||
|
||
/// DLKE encrypted firmware images always start with these bytes | ||
pub fn dlke_magic() -> Vec<Vec<u8>> { | ||
// These magic bytes are technically the ROM-ID field of a JBOOT header | ||
vec![b"DLK6E8202001".to_vec(), b"DLK6E6110002".to_vec()] | ||
} | ||
|
||
/// Validates the DLKE header | ||
pub fn dlke_parser(file_data: &[u8], offset: usize) -> Result<SignatureResult, SignatureError> { | ||
// Successful return value | ||
let mut result = SignatureResult { | ||
offset, | ||
description: DESCRIPTION.to_string(), | ||
confidence: CONFIDENCE_HIGH, | ||
..Default::default() | ||
}; | ||
|
||
// Parse the first header, which describes the size of the firmware signature | ||
if let Ok(dlke_signature_header) = parse_jboot_arm_header(&file_data[offset..]) { | ||
// Second header should immediately follow the first | ||
if let Some(dlke_crypt_header_data) = file_data | ||
.get(offset + dlke_signature_header.header_size + dlke_signature_header.data_size..) | ||
{ | ||
// Parse the second header, which describes the size of the encrypted data | ||
if let Ok(dlke_crypt_header) = parse_jboot_arm_header(dlke_crypt_header_data) { | ||
result.size = dlke_signature_header.header_size | ||
+ dlke_signature_header.data_size | ||
+ dlke_crypt_header.header_size | ||
+ dlke_crypt_header.data_size; | ||
result.description = format!( | ||
"{}, signature size: {} bytes, encrypted data size: {} bytes", | ||
result.description, | ||
dlke_signature_header.data_size, | ||
dlke_crypt_header.data_size | ||
); | ||
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
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