diff --git a/src/formats.rs b/src/formats.rs index 6370498..1228759 100644 --- a/src/formats.rs +++ b/src/formats.rs @@ -1,10 +1,10 @@ use std::any::Any; -use crate::ProgramContext; +use crate::AppContext; pub struct Format { pub name: &'static str, - pub detect_func: fn(&ProgramContext) -> Result>, Box>, - pub run_func: fn(&ProgramContext, Option>) -> Result<(), Box>, + pub detector_func: fn(&AppContext) -> Result>, Box>, + pub extractor_func: fn(&AppContext, Option>) -> Result<(), Box>, } pub mod mstar; @@ -44,32 +44,33 @@ pub mod mtk_bdp; pub fn get_registry() -> Vec { return vec![ - crate::formats::amlogic::format(), - crate::formats::epk1::format(), - crate::formats::android_ota_payload::format(), - crate::formats::bdl::format(), - crate::formats::epk2::format(), - crate::formats::epk::format(), - crate::formats::epk2b::format(), - crate::formats::funai_upg::format(), - crate::formats::invincible_image::format(), - crate::formats::msd10::format(), - crate::formats::msd11::format(), crate::formats::mstar::format(), - crate::formats::novatek::format(), crate::formats::nvt_timg::format(), crate::formats::pfl_upg::format(), - crate::formats::pup::format(), - crate::formats::roku::format(), - crate::formats::ruf::format(), - crate::formats::rvp::format(), crate::formats::sddl_sec::format(), + crate::formats::novatek::format(), + crate::formats::ruf::format(), + crate::formats::invincible_image::format(), crate::formats::slp::format(), - crate::formats::mtk_pkg_old::format(), - crate::formats::mtk_pkg::format(), + crate::formats::roku::format(), crate::formats::sony_bdp::format(), - crate::formats::mtk_pkg_new::format(), + crate::formats::rvp::format(), + crate::formats::funai_upg::format(), crate::formats::pana_dvd::format(), + crate::formats::android_ota_payload::format(), + crate::formats::bdl::format(), + crate::formats::amlogic::format(), + crate::formats::pup::format(), + crate::formats::msd10::format(), + crate::formats::msd11::format(), + crate::formats::epk::format(), + crate::formats::epk1::format(), + crate::formats::epk2::format(), + crate::formats::epk2b::format(), + crate::formats::epk3::format(), + crate::formats::mtk_pkg::format(), + crate::formats::mtk_pkg_old::format(), + crate::formats::mtk_pkg_new::format(), crate::formats::mtk_bdp::format(), ] } \ No newline at end of file diff --git a/src/formats/amlogic.rs b/src/formats/amlogic.rs index 08d4793..cd9b6c0 100644 --- a/src/formats/amlogic.rs +++ b/src/formats/amlogic.rs @@ -1,7 +1,7 @@ use std::any::Any; -use crate::{ProgramContext, formats::Format}; +use crate::{AppContext, formats::Format}; pub fn format() -> Format { - Format { name: "amlogic", detect_func: is_amlogic_file, run_func: extract_amlogic } + Format { name: "amlogic", detector_func: is_amlogic_file, extractor_func: extract_amlogic } } use std::path::{Path}; @@ -49,7 +49,7 @@ impl ItemEntry { } } -pub fn is_amlogic_file(app_ctx: &ProgramContext) -> Result>, Box> { +pub fn is_amlogic_file(app_ctx: &AppContext) -> Result>, Box> { let header = common::read_file(app_ctx.file, 8, 4)?; if header == b"\x56\x19\xB5\x27" { Ok(Some(Box::new(()))) @@ -58,7 +58,7 @@ pub fn is_amlogic_file(app_ctx: &ProgramContext) -> Result>, } } -pub fn extract_amlogic(app_ctx: &ProgramContext, _ctx: Option>) -> Result<(), Box> { +pub fn extract_amlogic(app_ctx: &AppContext, _ctx: Option>) -> Result<(), Box> { let mut file = app_ctx.file; file.seek(SeekFrom::Start(0))?; let header: ImageHeader = file.read_le()?; diff --git a/src/formats/android_ota_payload.rs b/src/formats/android_ota_payload.rs index 0153dd8..3e670cf 100644 --- a/src/formats/android_ota_payload.rs +++ b/src/formats/android_ota_payload.rs @@ -1,7 +1,7 @@ use std::any::Any; -use crate::{ProgramContext, formats::Format}; +use crate::{AppContext, formats::Format}; pub fn format() -> Format { - Format { name: "android_ota_payload", detect_func: is_android_ota_payload_file, run_func: extract_android_ota_payload } + Format { name: "android_ota_payload", detector_func: is_android_ota_payload_file, extractor_func: extract_android_ota_payload } } use std::fs::{self, OpenOptions}; @@ -22,7 +22,7 @@ struct Header { metadata_signature_size: u32, } -pub fn is_android_ota_payload_file(app_ctx: &ProgramContext) -> Result>, Box> { +pub fn is_android_ota_payload_file(app_ctx: &AppContext) -> Result>, Box> { let header = common::read_file(app_ctx.file, 0, 4)?; if header == b"CrAU" { Ok(Some(Box::new(()))) @@ -31,7 +31,7 @@ pub fn is_android_ota_payload_file(app_ctx: &ProgramContext) -> Result>) -> Result<(), Box> { +pub fn extract_android_ota_payload(app_ctx: &AppContext, _ctx: Option>) -> Result<(), Box> { let mut file = app_ctx.file; let header: Header = file.read_be()?; println!("File info:\nFormat version: {}\nManifest size: {}", header.file_format_version, header.manifest_size); diff --git a/src/formats/bdl.rs b/src/formats/bdl.rs index 2b66f41..7964ce7 100644 --- a/src/formats/bdl.rs +++ b/src/formats/bdl.rs @@ -1,7 +1,7 @@ use std::any::Any; -use crate::{ProgramContext, formats::Format}; +use crate::{AppContext, formats::Format}; pub fn format() -> Format { - Format { name: "bdl", detect_func: is_bdl_file, run_func: extract_bdl } + Format { name: "bdl", detector_func: is_bdl_file, extractor_func: extract_bdl } } use std::path::{Path}; @@ -85,7 +85,7 @@ impl PkgEntry { } } -pub fn is_bdl_file(app_ctx: &ProgramContext) -> Result>, Box> { +pub fn is_bdl_file(app_ctx: &AppContext) -> Result>, Box> { let header = common::read_file(app_ctx.file, 0, 4)?; if header == b"ibdl" { Ok(Some(Box::new(()))) @@ -94,7 +94,7 @@ pub fn is_bdl_file(app_ctx: &ProgramContext) -> Result>, Box } } -pub fn extract_bdl(app_ctx: &ProgramContext, _ctx: Option>) -> Result<(), Box> { +pub fn extract_bdl(app_ctx: &AppContext, _ctx: Option>) -> Result<(), Box> { let mut file = app_ctx.file; let header: BdlHeader = file.read_le()?; diff --git a/src/formats/epk.rs b/src/formats/epk.rs index eb5eacf..5ca3dfd 100644 --- a/src/formats/epk.rs +++ b/src/formats/epk.rs @@ -1,7 +1,7 @@ use std::any::Any; -use crate::{ProgramContext, formats::Format}; +use crate::{AppContext, formats::Format}; pub fn format() -> Format { - Format { name: "epk", detect_func: is_epk_file, run_func: extract_epk } + Format { name: "epk", detector_func: is_epk_file, extractor_func: extract_epk } } use crate::utils::common; @@ -11,7 +11,7 @@ pub struct EpkContext { epk_version: u8, } -pub fn is_epk_file(app_ctx: &ProgramContext) -> Result>, Box> { +pub fn is_epk_file(app_ctx: &AppContext) -> Result>, Box> { let versions = common::read_file(app_ctx.file, 1712, 36)?; if let Some(epk_version) = check_epk_version(&versions) { @@ -50,7 +50,7 @@ fn match_with_pattern(data: &[u8], pattern: &str) -> bool { true } -pub fn extract_epk(app_ctx: &ProgramContext, ctx: Option>) -> Result<(), Box> { +pub fn extract_epk(app_ctx: &AppContext, ctx: Option>) -> Result<(), Box> { let ctx = ctx.and_then(|c| c.downcast::().ok()).ok_or("Context is invalid or missing!")?; let versions = common::read_file(app_ctx.file, 1712, 36)?; diff --git a/src/formats/epk1.rs b/src/formats/epk1.rs index 9422ad4..74f2240 100644 --- a/src/formats/epk1.rs +++ b/src/formats/epk1.rs @@ -1,7 +1,7 @@ use std::any::Any; -use crate::{ProgramContext, formats::Format}; +use crate::{AppContext, formats::Format}; pub fn format() -> Format { - Format { name: "epk1", detect_func: is_epk1_file, run_func: extract_epk1 } + Format { name: "epk1", detector_func: is_epk1_file, extractor_func: extract_epk1 } } use std::path::{Path}; @@ -40,7 +40,7 @@ struct Pak { size : u32, } -pub fn is_epk1_file(app_ctx: &ProgramContext) -> Result>, Box> { +pub fn is_epk1_file(app_ctx: &AppContext) -> Result>, Box> { let epk2_magic = common::read_file(app_ctx.file, 12, 4)?; //for epk2b let epak_magic = common::read_file(app_ctx.file, 0, 4)?; if epak_magic == b"epak" && epk2_magic != b"EPK2" { @@ -50,7 +50,7 @@ pub fn is_epk1_file(app_ctx: &ProgramContext) -> Result>, Bo } } -pub fn extract_epk1(app_ctx: &ProgramContext, _ctx: Option>) -> Result<(), Box> { +pub fn extract_epk1(app_ctx: &AppContext, _ctx: Option>) -> Result<(), Box> { let mut file = app_ctx.file; //check type of epk1 let epk1_type; diff --git a/src/formats/epk2.rs b/src/formats/epk2.rs index 8194474..7a05c27 100644 --- a/src/formats/epk2.rs +++ b/src/formats/epk2.rs @@ -1,7 +1,7 @@ use std::any::Any; -use crate::{ProgramContext, formats::Format}; +use crate::{AppContext, formats::Format}; pub fn format() -> Format { - Format { name: "epk2", detect_func: is_epk2_file, run_func: extract_epk2 } + Format { name: "epk2", detector_func: is_epk2_file, extractor_func: extract_epk2 } } use std::fs::{self, OpenOptions}; @@ -71,7 +71,7 @@ struct Pak { name: String, } -pub fn is_epk2_file(app_ctx: &ProgramContext) -> Result>, Box> { +pub fn is_epk2_file(app_ctx: &AppContext) -> Result>, Box> { let header = common::read_file(app_ctx.file, 128, 4)?; if header == b"epak" { Ok(Some(Box::new(()))) @@ -80,7 +80,7 @@ pub fn is_epk2_file(app_ctx: &ProgramContext) -> Result>, Bo } } -pub fn extract_epk2(app_ctx: &ProgramContext, _: Option>) -> Result<(), Box> { +pub fn extract_epk2(app_ctx: &AppContext, _: Option>) -> Result<(), Box> { let mut file = app_ctx.file; let _header_signature = common::read_exact(&mut file, SIGNATURE_SIZE as usize)?; diff --git a/src/formats/epk2b.rs b/src/formats/epk2b.rs index 59ee06b..e972e82 100644 --- a/src/formats/epk2b.rs +++ b/src/formats/epk2b.rs @@ -1,7 +1,7 @@ use std::any::Any; -use crate::{ProgramContext, formats::Format}; +use crate::{AppContext, formats::Format}; pub fn format() -> Format { - Format { name: "epk2b", detect_func: is_epk2b_file, run_func: extract_epk2b } + Format { name: "epk2b", detector_func: is_epk2b_file, extractor_func: extract_epk2b } } use std::path::{Path}; @@ -56,7 +56,7 @@ struct Pak { size : u32, } -pub fn is_epk2b_file(app_ctx: &ProgramContext) -> Result>, Box> { +pub fn is_epk2b_file(app_ctx: &AppContext) -> Result>, Box> { let epk2_magic = common::read_file(app_ctx.file, 12, 4)?; let epak_magic = common::read_file(app_ctx.file, 0, 4)?; if epak_magic == b"epak" && epk2_magic == b"EPK2" { @@ -66,7 +66,7 @@ pub fn is_epk2b_file(app_ctx: &ProgramContext) -> Result>, B } } -pub fn extract_epk2b(app_ctx: &ProgramContext, _ctx: Option>) -> Result<(), Box> { +pub fn extract_epk2b(app_ctx: &AppContext, _ctx: Option>) -> Result<(), Box> { let mut file = app_ctx.file; let header: EpkHeader = file.read_le()?; diff --git a/src/formats/epk3.rs b/src/formats/epk3.rs index 58488a6..4b0e489 100644 --- a/src/formats/epk3.rs +++ b/src/formats/epk3.rs @@ -1,5 +1,8 @@ use std::any::Any; -use crate::{ProgramContext}; +use crate::{AppContext, formats::Format}; +pub fn format() -> Format { + Format { name: "epk3", detector_func: is_epk3_file, extractor_func: extract_epk3 } +} use std::fs::{self, OpenOptions}; use std::path::{Path}; @@ -73,7 +76,11 @@ impl PkgInfoEntry { } } -pub fn extract_epk3(app_ctx: &ProgramContext, _ctx: Option>) -> Result<(), Box> { +pub fn is_epk3_file(_app_ctx: &AppContext) -> Result>, Box> { + Ok(None) +} + +pub fn extract_epk3(app_ctx: &AppContext, _ctx: Option>) -> Result<(), Box> { let mut file = app_ctx.file; file.seek(SeekFrom::Start(0))?; let stored_header = common::read_exact(&mut file, 1712)?; diff --git a/src/formats/funai_upg.rs b/src/formats/funai_upg.rs index d9a5dac..57d73a2 100644 --- a/src/formats/funai_upg.rs +++ b/src/formats/funai_upg.rs @@ -1,7 +1,7 @@ use std::any::Any; -use crate::{ProgramContext, formats::Format}; +use crate::{AppContext, formats::Format}; pub fn format() -> Format { - Format { name: "funai_upg", detect_func: is_funai_upg_file, run_func: extract_funai_upg } + Format { name: "funai_upg", detector_func: is_funai_upg_file, extractor_func: extract_funai_upg } } use std::path::Path; @@ -25,7 +25,7 @@ struct Entry { _unk: u16, } -pub fn is_funai_upg_file(app_ctx: &ProgramContext) -> Result>, Box> { +pub fn is_funai_upg_file(app_ctx: &AppContext) -> Result>, Box> { let header = common::read_file(app_ctx.file, 0, 6)?; if header == b"UPG\x00\x00\x00" { Ok(Some(Box::new(()))) @@ -34,7 +34,7 @@ pub fn is_funai_upg_file(app_ctx: &ProgramContext) -> Result } } -pub fn extract_funai_upg(app_ctx: &ProgramContext, _ctx: Option>) -> Result<(), Box> { +pub fn extract_funai_upg(app_ctx: &AppContext, _ctx: Option>) -> Result<(), Box> { let mut file = app_ctx.file; let header: Header = file.read_le()?; println!("File info:\nFile size: {}\nEntry count: {}", header.file_size, header.entry_count); diff --git a/src/formats/invincible_image.rs b/src/formats/invincible_image.rs index 9534962..5e8caea 100644 --- a/src/formats/invincible_image.rs +++ b/src/formats/invincible_image.rs @@ -1,7 +1,7 @@ use std::any::Any; -use crate::{ProgramContext, formats::Format}; +use crate::{AppContext, formats::Format}; pub fn format() -> Format { - Format { name: "invincible_image", detect_func: is_invincible_image_file, run_func: extract_invincible_image } + Format { name: "invincible_image", detector_func: is_invincible_image_file, extractor_func: extract_invincible_image } } use std::path::{Path}; @@ -62,7 +62,7 @@ impl Entry { } } -pub fn is_invincible_image_file(app_ctx: &ProgramContext) -> Result>, Box> { +pub fn is_invincible_image_file(app_ctx: &AppContext) -> Result>, Box> { let header = common::read_file(app_ctx.file, 0, 16)?; if header == b"INVINCIBLE_IMAGE" { Ok(Some(Box::new(()))) @@ -71,7 +71,7 @@ pub fn is_invincible_image_file(app_ctx: &ProgramContext) -> Result>) -> Result<(), Box> { +pub fn extract_invincible_image(app_ctx: &AppContext, _ctx: Option>) -> Result<(), Box> { let mut file = app_ctx.file; let header: Header = file.read_le()?; diff --git a/src/formats/msd10.rs b/src/formats/msd10.rs index 7c7fefa..59e522c 100644 --- a/src/formats/msd10.rs +++ b/src/formats/msd10.rs @@ -1,7 +1,7 @@ use std::any::Any; -use crate::{ProgramContext, formats::Format}; +use crate::{AppContext, formats::Format}; pub fn format() -> Format { - Format { name: "msd10", detect_func: is_msd10_file, run_func: extract_msd10 } + Format { name: "msd10", detector_func: is_msd10_file, extractor_func: extract_msd10 } } use std::fs::{self, OpenOptions}; @@ -47,7 +47,7 @@ struct Section { size: u32, } -pub fn is_msd10_file(app_ctx: &ProgramContext) -> Result>, Box> { +pub fn is_msd10_file(app_ctx: &AppContext) -> Result>, Box> { let header = common::read_file(app_ctx.file, 0, 6)?; if header == b"MSDU10" { Ok(Some(Box::new(()))) @@ -56,7 +56,7 @@ pub fn is_msd10_file(app_ctx: &ProgramContext) -> Result>, B } } -pub fn extract_msd10(app_ctx: &ProgramContext, _ctx: Option>) -> Result<(), Box> { +pub fn extract_msd10(app_ctx: &AppContext, _ctx: Option>) -> Result<(), Box> { let mut file = app_ctx.file; let header: FileHeader = file.read_le()?; println!("\nNumber of sections: {}", header.section_count); diff --git a/src/formats/msd11.rs b/src/formats/msd11.rs index 38b058e..9a1aa6d 100644 --- a/src/formats/msd11.rs +++ b/src/formats/msd11.rs @@ -1,7 +1,7 @@ use std::any::Any; -use crate::{ProgramContext, formats::Format}; +use crate::{AppContext, formats::Format}; pub fn format() -> Format { - Format { name: "msd11", detect_func: is_msd11_file, run_func: extract_msd11 } + Format { name: "msd11", detector_func: is_msd11_file, extractor_func: extract_msd11 } } use std::fs::{self, OpenOptions}; @@ -48,7 +48,7 @@ struct Section { size: u64, } -pub fn is_msd11_file(app_ctx: &ProgramContext) -> Result>, Box> { +pub fn is_msd11_file(app_ctx: &AppContext) -> Result>, Box> { let header = common::read_file(app_ctx.file, 0, 6)?; if header == b"MSDU11" { Ok(Some(Box::new(()))) @@ -57,7 +57,7 @@ pub fn is_msd11_file(app_ctx: &ProgramContext) -> Result>, B } } -pub fn extract_msd11(app_ctx: &ProgramContext, _ctx: Option>) -> Result<(), Box> { +pub fn extract_msd11(app_ctx: &AppContext, _ctx: Option>) -> Result<(), Box> { let mut file = app_ctx.file; let header: FileHeader = file.read_le()?; println!("\nNumber of sections: {}", header.section_count); diff --git a/src/formats/mstar.rs b/src/formats/mstar.rs index e02852d..1579979 100644 --- a/src/formats/mstar.rs +++ b/src/formats/mstar.rs @@ -1,7 +1,7 @@ use std::any::Any; -use crate::{ProgramContext, formats::Format}; +use crate::{AppContext, formats::Format}; pub fn format() -> Format { - Format { name: "mstar", detect_func: is_mstar_file, run_func: extract_mstar } + Format { name: "mstar", detector_func: is_mstar_file, extractor_func: extract_mstar } } use std::fs::{self, OpenOptions}; @@ -13,7 +13,7 @@ use crate::utils::compression::{decompress_lzma, decompress_lz4}; use crate::utils::lzop::{unlzop_to_file}; use crate::utils::sparse::{unsparse_to_file}; -pub fn is_mstar_file(app_ctx: &ProgramContext) -> Result>, Box> { +pub fn is_mstar_file(app_ctx: &AppContext) -> Result>, Box> { let header = common::read_file(app_ctx.file, 0, 32768)?; let header_string = String::from_utf8_lossy(&header); @@ -32,7 +32,7 @@ fn parse_number(s: &str) -> Option { } } -pub fn extract_mstar(app_ctx: &ProgramContext, _ctx: Option>) -> Result<(), Box> { +pub fn extract_mstar(app_ctx: &AppContext, _ctx: Option>) -> Result<(), Box> { let file = app_ctx.file; let mut script = common::read_file(&file, 0, 32768)?; diff --git a/src/formats/mtk_bdp.rs b/src/formats/mtk_bdp.rs index 6e782c7..e410dd2 100644 --- a/src/formats/mtk_bdp.rs +++ b/src/formats/mtk_bdp.rs @@ -1,7 +1,7 @@ use std::any::Any; -use crate::{ProgramContext, formats::Format}; +use crate::{AppContext, formats::Format}; pub fn format() -> Format { - Format { name: "mtk_bdp", detect_func: is_mtk_bdp_file, run_func: extract_mtk_bdp } + Format { name: "mtk_bdp", detector_func: is_mtk_bdp_file, extractor_func: extract_mtk_bdp } } use std::path::{Path}; @@ -77,7 +77,7 @@ fn find_bytes(data: &[u8], pattern: &[u8]) -> Option { data.windows(pattern.len()).position(|window| window == pattern) } -pub fn is_mtk_bdp_file(app_ctx: &ProgramContext) -> Result>, Box> { +pub fn is_mtk_bdp_file(app_ctx: &AppContext) -> Result>, Box> { let mut file = app_ctx.file; let file_size = file.metadata()?.len(); let mut data = Vec::new(); @@ -95,7 +95,7 @@ pub fn is_mtk_bdp_file(app_ctx: &ProgramContext) -> Result>, } } -pub fn extract_mtk_bdp(app_ctx: &ProgramContext, ctx: Option>) -> Result<(), Box> { +pub fn extract_mtk_bdp(app_ctx: &AppContext, ctx: Option>) -> Result<(), Box> { let mut file = app_ctx.file; let ctx = ctx.and_then(|c: Box| c.downcast::().ok()).ok_or("Context is invalid or missing!")?; let offset = ctx.pitit_offset; diff --git a/src/formats/mtk_pkg.rs b/src/formats/mtk_pkg.rs index abd35ca..262330f 100644 --- a/src/formats/mtk_pkg.rs +++ b/src/formats/mtk_pkg.rs @@ -1,7 +1,7 @@ use std::any::Any; -use crate::{ProgramContext, formats::Format}; +use crate::{AppContext, formats::Format}; pub fn format() -> Format { - Format { name: "mtk_pkg", detect_func: is_mtk_pkg_file, run_func: extract_mtk_pkg } + Format { name: "mtk_pkg", detector_func: is_mtk_pkg_file, extractor_func: extract_mtk_pkg } } use std::path::Path; @@ -81,7 +81,7 @@ static HEADER_KEY: [u8; 16] = [ static HEADER_IV: [u8; 16] = [0x00; 16]; -pub fn is_mtk_pkg_file(app_ctx: &ProgramContext) -> Result>, Box> { +pub fn is_mtk_pkg_file(app_ctx: &AppContext) -> Result>, Box> { let mut encrypted_header = common::read_file(app_ctx.file, 0, HEADER_SIZE)?; let mut header = decrypt_aes128_cbc_nopad(&encrypted_header, &HEADER_KEY, &HEADER_IV)?; if &header[4..12] == MTK_HEADER_MAGIC { @@ -99,7 +99,7 @@ pub fn is_mtk_pkg_file(app_ctx: &ProgramContext) -> Result>, } } -pub fn extract_mtk_pkg(app_ctx: &ProgramContext, ctx: Option>) -> Result<(), Box> { +pub fn extract_mtk_pkg(app_ctx: &AppContext, ctx: Option>) -> Result<(), Box> { let mut file = app_ctx.file; let ctx = ctx.and_then(|c: Box| c.downcast::().ok()).ok_or("Context is invalid or missing!")?; diff --git a/src/formats/mtk_pkg_new.rs b/src/formats/mtk_pkg_new.rs index 0cce9e1..72b3db5 100644 --- a/src/formats/mtk_pkg_new.rs +++ b/src/formats/mtk_pkg_new.rs @@ -1,7 +1,7 @@ use std::any::Any; -use crate::{ProgramContext, formats::Format}; +use crate::{AppContext, formats::Format}; pub fn format() -> Format { - Format { name: "mtk_pkg_new", detect_func: is_mtk_pkg_new_file, run_func: extract_mtk_pkg_new } + Format { name: "mtk_pkg_new", detector_func: is_mtk_pkg_new_file, extractor_func: extract_mtk_pkg_new } } use std::path::Path; @@ -70,7 +70,7 @@ impl PartEntry { static HEADER_SIZE: usize = 0x170; -pub fn is_mtk_pkg_new_file(app_ctx: &ProgramContext) -> Result>, Box> { +pub fn is_mtk_pkg_new_file(app_ctx: &AppContext) -> Result>, Box> { let encrypted_header = common::read_file(app_ctx.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()?; @@ -90,7 +90,7 @@ pub fn is_mtk_pkg_new_file(app_ctx: &ProgramContext) -> Result>) -> Result<(), Box> { +pub fn extract_mtk_pkg_new(app_ctx: &AppContext, ctx: Option>) -> Result<(), Box> { let mut file = app_ctx.file; let ctx = ctx.and_then(|c: Box| c.downcast::().ok()).ok_or("Context is invalid or missing!")?; let file_size = file.metadata()?.len(); diff --git a/src/formats/mtk_pkg_old.rs b/src/formats/mtk_pkg_old.rs index 9af4b11..ae4faa7 100644 --- a/src/formats/mtk_pkg_old.rs +++ b/src/formats/mtk_pkg_old.rs @@ -1,7 +1,7 @@ use std::any::Any; -use crate::{ProgramContext, formats::Format}; +use crate::{AppContext, formats::Format}; pub fn format() -> Format { - Format { name: "mtk_pkg_old", detect_func: is_mtk_pkg_old_file, run_func: extract_mtk_pkg_old } + Format { name: "mtk_pkg_old", detector_func: is_mtk_pkg_old_file, extractor_func: extract_mtk_pkg_old } } use std::path::Path; @@ -63,7 +63,7 @@ impl PartEntry { static HEADER_SIZE: usize = 0x98; -pub fn is_mtk_pkg_old_file(app_ctx: &ProgramContext) -> Result>, Box> { +pub fn is_mtk_pkg_old_file(app_ctx: &AppContext) -> Result>, Box> { let mut file = app_ctx.file; let encrypted_header = common::read_file(&file, 0, HEADER_SIZE)?; let header = decrypt(&encrypted_header, KEY, Some(HEADER_XOR_MASK)); @@ -82,7 +82,7 @@ pub fn is_mtk_pkg_old_file(app_ctx: &ProgramContext) -> Result>) -> Result<(), Box> { +pub fn extract_mtk_pkg_old(app_ctx: &AppContext, _ctx: Option>) -> Result<(), Box> { let mut file = app_ctx.file; let file_size = file.metadata()?.len(); let encrypted_header = common::read_exact(&mut file, HEADER_SIZE)?; diff --git a/src/formats/novatek.rs b/src/formats/novatek.rs index d1c721c..e9194db 100644 --- a/src/formats/novatek.rs +++ b/src/formats/novatek.rs @@ -1,7 +1,7 @@ use std::any::Any; -use crate::{ProgramContext, formats::Format}; +use crate::{AppContext, formats::Format}; pub fn format() -> Format { - Format { name: "novatek", detect_func: is_novatek_file, run_func: extract_novatek } + Format { name: "novatek", detector_func: is_novatek_file, extractor_func: extract_novatek } } use std::path::Path; @@ -40,7 +40,7 @@ struct PartEntry { #[br(count = 16)] _md5_checksum: Vec, } -pub fn is_novatek_file(app_ctx: &ProgramContext) -> Result>, Box> { +pub fn is_novatek_file(app_ctx: &AppContext) -> Result>, Box> { let header = common::read_file(app_ctx.file, 0, 4)?; if header == b"NFWB" { Ok(Some(Box::new(()))) @@ -49,7 +49,7 @@ pub fn is_novatek_file(app_ctx: &ProgramContext) -> Result>, } } -pub fn extract_novatek(app_ctx: &ProgramContext, _ctx: Option>) -> Result<(), Box> { +pub fn extract_novatek(app_ctx: &AppContext, _ctx: Option>) -> Result<(), Box> { let mut file = app_ctx.file; let header: Header = file.read_le()?; diff --git a/src/formats/nvt_timg.rs b/src/formats/nvt_timg.rs index 1eafb5c..2ceb071 100644 --- a/src/formats/nvt_timg.rs +++ b/src/formats/nvt_timg.rs @@ -1,7 +1,7 @@ use std::any::Any; -use crate::{ProgramContext, formats::Format}; +use crate::{AppContext, formats::Format}; pub fn format() -> Format { - Format { name: "nvt_timg", detect_func: is_nvt_timg_file, run_func: extract_nvt_timg } + Format { name: "nvt_timg", detector_func: is_nvt_timg_file, extractor_func: extract_nvt_timg } } use std::path::{Path}; @@ -49,7 +49,7 @@ impl PIMG { } } -pub fn is_nvt_timg_file(app_ctx: &ProgramContext) -> Result>, Box> { +pub fn is_nvt_timg_file(app_ctx: &AppContext) -> Result>, Box> { let header = common::read_file(app_ctx.file, 0, 4)?; if header == b"TIMG" { Ok(Some(Box::new(()))) @@ -58,7 +58,7 @@ pub fn is_nvt_timg_file(app_ctx: &ProgramContext) -> Result> } } -pub fn extract_nvt_timg(app_ctx: &ProgramContext, _ctx: Option>) -> Result<(), Box> { +pub fn extract_nvt_timg(app_ctx: &AppContext, _ctx: Option>) -> Result<(), Box> { let mut file = app_ctx.file; let file_size = file.metadata()?.len(); let timg: TIMG = file.read_le()?; diff --git a/src/formats/pana_dvd.rs b/src/formats/pana_dvd.rs index 3f23230..ef73e80 100644 --- a/src/formats/pana_dvd.rs +++ b/src/formats/pana_dvd.rs @@ -1,7 +1,7 @@ use std::any::Any; -use crate::{ProgramContext, formats::Format}; +use crate::{AppContext, formats::Format}; pub fn format() -> Format { - Format { name: "pana_dvd", detect_func: is_pana_dvd_file, run_func: extract_pana_dvd } + Format { name: "pana_dvd", detector_func: is_pana_dvd_file, extractor_func: extract_pana_dvd } } use std::path::{Path, PathBuf}; @@ -149,7 +149,7 @@ 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(app_ctx: &ProgramContext) -> Result>, Box> { +pub fn is_pana_dvd_file(app_ctx: &AppContext) -> Result>, Box> { let header = common::read_file(app_ctx.file, 0, 64)?; if let Some(matching_key) = find_key(&keys::PANA_DVD_KEYONLY, &header, b"PROG", 0)? { Ok(Some(Box::new(PanaDvdContext { @@ -180,7 +180,7 @@ pub fn is_pana_dvd_file(app_ctx: &ProgramContext) -> Result> } } -pub fn extract_pana_dvd(app_ctx: &ProgramContext, ctx: Option>) -> Result<(), Box> { +pub fn extract_pana_dvd(app_ctx: &AppContext, ctx: Option>) -> Result<(), Box> { let mut file = app_ctx.file; let context = ctx.and_then(|c: Box| c.downcast::().ok()).ok_or("Context is invalid or missing!")?; diff --git a/src/formats/pfl_upg.rs b/src/formats/pfl_upg.rs index ad1f85e..def64c2 100644 --- a/src/formats/pfl_upg.rs +++ b/src/formats/pfl_upg.rs @@ -1,7 +1,7 @@ use std::any::Any; -use crate::{ProgramContext, formats::Format}; +use crate::{AppContext, formats::Format}; pub fn format() -> Format { - Format { name: "pfl_upg", detect_func: is_pfl_upg_file, run_func: extract_pfl_upg } + Format { name: "pfl_upg", detector_func: is_pfl_upg_file, extractor_func: extract_pfl_upg } } use rsa::{RsaPublicKey, BigUint}; @@ -48,7 +48,7 @@ impl FileHeader { } } -pub fn is_pfl_upg_file(app_ctx: &ProgramContext) -> Result>, Box> { +pub fn is_pfl_upg_file(app_ctx: &AppContext) -> Result>, Box> { let header = common::read_file(app_ctx.file, 0, 8)?; if header == b"2SWU3TXV" { Ok(Some(Box::new(()))) @@ -89,7 +89,7 @@ fn decrypt_aes256_ecb(key: &[u8], ciphertext: &[u8]) -> Result, Box>) -> Result<(), Box> { +pub fn extract_pfl_upg(app_ctx: &AppContext, _ctx: Option>) -> Result<(), Box> { let mut file = app_ctx.file; let header: Header = file.read_le()?; let signature = common::read_exact(&mut file, 128)?; diff --git a/src/formats/pup.rs b/src/formats/pup.rs index 9dd86f1..cdd25e3 100644 --- a/src/formats/pup.rs +++ b/src/formats/pup.rs @@ -1,7 +1,7 @@ use std::any::Any; -use crate::{ProgramContext, formats::Format}; +use crate::{AppContext, formats::Format}; pub fn format() -> Format { - Format { name: "pup", detect_func: is_pup_file, run_func: extract_pup } + Format { name: "pup", detector_func: is_pup_file, extractor_func: extract_pup } } use std::path::{Path}; @@ -56,7 +56,7 @@ struct BlockEntry { size: u32, } -pub fn is_pup_file(app_ctx: &ProgramContext) -> Result>, Box> { +pub fn is_pup_file(app_ctx: &AppContext) -> Result>, Box> { let header = common::read_file(app_ctx.file, 0, 4)?; if header == b"\x4F\x15\x3D\x1D" || header == b"\x54\x14\xF5\xEE" { //ps4, ps5 Ok(Some(Box::new(()))) @@ -65,7 +65,7 @@ pub fn is_pup_file(app_ctx: &ProgramContext) -> Result>, Box } } -pub fn extract_pup(app_ctx: &ProgramContext, _ctx: Option>) -> Result<(), Box> { +pub fn extract_pup(app_ctx: &AppContext, _ctx: Option>) -> Result<(), Box> { let mut file = app_ctx.file; let header: Header = file.read_le()?; diff --git a/src/formats/roku.rs b/src/formats/roku.rs index ede6644..2b60ed0 100644 --- a/src/formats/roku.rs +++ b/src/formats/roku.rs @@ -1,7 +1,7 @@ use std::any::Any; -use crate::{ProgramContext, formats::Format}; +use crate::{AppContext, formats::Format}; pub fn format() -> Format { - Format { name: "roku", detect_func: is_roku_file, run_func: extract_roku } + Format { name: "roku", detector_func: is_roku_file, extractor_func: extract_roku } } use std::fs::{self, OpenOptions}; @@ -61,7 +61,7 @@ impl ImageHeader { } } -pub fn is_roku_file(app_ctx: &ProgramContext) -> Result>, Box> { +pub fn is_roku_file(app_ctx: &AppContext) -> Result>, Box> { let header = common::read_file(app_ctx.file, 0, 32)?; let try_decrypt_header = decrypt_aes128_cbc_nopad(&header, &FILE_KEY, &FILE_IV)?; @@ -72,7 +72,7 @@ pub fn is_roku_file(app_ctx: &ProgramContext) -> Result>, Bo } } -pub fn extract_roku(app_ctx: &ProgramContext, _ctx: Option>) -> Result<(), Box> { +pub fn extract_roku(app_ctx: &AppContext, _ctx: Option>) -> Result<(), Box> { let mut file = app_ctx.file; let mut encrypted_data = Vec::new(); file.read_to_end(&mut encrypted_data)?; diff --git a/src/formats/ruf.rs b/src/formats/ruf.rs index cb235e5..b76a4b0 100644 --- a/src/formats/ruf.rs +++ b/src/formats/ruf.rs @@ -1,7 +1,7 @@ use std::any::Any; -use crate::{ProgramContext, formats::Format}; +use crate::{AppContext, formats::Format}; pub fn format() -> Format { - Format { name: "ruf", detect_func: is_ruf_file, run_func: extract_ruf } + Format { name: "ruf", detector_func: is_ruf_file, extractor_func: extract_ruf } } use std::path::{Path}; @@ -75,7 +75,7 @@ impl RufEntry { } } -pub fn is_ruf_file(app_ctx: &ProgramContext) -> Result>, Box> { +pub fn is_ruf_file(app_ctx: &AppContext) -> Result>, Box> { let header = common::read_file(app_ctx.file, 0, 6)?; if header == b"RUF\x00\x00\x00" { Ok(Some(Box::new(()))) @@ -84,7 +84,7 @@ pub fn is_ruf_file(app_ctx: &ProgramContext) -> Result>, Box } } -pub fn extract_ruf(app_ctx: &ProgramContext, _ctx: Option>) -> Result<(), Box> { +pub fn extract_ruf(app_ctx: &AppContext, _ctx: Option>) -> Result<(), Box> { let mut file = app_ctx.file; let header: RufHeader = file.read_be()?; if header.is_dual_ruf() { diff --git a/src/formats/rvp.rs b/src/formats/rvp.rs index f91abe0..e05e63c 100644 --- a/src/formats/rvp.rs +++ b/src/formats/rvp.rs @@ -1,7 +1,7 @@ use std::any::Any; -use crate::{ProgramContext, formats::Format}; +use crate::{AppContext, formats::Format}; pub fn format() -> Format { - Format { name: "rvp", detect_func: is_rvp_file, run_func: extract_rvp } + Format { name: "rvp", detector_func: is_rvp_file, extractor_func: extract_rvp } } use std::path::Path; @@ -18,7 +18,7 @@ fn decrypt_xor(data: &[u8]) -> Vec { .collect() } -pub fn is_rvp_file(app_ctx: &ProgramContext) -> Result>, Box> { +pub fn is_rvp_file(app_ctx: &AppContext) -> Result>, Box> { let mut file = app_ctx.file; //MVP let header = common::read_file(file, 0, 4)?; @@ -39,7 +39,7 @@ pub fn is_rvp_file(app_ctx: &ProgramContext) -> Result>, Box Ok(Some(Box::new(()))) } -pub fn extract_rvp(app_ctx: &ProgramContext, _ctx: Option>) -> Result<(), Box> { +pub fn extract_rvp(app_ctx: &AppContext, _ctx: Option>) -> Result<(), Box> { let mut file = app_ctx.file; let mut obf_data = Vec::new(); //we sadly cannot deXOR on the fly because of its 32 byte pattern file.read_to_end(&mut obf_data)?; diff --git a/src/formats/sddl_sec.rs b/src/formats/sddl_sec.rs index 180c58b..4a8719f 100644 --- a/src/formats/sddl_sec.rs +++ b/src/formats/sddl_sec.rs @@ -1,8 +1,8 @@ //sddl_dec 5.0 use std::any::Any; -use crate::{ProgramContext, formats::Format}; +use crate::{AppContext, formats::Format}; pub fn format() -> Format { - Format { name: "sddl_sec", detect_func: is_sddl_sec_file, run_func: extract_sddl_sec } + Format { name: "sddl_sec", detector_func: is_sddl_sec_file, extractor_func: extract_sddl_sec } } use std::path::{Path, PathBuf}; @@ -103,7 +103,7 @@ static DEC_IV: [u8; 16] = [ 0xCD, 0x88, 0x38, 0xC4, 0xB9, 0x0C, 0x76, 0x66, ]; -pub fn is_sddl_sec_file(app_ctx: &ProgramContext) -> Result>, Box> { +pub fn is_sddl_sec_file(app_ctx: &AppContext) -> Result>, Box> { let header = common::read_file(app_ctx.file, 0, 32)?; let deciph_header = decipher(&header); if deciph_header.starts_with(b"\x11\x22\x33\x44") { @@ -155,7 +155,7 @@ fn decipher(s: &[u8]) -> Vec { out } -pub fn extract_sddl_sec(app_ctx: &ProgramContext, _ctx: Option>) -> Result<(), Box> { +pub fn extract_sddl_sec(app_ctx: &AppContext, _ctx: Option>) -> Result<(), Box> { let mut file = app_ctx.file; let mut hdr_reader = Cursor::new(decipher(&common::read_exact(&mut file, 32)?)); let hdr: SddlSecHeader = hdr_reader.read_be()?; diff --git a/src/formats/slp.rs b/src/formats/slp.rs index de1aff5..f5940ae 100644 --- a/src/formats/slp.rs +++ b/src/formats/slp.rs @@ -1,7 +1,7 @@ use std::any::Any; -use crate::{ProgramContext, formats::Format}; +use crate::{AppContext, formats::Format}; pub fn format() -> Format { - Format { name: "slp", detect_func: is_slp_file, run_func: extract_slp } + Format { name: "slp", detector_func: is_slp_file, extractor_func: extract_slp } } use std::path::{Path}; @@ -52,7 +52,7 @@ struct EntryNew { #[br(count = 12)] _unk2: Vec, } -pub fn is_slp_file(app_ctx: &ProgramContext) -> Result>, Box> { +pub fn is_slp_file(app_ctx: &AppContext) -> Result>, Box> { let header = common::read_file(app_ctx.file, 0, 4)?; if header == b"SLP\x00" { Ok(Some(Box::new(()))) @@ -61,7 +61,7 @@ pub fn is_slp_file(app_ctx: &ProgramContext) -> Result>, Box } } -pub fn extract_slp(app_ctx: &ProgramContext, _ctx: Option>) -> Result<(), Box> { +pub fn extract_slp(app_ctx: &AppContext, _ctx: Option>) -> Result<(), Box> { let mut file = app_ctx.file; let header: Header = file.read_le()?; diff --git a/src/formats/sony_bdp.rs b/src/formats/sony_bdp.rs index 22fcbde..61ce0aa 100644 --- a/src/formats/sony_bdp.rs +++ b/src/formats/sony_bdp.rs @@ -1,7 +1,7 @@ use std::any::Any; -use crate::{ProgramContext, formats::Format}; +use crate::{AppContext, formats::Format}; pub fn format() -> Format { - Format { name: "sony_bdp", detect_func: is_sony_bdp_file, run_func: extract_sony_bdp } + Format { name: "sony_bdp", detector_func: is_sony_bdp_file, extractor_func: extract_sony_bdp } } use std::fs::File; @@ -63,7 +63,7 @@ struct Entry { size: u32, } -pub fn is_sony_bdp_file(app_ctx: &ProgramContext) -> Result>, Box> { +pub fn is_sony_bdp_file(app_ctx: &AppContext) -> Result>, Box> { let header = common::read_file(app_ctx.file, 0, 4)?; if header == b"\x01\x73\xEC\xC9" || header == b"\x01\x73\xEC\x1F" || header == b"\xEC\x7D\xB0\xB0" { //MSB1x, MSB0x, BDPPxx Ok(Some(Box::new(()))) @@ -72,7 +72,7 @@ pub fn is_sony_bdp_file(app_ctx: &ProgramContext) -> Result> } } -pub fn extract_sony_bdp(app_ctx: &ProgramContext, _ctx: Option>) -> Result<(), Box> { +pub fn extract_sony_bdp(app_ctx: &AppContext, _ctx: Option>) -> Result<(), Box> { let mut file = app_ctx.file; let obf_header = common::read_exact(&mut file, 300)?; let header = hex_substitute(&obf_header); @@ -120,7 +120,7 @@ pub fn extract_sony_bdp(app_ctx: &ProgramContext, _ctx: Option>) -> let last_file = File::open(last_file_path.unwrap())?; let mtk_extraction_path = format!("{}/{}", app_ctx.output_dir, i - 1); - let ctx: ProgramContext = ProgramContext { file: &last_file, output_dir: &mtk_extraction_path }; + let ctx: AppContext = AppContext { file: &last_file, output_dir: &mtk_extraction_path }; if let Some(result) = formats::mtk_bdp::is_mtk_bdp_file(&ctx)? { println!("- MTK BDP file detected!\n"); diff --git a/src/keys.rs b/src/keys.rs index af7ab8a..5b5e38f 100644 --- a/src/keys.rs +++ b/src/keys.rs @@ -2,16 +2,16 @@ //samsung old keys //github.com/george-hopkins/samygo-patcher -pub static SAMSUNG: &[(&str, &str)] = &[ - ("T-GA", "SHWJUH:85a045ae-2296-484c-b457-ede832fcfbe1-646390a3-105e-40aa-85f6-da3086c70111"), - ("T-MST5", "SHWJUH:eceb2c14-db11-425e-9ebf-5f9607f0eb4b-3c38193e-751e-4719-8884-9e76322c0cec"), - ("T-MST10P","b4c136-fbc93576-b3e8-4035-bf4e-ba4cb4ada1ac-f0d81cc4-8301-4832-bd60-f331295743ba"), - ("T-VAL", "A435HX:d3e90afc-0f09-4054-9bac-350cc8dfc901-7cee72ea-15ae-45ce-b0f5-00001abc2010"), - ("T-TDT", "A435HX:d3e90afc-0f09-4054-9bac-350cc8dfc901-7cee72ea-15ae-45ce-b0f5-00002abc2010"), - ("T-MSX", "A435HX:d3e90afc-0f09-4054-9bac-350cc8dfc901-7cee72ea-15ae-45ce-b0f5-00004abc2010"), - ("T-CH", "A435HX:d3e90afc-0f09-4054-9bac-350cc8dfc901-7cee72ea-15ae-45ce-b0f5-611c4f8d4a71"), - ("T-ECP", "3EF6067262CF0C678598BFF22169D1F1EA57C284"), -]; +//pub static SAMSUNG: &[(&str, &str)] = &[ +// ("T-GA", "SHWJUH:85a045ae-2296-484c-b457-ede832fcfbe1-646390a3-105e-40aa-85f6-da3086c70111"), +// ("T-MST5", "SHWJUH:eceb2c14-db11-425e-9ebf-5f9607f0eb4b-3c38193e-751e-4719-8884-9e76322c0cec"), +// ("T-MST10P","b4c136-fbc93576-b3e8-4035-bf4e-ba4cb4ada1ac-f0d81cc4-8301-4832-bd60-f331295743ba"), +// ("T-VAL", "A435HX:d3e90afc-0f09-4054-9bac-350cc8dfc901-7cee72ea-15ae-45ce-b0f5-00001abc2010"), +// ("T-TDT", "A435HX:d3e90afc-0f09-4054-9bac-350cc8dfc901-7cee72ea-15ae-45ce-b0f5-00002abc2010"), +// ("T-MSX", "A435HX:d3e90afc-0f09-4054-9bac-350cc8dfc901-7cee72ea-15ae-45ce-b0f5-00004abc2010"), +// ("T-CH", "A435HX:d3e90afc-0f09-4054-9bac-350cc8dfc901-7cee72ea-15ae-45ce-b0f5-611c4f8d4a71"), +// ("T-ECP", "3EF6067262CF0C678598BFF22169D1F1EA57C284"), +//]; //MSD10 keys //fw prefix, type, key diff --git a/src/main.rs b/src/main.rs index b7cb468..a0a6771 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,7 +14,7 @@ struct Args { output_folder: Option, } -pub struct ProgramContext<'a> { +pub struct AppContext<'a> { pub file: &'a std::fs::File, pub output_dir: &'a str, } @@ -47,13 +47,13 @@ fn main() -> Result<(), Box> { } let file = File::open(path)?; - let program_context: ProgramContext = ProgramContext { file: &file, output_dir: &output_path }; + let app_ctx: AppContext = AppContext { file: &file, output_dir: &output_path }; let formats: Vec = get_registry(); for format in formats { - if let Some(ctx) = (format.detect_func)(&program_context)? { + if let Some(ctx) = (format.detector_func)(&app_ctx)? { println!("{} detected!", format.name); - (format.run_func)(&program_context, Some(ctx))?; + (format.extractor_func)(&app_ctx, Some(ctx))?; return Ok(()); } }