unify error and success handling in extractors

This commit is contained in:
theubusu
2026-02-17 18:34:46 +01:00
parent aa2249f024
commit 10dd854685
29 changed files with 58 additions and 100 deletions
+1 -3
View File
@@ -32,8 +32,7 @@ pub fn extract_amlogic(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), B
header.image_size, header.item_align_size, header.item_count, header.version);
if header.version != 2 {
println!("\nSorry, this format version is not yet supported!");
return Ok(());
return Err("Unsupported format version! (Only 2 is supported right now)".into());
}
let mut items: Vec<ItemEntry> = Vec::new();
@@ -74,6 +73,5 @@ pub fn extract_amlogic(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), B
}
}
println!("\nExtraction finished!");
Ok(())
}
+1 -4
View File
@@ -32,8 +32,7 @@ pub fn extract_android_ota_payload(app_ctx: &AppContext, _ctx: Box<dyn Any>) ->
println!("File info:\nFormat version: {}\nManifest size: {}", header.file_format_version, header.manifest_size);
if header.file_format_version != 2 {
println!("\nSorry, this version of the file is not supported!");
return Ok(())
return Err("Unsupported format version! (Only 2 is supported right now)".into());
}
let base_offset = 24 /* size of header */ + header.manifest_size + header.metadata_signature_size as u64;
@@ -85,7 +84,5 @@ pub fn extract_android_ota_payload(app_ctx: &AppContext, _ctx: Box<dyn Any>) ->
println!("\n-- Saved!");
}
println!("\nExtraction finished!");
Ok(())
}
-2
View File
@@ -70,7 +70,5 @@ pub fn extract_bdl(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), Box<d
}
}
println!("\nExtraction finished!");
Ok(())
}
+12 -7
View File
@@ -36,8 +36,7 @@ pub fn extract_epk1(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), Box<
println!("\nLittle endian EPK1 detected.");
epk1_type = "le";
} else {
println!("\nUnknown EPK1 variant!");
return Ok(());
return Err("Unknown EPK1 variant!".into());
}
file.seek(SeekFrom::Start(0))?;
@@ -54,7 +53,10 @@ pub fn extract_epk1(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), Box<
}
paks.push(Pak { offset: pak.offset, size: pak.size });
}
assert!(header.pak_count as usize == paks.len(), "Paks count in header({}) does not match the amount of non empty pak entries({})!", header.pak_count, paks.len());
if header.pak_count as usize != paks.len() {
return Err(format!("Paks count in header({}) does not match the amount of non empty pak entries({})!", header.pak_count, paks.len()).into());
}
let version = common::read_exact(&mut file, 4)?;
@@ -68,7 +70,9 @@ pub fn extract_epk1(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), Box<
let header_size_bytes = common::read_file(&file, 12, 4)?; //offset of first entry, can be treated as header size
let header_size = u32::from_le_bytes(header_size_bytes.try_into().unwrap());
let max_pak_count = (header_size - 48) / 8; //header size minus common header + ota id (48) divide by size of pak entry (8).
assert!(max_pak_count < 128, "Unreasonable calculated pak count {}!!", max_pak_count);
if max_pak_count > 128 {
return Err(format!("Unreasonable calculated pak count {}!!", max_pak_count).into());
}
for _i in 0..max_pak_count {
let pak: Pak = file.read_le()?;
@@ -77,7 +81,10 @@ pub fn extract_epk1(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), Box<
}
paks.push(Pak { offset: pak.offset, size: pak.size });
}
assert!(header.pak_count as usize == paks.len(), "Paks count in header({}) does not match the amount of non empty pak entries({})!", header.pak_count, paks.len());
if header.pak_count as usize != paks.len() {
return Err(format!("Paks count in header({}) does not match the amount of non empty pak entries({})!", header.pak_count, paks.len()).into());
}
let version = common::read_exact(&mut file, 4)?;
@@ -104,8 +111,6 @@ pub fn extract_epk1(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), Box<
println!("- Saved file!");
}
println!("\nExtraction finished!");
Ok(())
}
+5 -7
View File
@@ -47,8 +47,7 @@ pub fn extract_epk2(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), Box<
matching_key = Some(key_bytes);
header = decrypt_aes_ecb_auto(matching_key.as_ref().unwrap(), &stored_header)?;
} else {
println!("No valid key found!");
return Ok(());
return Err("No valid key found!".into());
}
}
//parse header
@@ -86,8 +85,7 @@ pub fn extract_epk2(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), Box<
println!("Found correct key: {}", key_name);
matching_key = Some(key_bytes);
} else {
println!("No valid key found!");
return Ok(());
return Err("No valid key found!".into());
}
}
let matching_key_bytes = matching_key.as_ref().unwrap();
@@ -109,7 +107,9 @@ pub fn extract_epk2(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), Box<
pak_header = pak_header_reader.read_le()?;
}
assert!(i == pak_header.segment_index, "Unexpected segment index in pak header!, expected: {}, got: {}", i , pak_header.segment_index);
if i != pak_header.segment_index {
return Err(format!("Unexpected segment index in pak header!, expected: {}, got: {}", i , pak_header.segment_index).into());
}
let actual_segment_size =
// check if this is the last segment and not the last PAK
@@ -144,7 +144,5 @@ pub fn extract_epk2(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), Box<
}
}
println!("\nExtraction finished!");
Ok(())
}
+6 -4
View File
@@ -39,7 +39,9 @@ pub fn extract_epk2b(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), Box
paks.push(Pak { offset: pak.offset, size: pak.size });
}
assert!(header.pak_count as usize == paks.len(), "Paks count in header does not match the amount of non empty pak entries!");
if header.pak_count as usize != paks.len() {
return Err(format!("Paks count in header({}) does not match the amount of non empty pak entries({})!", header.pak_count, paks.len()).into());
}
for (i, pak) in paks.iter().enumerate() {
file.seek(SeekFrom::Start(pak.offset as u64))?;
@@ -56,7 +58,9 @@ pub fn extract_epk2b(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), Box
pak_header = file.read_le()?;
}
assert!(i == pak_header.segment_index, "Unexpected segment index in pak header!, expected: {}, got: {}", i , pak_header.segment_index);
if i != pak_header.segment_index {
return Err(format!("Unexpected segment index in pak header!, expected: {}, got: {}", i , pak_header.segment_index).into());
}
println!("- Segment {}/{} - Size: {}", i + 1, pak_header.segment_count, pak_header.segment_size);
let out_data = common::read_exact(&mut file, pak_header.segment_size as usize)?;
@@ -79,7 +83,5 @@ pub fn extract_epk2b(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), Box
}
}
println!("\nExtraction finished!");
Ok(())
}
+1 -3
View File
@@ -43,8 +43,7 @@ pub fn extract_epk3(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), Box<
new_type = true;
} else {
println!("No valid key found!");
return Ok(());
return Err("No valid key found!".into());
}
let signature_size = if new_type {256} else {128};
@@ -110,6 +109,5 @@ pub fn extract_epk3(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), Box<
pak_i += 1;
}
println!("\nExtraction finished!");
Ok(())
}
+1 -3
View File
@@ -46,8 +46,6 @@ pub fn extract_funai_upg(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(),
println!("- Saved file!");
}
println!("\nExtraction finished!");
Ok(())
}
+1 -4
View File
@@ -39,8 +39,7 @@ pub fn extract_invincible_image(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Res
}
if header.file_version[0] != 3 {
println!("\nSorry, this version of the file is not supported!");
return Ok(())
return Err("Unsupported format version! (Only 3 is supported right now)".into());
}
let mut encrypted_data = Vec::new();
@@ -77,7 +76,5 @@ pub fn extract_invincible_image(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Res
i += 1;
}
println!("\nExtraction finished!");
Ok(())
}
+6 -2
View File
@@ -12,7 +12,9 @@ type Aes128CbcDec = Decryptor<Aes128>;
pub fn decrypt_aes_salted_old(encrypted_data: &[u8], passphrase_bytes: &Vec<u8>) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
let mut data = encrypted_data.to_vec();
assert!(data[0..8].to_vec() == b"Salted__", "invalid encrypted data!");
if data[0..8].to_vec() != b"Salted__" {
return Err("Invalid encrypted data!".into());
}
let salt = &data[8..16];
//key = md5 of (passphrase + salt)
@@ -38,7 +40,9 @@ pub fn decrypt_aes_salted_old(encrypted_data: &[u8], passphrase_bytes: &Vec<u8>)
pub fn decrypt_aes_salted_tizen(encrypted_data: &[u8], passphrase_bytes: &Vec<u8>) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
let mut data = encrypted_data.to_vec();
assert!(data[0..8].to_vec() == b"Salted__", "invalid encrypted data!");
if data[0..8].to_vec() != b"Salted__" {
return Err("Invalid encrypted data!".into());
}
let salt = &data[8..16];
//iv = md5 of salt
+7 -6
View File
@@ -70,8 +70,7 @@ pub fn extract_msd10(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), Box
passphrase_bytes = hex::decode(p)?;
println!("Firmware type: {}", firmware_type);
} else {
println!("Sorry, this firmware is not supported!");
std::process::exit(1);
return Err("This firmware is not supported!".into());
}
let toc_offset = headers[0].offset;
@@ -95,7 +94,9 @@ pub fn extract_msd10(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), Box
println!("\n({}/{}) - {}, Size: {}",
i + 1, items.len(), item.name, size);
assert!(sections[i as usize].index == item.item_id, "Item ID in TOC does not match ID from header!");
if sections[i as usize].index != item.item_id {
return Err("Item ID in TOC does not match ID from header!".into());
}
let stored_data = common::read_file(&file, offset as u64, size as usize)?;
@@ -132,7 +133,9 @@ pub fn extract_msd10(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), Box
println!("\n({}/{}) - {}, Type: {}, Size: {}",
item.item_id, items.len(), item.name, type_str, item.all_size);
assert!(sections[i as usize].index == item.item_id, "Item ID in TOC does not match ID from header!");
if sections[i as usize].index != item.item_id {
return Err("Item ID in TOC does not match ID from header!".into());
}
if item.item_type == 0x11 { //Skip CMAC DATA
println!("- Skipping CMAC Data...");
@@ -162,7 +165,5 @@ pub fn extract_msd10(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), Box
}
}
println!("\nExtraction finished!");
Ok(())
}
+4 -5
View File
@@ -65,8 +65,7 @@ pub fn extract_msd11(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), Box
println!("Passphrase: {}", p);
passphrase_bytes = hex::decode(p)?;
} else {
println!("Sorry, this firmware is not supported!");
std::process::exit(1);
return Err("This firmware is not supported!".into());
}
let toc_offset = headers[0].offset + 8;
@@ -88,7 +87,9 @@ pub fn extract_msd11(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), Box
println!("\n({}/{}) - {}, Size: {}",
i + 1, items.len(), item.name, size);
assert!(sections[i as usize].index == item.item_id, "Item ID in TOC does not match ID from header!");
if sections[i as usize].index != item.item_id {
return Err("Item ID in TOC does not match ID from header!".into());
}
let stored_data = common::read_file(&file, offset as u64, size as usize)?;
@@ -109,7 +110,5 @@ pub fn extract_msd11(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), Box
println!("-- Saved file!");
}
println!("\nExtraction finished!");
Ok(())
}
+1 -4
View File
@@ -47,7 +47,7 @@ pub fn extract_mstar(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), Box
script_string = String::from_utf8_lossy(&script);
if script_string == "" {
println!("Failed to get script.");
return Err("Failed to get script".into());
}
}
@@ -168,8 +168,5 @@ pub fn extract_mstar(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), Box
i += 1;
}
println!();
println!("Extraction finished!");
Ok(())
}
+3 -7
View File
@@ -72,8 +72,7 @@ pub fn extract_mtk_bdp(app_ctx: &AppContext, ctx: Box<dyn Any>) -> Result<(), Bo
let mut pit_entries: Vec<PITEntry> = Vec::new();
let pit_header: PITHeader = file.read_le()?;
if pit_header.pit_magic != PIT_MAGIC {
println!("Invalid PIT Magic!");
return Ok(());
return Err("Invalid PIT magic!".into());
}
println!("PIT Info - First entry offs: {}, Entry size: {}, Entry count: {}", pit_header.first_entry_offset, pit_header.entry_size, pit_header.entry_count);
file.seek(SeekFrom::Start(pit_offset + pit_header.first_entry_offset as u64))?;
@@ -90,8 +89,7 @@ pub fn extract_mtk_bdp(app_ctx: &AppContext, ctx: Box<dyn Any>) -> Result<(), Bo
let mut bit_entries: Vec<BITEntry> = Vec::new();
let bit_magic = common::read_exact(&mut file, 20)?;
if bit_magic != BIT_MAGIC {
println!("Invalid BIT Magic!");
return Ok(());
return Err("Invalid BIT magic!".into());
}
let mut bit_i = 0;
@@ -127,8 +125,6 @@ pub fn extract_mtk_bdp(app_ctx: &AppContext, ctx: Box<dyn Any>) -> Result<(), Bo
println!("-- Saved file!");
}
println!("\nExtraction finished!");
Ok(())
}
-2
View File
@@ -162,7 +162,5 @@ pub fn extract_mtk_pkg(app_ctx: &AppContext, ctx: Box<dyn Any>) -> Result<(), Bo
println!("-- Saved file!");
}
println!("\nExtraction finished!");
Ok(())
}
-2
View File
@@ -132,7 +132,5 @@ pub fn extract_mtk_pkg_new(app_ctx: &AppContext, ctx: Box<dyn Any>) -> Result<()
println!("-- Saved file!");
}
println!("\nExtraction finished!");
Ok(())
}
-2
View File
@@ -102,7 +102,5 @@ pub fn extract_mtk_pkg_old(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(
println!("-- Saved file!");
}
println!("\nExtraction finished!");
Ok(())
}
+2 -5
View File
@@ -35,8 +35,7 @@ pub fn extract_nvt_timg(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(),
pimg_i += 1;
let pimg: PIMG = file.read_le()?;
if &pimg.magic_bytes != b"PIMG" {
println!("Invalid PIMG magic!");
return Ok(());
return Err("Invalid PIMG magic!".into());
}
let data = common::read_exact(&mut file, pimg.size as usize)?;
@@ -57,7 +56,7 @@ pub fn extract_nvt_timg(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(),
println!("-- Saved file!");
continue
} else {
println!("- Warning: unsupported compression type!");
println!("- Warning: unsupported compression type, saving stored data!");
out_data = data;
}
@@ -68,7 +67,5 @@ pub fn extract_nvt_timg(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(),
println!("-- Saved file!");
}
println!("\nExtraction finished!");
Ok(())
}
-2
View File
@@ -105,8 +105,6 @@ pub fn extract_pana_dvd(app_ctx: &AppContext, ctx: Box<dyn Any>) -> Result<(), B
}
}
println!("\nExtraction finished!");
Ok(())
}
+1 -4
View File
@@ -52,8 +52,7 @@ pub fn extract_pfl_upg(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), B
}
}
if key.is_none() {
println!("Sorry, this firmware is not supported!");
std::process::exit(1);
return Err("This firmware is not supported!".into());
}
//get key
@@ -142,8 +141,6 @@ pub fn extract_pfl_upg(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), B
println!("- Saved file!");
}
println!("\nExtraction finished!");
Ok(())
}
-1
View File
@@ -133,6 +133,5 @@ pub fn extract_pup(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), Box<d
}
println!("\nExtraction finished!");
Ok(())
}
-1
View File
@@ -95,6 +95,5 @@ pub fn extract_roku(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), Box<
}
}
println!("\nExtraction finished!");
Ok(())
}
+1 -3
View File
@@ -36,7 +36,6 @@ pub fn extract_ruf(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), Box<d
actually_extract_ruf(file, &app_ctx.output_dir, 0)?;
}
println!("\nExtraction finished!");
Ok(())
}
@@ -86,8 +85,7 @@ fn actually_extract_ruf(mut file: &File, output_folder: &PathBuf, start_offset:
println!("\nKey: {}", k);
key_bytes = hex::decode(k)?.as_slice().try_into()?;
} else {
println!("\nSorry, this firmware is not supported!");
std::process::exit(1);
return Err("This firmware is not supported!".into());
}
file.seek(SeekFrom::Start(start_offset + 2048))?;
-2
View File
@@ -122,7 +122,5 @@ pub fn extract_rvp(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), Box<d
println!("- Saved file!");
}
println!("\nExtraction finished!");
Ok(())
}
+1 -4
View File
@@ -45,8 +45,7 @@ pub fn extract_samsung_old(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(
if let Some(p) = secret {
println!("Secret: {}", p);
} else {
println!("Sorry, this firmware is not supported!");
std::process::exit(1);
return Err("This firmware is not supported!".into());
}
for entry in fs::read_dir(image_path)? {
@@ -129,7 +128,5 @@ pub fn extract_samsung_old(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(
}
}
println!("\nExtraction finished!");
Ok(())
}
-2
View File
@@ -155,7 +155,5 @@ pub fn extract_sddl_sec(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(),
}
}
println!("\nExtraction finished!");
Ok(())
}
+1 -7
View File
@@ -62,11 +62,7 @@ pub fn extract_slp(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), Box<d
let output_path = Path::new(&app_ctx.output_dir).join(format!("{}.bin", i));
fs::create_dir_all(&app_ctx.output_dir)?;
let mut out_file = OpenOptions::new()
.write(true)
.create(true)
.open(output_path)?;
let mut out_file = OpenOptions::new().write(true).create(true).open(output_path)?;
out_file.write_all(&data)?;
println!("- Saved file!");
@@ -74,7 +70,5 @@ pub fn extract_slp(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), Box<d
i += 1;
}
println!("\nExtraction finished!");
Ok(())
}
-2
View File
@@ -82,8 +82,6 @@ pub fn extract_sony_bdp(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(),
println!("- Not an MTK BDP file.");
}
}
println!("\nExtraction finished!");
Ok(())
}