diff --git a/src/formats/mtk_bdp.rs b/src/formats/mtk_bdp.rs index b8c611a..b9cff1e 100644 --- a/src/formats/mtk_bdp.rs +++ b/src/formats/mtk_bdp.rs @@ -3,9 +3,14 @@ use std::path::{Path}; use std::fs::{self, OpenOptions}; use std::io::{Seek, SeekFrom, Read, Write}; use binrw::{BinRead, BinReaderExt}; -use std::sync::OnceLock; use crate::utils::common; +pub struct MtkBdpContext { + pitit_offset: u64, +} + +static PITIT_MAGIC: [u8; 8] = [0x69, 0x54, 0x49, 0x50, 0x69, 0x54, 0x49, 0x50]; +static PITIT_END_MARKER: u32 = 0x69_54_49_50; //PITi - end marker of PITIT #[derive(BinRead)] struct PITITPITEntry { @@ -32,6 +37,8 @@ struct PITHeader { entry_count: u32, } +static PIT_MAGIC: [u8; 8] = [0xDC, 0xEA, 0x30, 0x85, 0xDC, 0xEA, 0x30, 0x85]; + #[derive(BinRead)] struct PITEntry { #[br(count = 16)] name_bytes: Vec, @@ -56,36 +63,35 @@ struct BITEntry { _unknown: u32, } -static PITIT_MAGIC: [u8; 8] = [0x69, 0x54, 0x49, 0x50, 0x69, 0x54, 0x49, 0x50]; -static PITIT_OFFSET: OnceLock = OnceLock::new(); +static BIT_MAGIC: [u8; 20] = [0xCD, 0xAB, 0x30, 0x85, 0xCD, 0xAB, 0x30, 0x85, 0xCD, 0xAB, 0x30, 0x85, 0xCD, 0xAB, 0x30, 0x85, 0xCD, 0xAB, 0x30, 0x85]; +static BIT_END_MARKER: u32 = 0x85_30_EF_EF; //EF EF 30 85 - end marker of BIT fn find_bytes(data: &[u8], pattern: &[u8]) -> Option { data.windows(pattern.len()).position(|window| window == pattern) } -pub fn is_mtk_bdp_file(mut file: &File) -> bool { - let file_size = file.metadata().expect("REASON").len(); +pub fn is_mtk_bdp_file(mut file: &File) -> Result, Box> { + let file_size = file.metadata()?.len(); let mut data = Vec::new(); // I wish there was a better way let start_offset = file_size.saturating_sub(file_size / 20); let _ = file.seek(SeekFrom::Start(start_offset)); - file.read_to_end(&mut data).expect("Failed to read from file."); + file.read_to_end(&mut data)?; if let Some(pos) = find_bytes(&data, &PITIT_MAGIC) { - PITIT_OFFSET.set(start_offset as usize + pos).unwrap(); - true + Ok(Some(MtkBdpContext {pitit_offset: start_offset + pos as u64})) } else { - false + Ok(None) } } -pub fn extract_mtk_bdp(mut file: &File, output_folder: &str) -> Result<(), Box> { - let offset = PITIT_OFFSET.get().unwrap(); +pub fn extract_mtk_bdp(mut file: &File, output_folder: &str, context: MtkBdpContext) -> Result<(), Box> { + let offset = context.pitit_offset; println!("\nReading PITIT at: {}", offset); - file.seek(SeekFrom::Start(*offset as u64 + 8))?; + file.seek(SeekFrom::Start(offset + 8))?; let pitit_check = common::read_exact(&mut file, 8)?; //{UPG_INFO}the upg bin is %d version(old is 0,new is 1)!\n @@ -95,7 +101,7 @@ pub fn extract_mtk_bdp(mut file: &File, output_folder: &str) -> Result<(), Box Result<(), Box = Vec::new(); let pit_header: PITHeader = file.read_le()?; - if pit_header.pit_magic != b"\xDC\xEA\x30\x85\xDC\xEA\x30\x85" { + if pit_header.pit_magic != PIT_MAGIC { println!("Invalid PIT Magic!"); return Ok(()); } @@ -135,7 +141,7 @@ pub fn extract_mtk_bdp(mut file: &File, output_folder: &str) -> Result<(), Box = Vec::new(); let bit_magic = common::read_exact(&mut file, 20)?; - if bit_magic != b"\xCD\xAB\x30\x85\xCD\xAB\x30\x85\xCD\xAB\x30\x85\xCD\xAB\x30\x85\xCD\xAB\x30\x85" { + if bit_magic != BIT_MAGIC { println!("Invalid BIT Magic!"); return Ok(()); } @@ -143,7 +149,7 @@ pub fn extract_mtk_bdp(mut file: &File, output_folder: &str) -> Result<(), Box, +} + #[derive(BinRead)] struct Header { #[br(count = 4)] vendor_magic_bytes: Vec, @@ -52,6 +57,17 @@ impl PartEntry { } } +pub static MTK_HEADER_MAGIC: &[u8; 8] = b"#DH@FiRm"; +pub static MTK_RESERVED_MAGIC: &[u8; 16] = b"reserved mtk inc"; +pub static MTK_META_MAGIC: &[u8; 4] = b"iMtK"; +pub static MTK_META_PAD_MAGIC: &[u8; 4] = b"iPAd"; +pub static CRYPTED_HEADER_SIZE: usize = 0x30; + +static HEADER_SIZE: usize = 0x90; + +static PHILIPS_EXTRA_HEADER_SIZE: usize = 0x80; +static _PHILIPS_FOOTER_SIGNATURE_SIZE: usize = 0x100; + static HEADER_KEY: [u8; 16] = [ 0x09, 0x29, 0x10, 0x94, 0x09, 0x29, 0x10, 0x94, 0x09, 0x29, 0x10, 0x94, 0x09, 0x29, 0x10, 0x94, @@ -59,34 +75,39 @@ static HEADER_KEY: [u8; 16] = [ static HEADER_IV: [u8; 16] = [0x00; 16]; -pub fn is_mtk_pkg_file(file: &File) -> bool { - let mut encrypted_header = common::read_file(&file, 0, 144).expect("Failed to read from file."); - let mut header = decrypt_aes128_cbc_nopad(&encrypted_header, &HEADER_KEY, &HEADER_IV).expect("Decryption error!"); - if &header[4..12] == b"#DH@FiRm" { - true +pub fn is_mtk_pkg_file(file: &File) -> Result, Box> { + let mut encrypted_header = common::read_file(&file, 0, HEADER_SIZE)?; + let mut header = decrypt_aes128_cbc_nopad(&encrypted_header, &HEADER_KEY, &HEADER_IV)?; + if &header[4..12] == MTK_HEADER_MAGIC { + Ok(Some(MtkPkgContext { is_philips_variant: false, decrypted_header: header})) } else { // try for philips which has additional 128 bytes at beginning - encrypted_header = common::read_file(&file, 128, 144).expect("Failed to read from file."); - header = decrypt_aes128_cbc_nopad(&encrypted_header, &HEADER_KEY, &HEADER_IV).expect("Decryption error!"); - if &header[4..12] == b"#DH@FiRm" { - true + encrypted_header = common::read_file(&file, PHILIPS_EXTRA_HEADER_SIZE as u64, HEADER_SIZE)?; + header = decrypt_aes128_cbc_nopad(&encrypted_header, &HEADER_KEY, &HEADER_IV)?; + if &header[4..12] == MTK_HEADER_MAGIC { + Ok(Some(MtkPkgContext { is_philips_variant: true, decrypted_header: header })) } else { - false + Ok(None) } } } -pub fn extract_mtk_pkg(mut file: &File, output_folder: &str) -> Result<(), Box> { +pub fn extract_mtk_pkg(mut file: &File, output_folder: &str, context: MtkPkgContext) -> Result<(), Box> { let file_size = file.metadata()?.len(); - let encrypted_header = common::read_exact(&mut file, 144)?; - let header = decrypt_aes128_cbc_nopad(&encrypted_header, &HEADER_KEY, &HEADER_IV)?; + let header = context.decrypted_header; let mut hdr_reader = Cursor::new(header); let hdr: Header = hdr_reader.read_le()?; println!("File info:\nFile size: {}\nVendor magic: {}\nVersion info: {}\nProduct name: {}" , hdr.file_size, hdr.vendor_magic(), hdr.version(), hdr.product_name()); + if context.is_philips_variant { + file.seek(SeekFrom::Start(HEADER_SIZE as u64 + PHILIPS_EXTRA_HEADER_SIZE as u64))?; + } else { + file.seek(SeekFrom::Start(HEADER_SIZE as u64))?; + } + let mut part_n = 0; while file.stream_position()? < file_size as u64 { part_n += 1; @@ -96,7 +117,7 @@ pub fn extract_mtk_pkg(mut file: &File, output_folder: &str) -> Result<(), Box Result<(), Box = None; let mut matching_iv: Option<[u8; 16]> = None; - let crypted_header = &data[..48]; + let crypted_header = &data[..CRYPTED_HEADER_SIZE]; // try decrypting with vendor magic repeated 4 times (works for most) let mut key = [0u8; 16]; @@ -116,7 +137,7 @@ pub fn extract_mtk_pkg(mut file: &File, output_folder: &str) -> Result<(), Box Result<(), Box Result<(), Box Result<(), Box, +} + #[derive(BinRead)] struct Header { #[br(count = 4)] vendor_magic_bytes: Vec, @@ -53,45 +62,36 @@ impl PartEntry { } } -pub fn is_mtk_pkg_new_file(file: &File) -> bool { - let encrypted_header = common::read_file(&file, 0, 112).expect("Failed to read from file."); - for (key_hex, iv_hex, _name) in keys::MTK_PKG_CUST { - let key_array: [u8; 16] = hex::decode(key_hex).expect("Error").as_slice().try_into().expect("Error"); - let iv_array: [u8; 16] = hex::decode(iv_hex).expect("Error").as_slice().try_into().expect("Error"); - let try_decrypt = decrypt_aes128_cbc_nopad(&encrypted_header, &key_array, &iv_array).expect("Failed to decrypt."); +static HEADER_SIZE: usize = 0x170; - if &try_decrypt[4..12] == b"#DH@FiRm" { - return true; +pub fn is_mtk_pkg_new_file(file: &File) -> Result, Box> { + let encrypted_header = common::read_file(&file, 0, HEADER_SIZE)?; + for (key_hex, iv_hex, name) in keys::MTK_PKG_CUST { + let key_array: [u8; 16] = hex::decode(key_hex)?.as_slice().try_into()?; + let iv_array: [u8; 16] = hex::decode(iv_hex)?.as_slice().try_into()?; + let try_decrypt = decrypt_aes128_cbc_nopad(&encrypted_header, &key_array, &iv_array)?; + + if &try_decrypt[4..12] == MTK_HEADER_MAGIC { + return Ok(Some(MtkPkgNewContext { + matching_key_name: name.to_string(), + matching_key_key: key_array, + matching_key_iv: iv_array, + decrypted_header: try_decrypt + })); } } - false + Ok(None) } -pub fn extract_mtk_pkg_new(mut file: &File, output_folder: &str) -> Result<(), Box> { +pub fn extract_mtk_pkg_new(mut file: &File, output_folder: &str, context: MtkPkgNewContext) -> Result<(), Box> { let file_size = file.metadata()?.len(); - let encrypted_header = common::read_exact(&mut file, 368)?; - let mut header = Vec::new(); - let mut matching_key: Option<[u8; 16]> = None; - let mut matching_iv: Option<[u8; 16]> = None; - //find key, the header and data key will be the same - for (key_hex, iv_hex, name) in keys::MTK_PKG_CUST { - let key_array = hex::decode(key_hex)?.as_slice().try_into()?; - let iv_array = hex::decode(iv_hex)?.as_slice().try_into()?; - header = decrypt_aes128_cbc_nopad(&encrypted_header, &key_array, &iv_array)?; - - if &header[4..12] == b"#DH@FiRm" { - println!("Using key {}", name); - matching_key = Some(key_array); - matching_iv = Some(iv_array); - break - } - } - if matching_key.is_none() && matching_iv.is_none() { - println!("Failed to find key!"); - return Ok(()) - } + //the key was founf, and header was decrypted at detection stage so we can reuse + println!("Using key {}", context.matching_key_name); + let key_array = context.matching_key_key; + let iv_array = context.matching_key_iv; + let header = context.decrypted_header; let mut hdr_reader = Cursor::new(header); let hdr: Header = hdr_reader.read_le()?; @@ -99,6 +99,8 @@ pub fn extract_mtk_pkg_new(mut file: &File, output_folder: &str) -> Result<(), B println!("File info:\nFile size: {}\nVendor magic: {}\nVersion info: {}\nProduct name: {}" , hdr.file_size, hdr.vendor_magic(), hdr.version(), hdr.product_name()); + file.seek(SeekFrom::Start(HEADER_SIZE as u64))?; + let mut part_n = 0; while file.stream_position()? < file_size as u64 { part_n += 1; @@ -120,7 +122,6 @@ pub fn extract_mtk_pkg_new(mut file: &File, output_folder: &str) -> Result<(), B let mut out_data; if part_entry.is_encrypted() { println!("- Decrypting..."); - let (key_array, iv_array) = (matching_key.unwrap(), matching_iv.unwrap()); //data aligned to 16 bytes is AES encrypted. the remaining unaligned data is XORed with the key let align_len = data.len() & !15; let (aes_enc, xor_tail) = data.split_at(align_len); @@ -133,9 +134,9 @@ pub fn extract_mtk_pkg_new(mut file: &File, output_folder: &str) -> Result<(), B } //strip iMtK thing and get version - let extra_header_len = if &out_data[48..52] == b"iMtK" { + let extra_header_len = if &out_data[48..52] == MTK_META_MAGIC { let imtk_len = u32::from_le_bytes(out_data[52..56].try_into().unwrap()); - if &out_data[56..60] != b"iPAd" { + if &out_data[56..60] != MTK_META_PAD_MAGIC { let version_len = u32::from_le_bytes(out_data[56..60].try_into().unwrap()); let version = common::string_from_bytes(&out_data[60..60 + version_len as usize]); println!("- Version: {}", version); diff --git a/src/formats/mtk_pkg_old.rs b/src/formats/mtk_pkg_old.rs index bf23036..a03231f 100644 --- a/src/formats/mtk_pkg_old.rs +++ b/src/formats/mtk_pkg_old.rs @@ -12,6 +12,8 @@ static KEY: u32 = 0x94102909; //09 29 10 94 static HEADER_XOR_MASK: u32 = 0x04BE7C75; //75 7C BE 04 static CONTENT_XOR_MASK: u32 = 0x04BE7C72; //72 7C BE 04 +use crate::formats::mtk_pkg::{MTK_HEADER_MAGIC, MTK_META_MAGIC, MTK_META_PAD_MAGIC}; + #[derive(BinRead)] struct Header { #[br(count = 4)] vendor_magic_bytes: Vec, @@ -53,16 +55,18 @@ impl PartEntry { } } +static HEADER_SIZE: usize = 0x98; + pub fn is_mtk_pkg_old_file(mut file: &File) -> bool { - let encrypted_header = common::read_file(&file, 0, 152).expect("Failed to read from file."); + let encrypted_header = common::read_file(&file, 0, HEADER_SIZE).expect("Failed to read from file."); let header = decrypt(&encrypted_header, KEY, Some(HEADER_XOR_MASK)); - if &header[4..12] == b"#DH@FiRm" { + if &header[4..12] == MTK_HEADER_MAGIC { true - } else if &header[68..76] == b"#DH@FiRm" { + } else if &header[68..76] == MTK_HEADER_MAGIC { //check for 64 byte additional header used in some Sony and Philips firmwares and skip it file.seek(std::io::SeekFrom::Start(64)).expect("Failed to seek"); true - } else if &header[132..140] == b"#DH@FiRm" { + } else if &header[132..140] == MTK_HEADER_MAGIC { //check for 128 byte additional header used in some Philips firmwares and skip it file.seek(std::io::SeekFrom::Start(128)).expect("Failed to seek"); true @@ -73,7 +77,7 @@ pub fn is_mtk_pkg_old_file(mut file: &File) -> bool { pub fn extract_mtk_pkg_old(mut file: &File, output_folder: &str) -> Result<(), Box> { let file_size = file.metadata()?.len(); - let encrypted_header = common::read_exact(&mut file, 152)?; + let encrypted_header = common::read_exact(&mut file, HEADER_SIZE)?; let header = decrypt(&encrypted_header, KEY, Some(HEADER_XOR_MASK)); let mut hdr_reader = Cursor::new(header); let hdr: Header = hdr_reader.read_le()?; @@ -101,9 +105,9 @@ pub fn extract_mtk_pkg_old(mut file: &File, output_folder: &str) -> Result<(), B } //strip iMtK thing and get version - let extra_header_len = if &out_data[0..4] == b"iMtK" { + let extra_header_len = if &out_data[0..4] == MTK_META_MAGIC { let imtk_len = u32::from_le_bytes(out_data[4..8].try_into().unwrap()); - if &out_data[8..12] != b"iPAd" { + if &out_data[8..12] != MTK_META_PAD_MAGIC { let version_len = u32::from_le_bytes(out_data[8..12].try_into().unwrap()); let version = common::string_from_bytes(&out_data[12..12 + version_len as usize]); println!("- Version: {}", version); diff --git a/src/formats/pana_dvd.rs b/src/formats/pana_dvd.rs index a86b2d4..8985ba4 100644 --- a/src/formats/pana_dvd.rs +++ b/src/formats/pana_dvd.rs @@ -11,6 +11,14 @@ use crate::utils::aes::{decrypt_aes128_cbc_nopad}; use crate::utils::compression::{decompress_gzip}; use crate::utils::lzss::{decompress_lzss}; +pub struct PanaDvdContext { + matching_key: [u8; 8], + base_hdr_size: u32, + is_aes: bool, + aes_key: Option<[u8; 16]>, + aes_iv: Option<[u8; 16]> +} + #[derive(BinRead)] struct AesHeaderFileEntry { offset: u32, @@ -104,6 +112,8 @@ impl MainEntryHeader { } } +static MAX_HEADER_SIZE: usize = 0x2000; + pub fn find_key<'a>(key_array: &'a [&'a str], data: &[u8], expected_magic: &[u8], magic_offset: usize) -> Result, Box> { for key_hex in key_array { let key_bytes = hex::decode(key_hex)?; @@ -134,75 +144,77 @@ pub fn find_aes_key_pair<'a>(key_array: &'a [(&'a str, &'a str, &'a str)], data: Ok(None) } -pub fn is_pana_dvd_file(file: &File) -> bool { - let header = common::read_file(&file, 0, 64).expect("Failed to read from file."); - if header.starts_with(b"PANASONIC\x00\x00\x00") { - true - } else if find_key(&keys::PANA_DVD_KEYONLY, &header, b"PROG", 0).expect("Failed to decrypt header.").is_some() { - true - } else if find_aes_key_pair(&keys::PANA_DVD_AESPAIR, &header, b"PANASONIC", 32).expect("Failed to decrypt header.").is_some() { - true +pub fn is_pana_dvd_file(file: &File) -> Result, Box> { + let header = common::read_file(&file, 0, 64)?; + if let Some(matching_key) = find_key(&keys::PANA_DVD_KEYONLY, &header, b"PROG", 0)? { + Ok(Some(PanaDvdContext { + matching_key: matching_key, + base_hdr_size: 0, + is_aes: false, + aes_key: None, + aes_iv: None, + })) + } else if header.starts_with(b"PANASONIC\x00\x00\x00") && let Some(matching_key) = find_key(&keys::PANA_DVD_KEYONLY, &header, b"PROG", 48)? { + Ok(Some(PanaDvdContext { + matching_key: matching_key, + base_hdr_size: 48, + is_aes: false, + aes_key: None, + aes_iv: None, + })) + } else if let Some((aes_key, aes_iv, matching_key)) = find_aes_key_pair(&keys::PANA_DVD_AESPAIR, &header, b"PANASONIC", 32)? { + Ok(Some(PanaDvdContext { + matching_key: matching_key, + base_hdr_size: 48, + is_aes: true, + aes_key: Some(aes_key), + aes_iv: Some(aes_iv), + })) } else { - false + Ok(None) } } -pub fn extract_pana_dvd(mut file: &File, output_folder: &str) -> Result<(), Box> { +pub fn extract_pana_dvd(mut file: &File, output_folder: &str, context: PanaDvdContext) -> Result<(), Box> { let mut data = Vec::new(); // we need to load the entire file into memory so we can swap it with AES decrypted data if its AES encrypted file.read_to_end(&mut data)?; let mut file_reader = Cursor::new(data); - let enc_header_s = common::read_exact(&mut file_reader, 64)?; - let matching_key; + + let matching_key = context.matching_key; let mut file_entries: Vec = Vec::new(); - // (custom enc) find the key, knowing that the first entry is always "PROG" (offset 0) - if let Some(key_array) = find_key(&keys::PANA_DVD_KEYONLY, &enc_header_s, b"PROG", 0)? { - println!("Found valid key: {}\n", hex::encode_upper(key_array)); - matching_key = Some(key_array); - file_entries.push(FileEntry { offset: 0, base_offset: 0 }) - - // (custom enc) find the key, knowing that the first entry is always "PROG" (offset 48) - } else if let Some(key_array) = find_key(&keys::PANA_DVD_KEYONLY, &enc_header_s, b"PROG", 48)? { - println!("Found valid key: {}\n", hex::encode_upper(key_array)); - matching_key = Some(key_array); - file_entries.push(FileEntry { offset: 0, base_offset: 48 }) - - // (aes) find the key using PANASONIC magic - } else if let Some((aes_key, aes_iv, key_array)) = find_aes_key_pair(&keys::PANA_DVD_AESPAIR, &enc_header_s, b"PANASONIC", 32)? { - println!("Found AES key pair: aes={} iv={} cust={}", hex::encode_upper(aes_key), hex::encode_upper(aes_iv), hex::encode_upper(key_array)); - matching_key = Some(key_array); - + if context.is_aes { + let (aes_key, aes_iv) = (context.aes_key.unwrap(), context.aes_iv.unwrap()); + println!("Using key: {} + AES key: {}, IV: {}", hex::encode_upper(matching_key), hex::encode_upper(aes_key), hex::encode_upper(aes_iv)); println!("Decrypting AES...\n"); let aes_decrypted = decrypt_aes128_cbc_nopad(&file_reader.get_ref(), &aes_key, &aes_iv)?; file_reader = Cursor::new(aes_decrypted); //set the file reader to use AES decrypted stream //read file entries in extra header let file_table = common::read_exact(&mut file_reader, 48)?; - let mut file_table_reader = Cursor::new(decrypt_data(&file_table, &key_array)); + let mut file_table_reader = Cursor::new(decrypt_data(&file_table, &matching_key)); for _i in 0..4 { let file_entry: AesHeaderFileEntry = file_table_reader.read_le()?; if file_entry.size == 0 && file_entry.offset == 0 { break } - file_entries.push(FileEntry { offset: file_entry.offset, base_offset: 48 }); + file_entries.push(FileEntry { offset: file_entry.offset, base_offset: context.base_hdr_size }); } } else { - println!("\nNo valid key found!"); - return Ok(()); + println!("Using key: {}", hex::encode_upper(matching_key)); + file_entries.push(FileEntry { offset: 0, base_offset: context.base_hdr_size }); } - let matching_key_array = matching_key.unwrap(); - if file_entries.len() == 1 { //only one file, standard extraction - println!("File contains no extra sub-files..."); - extract_file(&mut file_reader, file_entries[0].offset as u64, file_entries[0].base_offset as u64, matching_key_array, output_folder)?; + println!("File contains no extra sub-files...\n"); + extract_file(&mut file_reader, file_entries[0].offset as u64, file_entries[0].base_offset as u64, matching_key, output_folder)?; } else { println!("File contains {} sub-files...", file_entries.len()); for (i, file_entry ) in file_entries.iter().enumerate() { println!("\nExtracting file {}/{} - Offset: {}, base: {}", i + 1, file_entries.len(), file_entry.offset, file_entry.base_offset); - extract_file(&mut file_reader, file_entry.offset as u64, file_entry.base_offset as u64, matching_key_array, &format!("{}/file_{}", output_folder, i + 1))?; + extract_file(&mut file_reader, file_entry.offset as u64, file_entry.base_offset as u64, matching_key, &format!("{}/file_{}", output_folder, i + 1))?; } } @@ -214,7 +226,7 @@ pub fn extract_pana_dvd(mut file: &File, output_folder: &str) -> Result<(), Box< fn extract_file(file_reader: &mut Cursor>, offset: u64, base_offset: u64, key: [u8; 8], output_folder: &str) -> Result<(), Box> { file_reader.seek(SeekFrom::Start(offset + base_offset))?; - let enc_header = common::read_exact(file_reader, 8192)?; + let enc_header = common::read_exact(file_reader, MAX_HEADER_SIZE)?; let mut hdr_reader = Cursor::new(decrypt_data(&enc_header, &key)); let mut modules: Vec = Vec::new(); diff --git a/src/formats/sony_bdp.rs b/src/formats/sony_bdp.rs index 237a7bf..e3e5033 100644 --- a/src/formats/sony_bdp.rs +++ b/src/formats/sony_bdp.rs @@ -111,10 +111,10 @@ pub fn extract_sony_bdp(mut file: &File, output_folder: &str) -> Result<(), Box< if last_file_path.is_some() { println!("\nChecking if it's also MTK BDP..."); let last_file = File::open(last_file_path.unwrap())?; - if formats::mtk_bdp::is_mtk_bdp_file(&last_file) { + if let Some(result) = formats::mtk_bdp::is_mtk_bdp_file(&last_file)? { println!("- MTK BDP file detected!\n"); let mtk_extraction_path = format!("{}/{}", &output_folder, i - 1); - formats::mtk_bdp::extract_mtk_bdp(&last_file, &mtk_extraction_path)?; + formats::mtk_bdp::extract_mtk_bdp(&last_file, &mtk_extraction_path, result)?; } else { println!("- Not an MTK BDP file."); } diff --git a/src/main.rs b/src/main.rs index 642c0cc..5bf66f2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,7 +21,6 @@ fn main() -> Result<(), Box> { println!("Input target: {}", target_path); let path = PathBuf::from(target_path); - let output_path = if args.output_folder.is_some() { args.output_folder.unwrap() } else { @@ -120,9 +119,9 @@ fn main() -> Result<(), Box> { println!("Amlogic image file detected!"); formats::amlogic::extract_amlogic(&file, &output_path)?; } - else if formats::pana_dvd::is_pana_dvd_file(&file) { + else if let Some(result) = formats::pana_dvd::is_pana_dvd_file(&file)? { println!("PANA_DVD file detected!"); - formats::pana_dvd::extract_pana_dvd(&file, &output_path)?; + formats::pana_dvd::extract_pana_dvd(&file, &output_path, result)?; } else if formats::pup::is_pup_file(&file) { println!("PUP file detected!"); @@ -144,21 +143,21 @@ fn main() -> Result<(), Box> { println!("Roku file detected!"); formats::roku::extract_roku(&file, &output_path)?; } - else if formats::mtk_pkg::is_mtk_pkg_file(&file) { + else if let Some(result) = formats::mtk_pkg::is_mtk_pkg_file(&file)? { println!("MTK PKG file detected!"); - formats::mtk_pkg::extract_mtk_pkg(&file, &output_path)?; + formats::mtk_pkg::extract_mtk_pkg(&file, &output_path, result)?; } else if formats::mtk_pkg_old::is_mtk_pkg_old_file(&file) { println!("MTK PKG (Old) file detected!"); formats::mtk_pkg_old::extract_mtk_pkg_old(&file, &output_path)?; } - else if formats::mtk_pkg_new::is_mtk_pkg_new_file(&file) { + else if let Some(result) = formats::mtk_pkg_new::is_mtk_pkg_new_file(&file)? { println!("MTK PKG (New) file detected!"); - formats::mtk_pkg_new::extract_mtk_pkg_new(&file, &output_path)?; + formats::mtk_pkg_new::extract_mtk_pkg_new(&file, &output_path, result)?; } - else if formats::mtk_bdp::is_mtk_bdp_file(&file) { + else if let Some(result) = formats::mtk_bdp::is_mtk_bdp_file(&file)? { println!("MTK BDP file detected!"); - formats::mtk_bdp::extract_mtk_bdp(&file, &output_path)?; + formats::mtk_bdp::extract_mtk_bdp(&file, &output_path, result)?; } else { println!("Input format not recognized!");