always seek file to start before starting extractor

This commit is contained in:
theubusu
2026-02-17 18:57:14 +01:00
parent 10dd854685
commit c72966cd7e
8 changed files with 26 additions and 16 deletions
+1 -3
View File
@@ -4,7 +4,7 @@ use crate::AppContext;
use std::path::Path; use std::path::Path;
use std::fs::{self, OpenOptions}; use std::fs::{self, OpenOptions};
use std::io::{Write, Seek, SeekFrom}; use std::io::Write;
use binrw::BinReaderExt; use binrw::BinReaderExt;
use crate::utils::common; use crate::utils::common;
@@ -25,9 +25,7 @@ pub fn is_amlogic_file(app_ctx: &AppContext) -> Result<Option<Box<dyn Any>>, Box
pub fn extract_amlogic(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), Box<dyn std::error::Error>> { pub fn extract_amlogic(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), Box<dyn std::error::Error>> {
let mut file = app_ctx.file().ok_or("Extractor expected file")?; let mut file = app_ctx.file().ok_or("Extractor expected file")?;
file.seek(SeekFrom::Start(0))?;
let header: ImageHeader = file.read_le()?; let header: ImageHeader = file.read_le()?;
println!("File info -\nImage size: {}\nItem align size: {}\nItem count: {}\nFormat version: {}", println!("File info -\nImage size: {}\nItem align size: {}\nItem count: {}\nFormat version: {}",
header.image_size, header.item_align_size, header.item_count, header.version); header.image_size, header.item_align_size, header.item_count, header.version);
+4 -1
View File
@@ -1,4 +1,5 @@
use std::any::Any; use std::any::Any;
use std::io::Seek;
use crate::AppContext; use crate::AppContext;
use crate::utils::common; use crate::utils::common;
@@ -49,7 +50,7 @@ fn match_with_pattern(data: &[u8], pattern: &str) -> bool {
} }
pub fn extract_epk(app_ctx: &AppContext, ctx: Box<dyn Any>) -> Result<(), Box<dyn std::error::Error>> { pub fn extract_epk(app_ctx: &AppContext, ctx: Box<dyn Any>) -> Result<(), Box<dyn std::error::Error>> {
let file = app_ctx.file().ok_or("Extractor expected file")?; let mut file = app_ctx.file().ok_or("Extractor expected file")?;
let ctx = ctx.downcast::<EpkContext>().expect("Missing context"); let ctx = ctx.downcast::<EpkContext>().expect("Missing context");
let versions = common::read_file(&file, 1712, 36)?; let versions = common::read_file(&file, 1712, 36)?;
@@ -58,6 +59,8 @@ pub fn extract_epk(app_ctx: &AppContext, ctx: Box<dyn Any>) -> Result<(), Box<dy
let sdk_version = common::string_from_bytes(&versions[20..36]); let sdk_version = common::string_from_bytes(&versions[20..36]);
println!("Platform version: {}\nSDK version: {}", platform_version, sdk_version); println!("Platform version: {}\nSDK version: {}", platform_version, sdk_version);
file.seek(std::io::SeekFrom::Start(0))?;
if ctx.epk_version == 2 { if ctx.epk_version == 2 {
println!("EPK2 detected!\n"); println!("EPK2 detected!\n");
formats::epk2::extract_epk2(app_ctx, Box::new(()))?; formats::epk2::extract_epk2(app_ctx, Box::new(()))?;
-1
View File
@@ -25,7 +25,6 @@ pub fn is_epk2_file(app_ctx: &AppContext) -> Result<Option<Box<dyn Any>>, Box<dy
pub fn extract_epk2(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), Box<dyn std::error::Error>> { pub fn extract_epk2(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), Box<dyn std::error::Error>> {
let mut file = app_ctx.file().ok_or("Extractor expected file")?; let mut file = app_ctx.file().ok_or("Extractor expected file")?;
file.seek(SeekFrom::Start(0))?;
let _header_signature = common::read_exact(&mut file, SIGNATURE_SIZE as usize)?; let _header_signature = common::read_exact(&mut file, SIGNATURE_SIZE as usize)?;
let stored_header = common::read_exact(&mut file, 1584)?; //max header size let stored_header = common::read_exact(&mut file, 1584)?; //max header size
+1 -1
View File
@@ -13,8 +13,8 @@ use include::*;
pub fn is_epk2b_file(app_ctx: &AppContext) -> Result<Option<Box<dyn Any>>, Box<dyn std::error::Error>> { pub fn is_epk2b_file(app_ctx: &AppContext) -> Result<Option<Box<dyn Any>>, Box<dyn std::error::Error>> {
let file = match app_ctx.file() {Some(f) => f, None => return Ok(None)}; let file = match app_ctx.file() {Some(f) => f, None => return Ok(None)};
let epk2_magic = common::read_file(&file, 12, 4)?;
let epak_magic = common::read_file(&file, 0, 4)?; let epak_magic = common::read_file(&file, 0, 4)?;
let epk2_magic = common::read_file(&file, 12, 4)?;
if epak_magic == b"epak" && epk2_magic == b"EPK2" { if epak_magic == b"epak" && epk2_magic == b"EPK2" {
Ok(Some(Box::new(()))) Ok(Some(Box::new(())))
} else { } else {
+2 -2
View File
@@ -4,7 +4,7 @@ use crate::AppContext;
use std::fs::{self, OpenOptions}; use std::fs::{self, OpenOptions};
use std::path::Path; use std::path::Path;
use std::io::{Write, Seek, SeekFrom, Cursor}; use std::io::{Write, Cursor};
use binrw::BinReaderExt; use binrw::BinReaderExt;
use crate::utils::common; use crate::utils::common;
@@ -18,7 +18,7 @@ pub fn is_epk3_file(_app_ctx: &AppContext) -> Result<Option<Box<dyn Any>>, Box<d
pub fn extract_epk3(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), Box<dyn std::error::Error>> { pub fn extract_epk3(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), Box<dyn std::error::Error>> {
let mut file = app_ctx.file().ok_or("Extractor expected file")?; let mut file = app_ctx.file().ok_or("Extractor expected file")?;
file.seek(SeekFrom::Start(0))?;
let stored_header = common::read_exact(&mut file, 1712)?; let stored_header = common::read_exact(&mut file, 1712)?;
let header: Vec<u8>; let header: Vec<u8>;
let _header_signature; let _header_signature;
+11 -6
View File
@@ -9,13 +9,16 @@ use std::io::{Write, Read, Cursor, Seek};
use crate::utils::common; use crate::utils::common;
use include::*; use include::*;
pub struct RvpContext {
header_offset: u64,
}
pub fn is_rvp_file(app_ctx: &AppContext) -> Result<Option<Box<dyn Any>>, Box<dyn std::error::Error>> { pub fn is_rvp_file(app_ctx: &AppContext) -> Result<Option<Box<dyn Any>>, Box<dyn std::error::Error>> {
let mut file = match app_ctx.file() {Some(f) => f, None => return Ok(None)}; let file = match app_ctx.file() {Some(f) => f, None => return Ok(None)};
//MVP //MVP
let header = common::read_file(&file, 0, 4)?; let header = common::read_file(&file, 0, 4)?;
if header == b"UPDT" { if header == b"UPDT" {
file.seek(std::io::SeekFrom::Start(36))?; //skip rest of header // NOT GOOD PRACTICE SHOULD BE REMOVED return Ok(Some(Box::new(RvpContext {header_offset: 36})))
return Ok(Some(Box::new(())))
} }
//RVP //RVP
@@ -26,12 +29,14 @@ pub fn is_rvp_file(app_ctx: &AppContext) -> Result<Option<Box<dyn Any>>, Box<dyn
} }
} }
file.seek(std::io::SeekFrom::Start(64))?; //skip rest of header // NOT GOOD PRACTICE SHOULD BE REMOVED Ok(Some(Box::new(RvpContext {header_offset: 64})))
Ok(Some(Box::new(())))
} }
pub fn extract_rvp(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), Box<dyn std::error::Error>> { pub fn extract_rvp(app_ctx: &AppContext, ctx: Box<dyn Any>) -> Result<(), Box<dyn std::error::Error>> {
let mut file = app_ctx.file().ok_or("Extractor expected file")?; let mut file = app_ctx.file().ok_or("Extractor expected file")?;
let ctx = ctx.downcast::<RvpContext>().expect("Missing context");
file.seek(std::io::SeekFrom::Start(ctx.header_offset))?;
let mut obf_data = Vec::new(); //we sadly cannot deXOR on the fly because of its 32 byte pattern 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)?; file.read_to_end(&mut obf_data)?;
-1
View File
@@ -66,7 +66,6 @@ fn parse_tdi_to_modules(tdi_data: Vec<u8>) -> Result<Vec<TdiTgtInf>, Box<dyn std
pub fn extract_sddl_sec(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), Box<dyn std::error::Error>> { pub fn extract_sddl_sec(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(), Box<dyn std::error::Error>> {
let mut file = app_ctx.file().ok_or("Extractor expected file")?; let mut file = app_ctx.file().ok_or("Extractor expected file")?;
file.seek(SeekFrom::Start(0))?;
let mut secfile_hdr_reader = Cursor::new(decipher(&common::read_exact(&mut file, 32)?)); let mut secfile_hdr_reader = Cursor::new(decipher(&common::read_exact(&mut file, 32)?));
let secfile_header: SecHeader = secfile_hdr_reader.read_be()?; let secfile_header: SecHeader = secfile_hdr_reader.read_be()?;
+7 -1
View File
@@ -4,7 +4,7 @@ mod utils;
use clap::Parser; use clap::Parser;
use std::path::{PathBuf}; use std::path::{PathBuf};
use std::io::{self}; use std::io::{self, Seek, SeekFrom};
use std::fs::{self, File}; use std::fs::{self, File};
use crate::formats::{Format, get_registry}; use crate::formats::{Format, get_registry};
@@ -89,6 +89,12 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
for format in formats { for format in formats {
if let Some(ctx) = (format.detector_func)(&app_ctx)? { if let Some(ctx) = (format.detector_func)(&app_ctx)? {
println!("\n{} detected!", format.name); println!("\n{} detected!", format.name);
//reset seek of the file if present
if let Some(mut file) = app_ctx.file() {
file.seek(SeekFrom::Start(0))?;
}
(format.extractor_func)(&app_ctx, ctx)?; (format.extractor_func)(&app_ctx, ctx)?;
//extractor returned with no error //extractor returned with no error