mirror of
https://github.com/Ap0dexMe0/unixtract.git
synced 2026-07-15 21:00:03 +02:00
general: move common to utils, move common compression function to utils, clean up inconsitencies + add missing header to sony_bdp
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
||||
use std::fs::File;
|
||||
|
||||
use crate::common;
|
||||
use crate::utils::common;
|
||||
use crate::formats;
|
||||
|
||||
pub fn is_epk_file(file: &File) -> bool {
|
||||
|
||||
+1
-2
@@ -2,10 +2,9 @@ use std::fs::File;
|
||||
use std::path::{Path};
|
||||
use std::fs::{self, OpenOptions};
|
||||
use std::io::{Write, Seek, SeekFrom};
|
||||
|
||||
use binrw::{BinRead, BinReaderExt};
|
||||
|
||||
use crate::common;
|
||||
use crate::utils::common;
|
||||
|
||||
#[derive(BinRead)]
|
||||
struct CommonHeader {
|
||||
|
||||
+1
-2
@@ -1,10 +1,9 @@
|
||||
use std::fs::{self, File, OpenOptions};
|
||||
use std::path::{Path};
|
||||
use std::io::{Write, Seek, SeekFrom, Cursor};
|
||||
|
||||
use binrw::{BinRead, BinReaderExt};
|
||||
|
||||
use crate::common;
|
||||
use crate::utils::common;
|
||||
use crate::keys;
|
||||
use crate::formats::epk::{decrypt_aes_ecb_auto, find_key};
|
||||
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ use std::path::{Path};
|
||||
use std::io::{Write, Seek, SeekFrom, Cursor};
|
||||
use binrw::{BinRead, BinReaderExt};
|
||||
|
||||
use crate::common;
|
||||
use crate::utils::common;
|
||||
use crate::keys;
|
||||
use crate::formats::epk::{decrypt_aes_ecb_auto, find_key};
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ use std::fs::{self, OpenOptions};
|
||||
use std::io::{Write};
|
||||
use binrw::{BinRead, BinReaderExt};
|
||||
|
||||
use crate::common;
|
||||
use crate::utils::common;
|
||||
|
||||
#[derive(BinRead)]
|
||||
struct Header {
|
||||
|
||||
@@ -4,7 +4,7 @@ use std::io::{Write, Read, Seek, SeekFrom, Cursor};
|
||||
use binrw::{BinRead, BinReaderExt};
|
||||
|
||||
use crate::utils::aes::{decrypt_aes128_cbc_nopad};
|
||||
use crate::common;
|
||||
use crate::utils::common;
|
||||
|
||||
#[derive(BinRead)]
|
||||
struct Header {
|
||||
@@ -99,8 +99,9 @@ pub fn extract_invincible_image(mut file: &File, output_folder: &str) -> Result<
|
||||
file.seek(SeekFrom::Current(header.skip_size.into()))?;
|
||||
}
|
||||
|
||||
let key = b"\x32\xe5\x26\x1e\x22\x67\x5e\x93\x20\xcf\x35\x91\x7c\x63\x7a\x36";
|
||||
let iv = b"\xe3\x9f\x36\x39\x56\x9a\x6b\x8d\x3f\x2e\xc9\x44\xd9\xbc\xec\x43";
|
||||
//v3 key + iv
|
||||
let key: [u8; 16] = [0x32, 0xe5, 0x26, 0x1e, 0x22, 0x67, 0x5e, 0x93, 0x20, 0xcf, 0x35, 0x91, 0x7c, 0x63, 0x7a, 0x36];
|
||||
let iv: [u8; 16] = [0xe3, 0x9f, 0x36, 0x39, 0x56, 0x9a, 0x6b, 0x8d, 0x3f, 0x2e, 0xc9, 0x44, 0xd9, 0xbc, 0xec, 0x43];
|
||||
|
||||
println!("\nDecrypting data...");
|
||||
let decrypted_data = decrypt_aes128_cbc_nopad(&encrypted_data, &key, &iv)?;
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::path::{Path};
|
||||
use std::io::{Cursor, Write, Seek, SeekFrom};
|
||||
use binrw::{BinRead, BinReaderExt};
|
||||
|
||||
use crate::common;
|
||||
use crate::utils::common;
|
||||
use crate::keys;
|
||||
use crate::formats::msd::{decrypt_aes_salted_old, decrypt_aes_salted_tizen, decrypt_aes_tizen};
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::path::{Path};
|
||||
use std::io::{Cursor, Write, Seek, SeekFrom};
|
||||
use binrw::{BinRead, BinReaderExt};
|
||||
|
||||
use crate::common;
|
||||
use crate::utils::common;
|
||||
use crate::keys;
|
||||
use crate::formats::msd::{decrypt_aes_salted_tizen, decrypt_aes_tizen};
|
||||
|
||||
|
||||
+3
-19
@@ -1,10 +1,9 @@
|
||||
use std::fs::{self, File, OpenOptions};
|
||||
use std::path::{Path};
|
||||
use std::io::{Write, Cursor};
|
||||
use lz4::block::decompress;
|
||||
use lzma_rs::lzma_decompress;
|
||||
use std::io::{Write};
|
||||
|
||||
use crate::common;
|
||||
use crate::utils::common;
|
||||
use crate::utils::compression::{decompress_lzma, decompress_lz4};
|
||||
use crate::utils::lzop::{unlzop_to_file};
|
||||
use crate::utils::sparse::{unsparse_to_file};
|
||||
|
||||
@@ -32,21 +31,6 @@ fn parse_number(s: &str) -> Option<u64> {
|
||||
}
|
||||
}
|
||||
|
||||
fn decompress_lzma(compressed_data: &[u8]) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
|
||||
let mut input = Cursor::new(compressed_data);
|
||||
let mut output = Vec::new();
|
||||
|
||||
lzma_decompress(&mut input, &mut output)?;
|
||||
Ok(output)
|
||||
}
|
||||
|
||||
fn decompress_lz4(compressed_data: &[u8], original_size: i32) -> Result<Vec<u8>, std::io::Error> {
|
||||
match decompress(compressed_data, Some(original_size)) {
|
||||
Ok(decompressed) => Ok(decompressed),
|
||||
Err(e) => Err(std::io::Error::new(std::io::ErrorKind::InvalidData, e)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extract_mstar(file: &File, output_folder: &str) -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
let mut script = common::read_file(&file, 0, 32768)?;
|
||||
|
||||
@@ -5,7 +5,7 @@ use std::io::{Seek, SeekFrom, Read, Write};
|
||||
use binrw::{BinRead, BinReaderExt};
|
||||
use std::sync::OnceLock;
|
||||
|
||||
use crate::common;
|
||||
use crate::utils::common;
|
||||
|
||||
#[derive(BinRead)]
|
||||
struct TocEntry {
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::fs::{self, File, OpenOptions};
|
||||
use std::io::{Write, Cursor, Seek};
|
||||
use binrw::{BinRead, BinReaderExt};
|
||||
|
||||
use crate::common;
|
||||
use crate::utils::common;
|
||||
use crate::utils::aes::{decrypt_aes128_cbc_nopad};
|
||||
|
||||
#[derive(BinRead)]
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::fs::{self, File, OpenOptions};
|
||||
use std::io::{Write, Seek};
|
||||
use binrw::{BinRead, BinReaderExt};
|
||||
|
||||
use crate::common;
|
||||
use crate::utils::common;
|
||||
|
||||
pub fn is_mtk_upgrade_loader_file(file: &File) -> bool {
|
||||
let header = common::read_file(&file, 152, 4).expect("Failed to read from file.");
|
||||
|
||||
@@ -5,7 +5,7 @@ use std::io::{Write, Seek};
|
||||
|
||||
use binrw::{BinRead, BinReaderExt};
|
||||
|
||||
use crate::common;
|
||||
use crate::utils::common;
|
||||
|
||||
#[derive(BinRead)]
|
||||
struct Header {
|
||||
|
||||
+3
-11
@@ -1,12 +1,11 @@
|
||||
use std::str;
|
||||
use std::path::{Path};
|
||||
use std::io::{Read, Write};
|
||||
use std::io::{Write};
|
||||
use std::fs::{self, File, OpenOptions};
|
||||
|
||||
use binrw::{BinRead, BinReaderExt};
|
||||
use flate2::read::GzDecoder;
|
||||
|
||||
use crate::common;
|
||||
use crate::utils::common;
|
||||
use crate::utils::compression::{decompress_gzip};
|
||||
|
||||
#[derive(Debug, BinRead)]
|
||||
struct PIMG {
|
||||
@@ -41,13 +40,6 @@ pub fn is_nvt_timg_file(file: &File) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
fn decompress_gzip(compressed_data: &[u8]) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
|
||||
let mut decoder = GzDecoder::new(compressed_data);
|
||||
let mut decompressed = Vec::new();
|
||||
decoder.read_to_end(&mut decompressed)?;
|
||||
Ok(decompressed)
|
||||
}
|
||||
|
||||
pub fn extract_nvt_timg(mut file: &File, output_folder: &str) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let _timg = common::read_exact(&mut file, 288)?; //TIMG magic + header
|
||||
|
||||
|
||||
+9
-26
@@ -2,15 +2,14 @@ use std::fs::File;
|
||||
use std::path::Path;
|
||||
use std::fs::{self, OpenOptions};
|
||||
use std::io::{Write, Read, Cursor, Seek, SeekFrom};
|
||||
|
||||
use simd_adler32::adler32;
|
||||
use flate2::read::GzDecoder;
|
||||
use binrw::{BinRead, BinReaderExt};
|
||||
|
||||
use crate::keys;
|
||||
use crate::common;
|
||||
use crate::utils::common;
|
||||
use crate::utils::pana_dvd_crypto::{decrypt_data};
|
||||
use crate::utils::aes::{decrypt_aes128_cbc_nopad};
|
||||
use crate::utils::compression::{decompress_gzip};
|
||||
use crate::utils::lzss::{decompress_lzss};
|
||||
|
||||
#[derive(BinRead)]
|
||||
@@ -95,10 +94,7 @@ impl MainEntryHeader {
|
||||
pub fn find_key<'a>(key_array: &'a [&'a str], data: &[u8], expected_magic: &[u8]) -> Result<Option<[u8; 8]>, Box<dyn std::error::Error>> {
|
||||
for key_hex in key_array {
|
||||
let key_bytes = hex::decode(key_hex)?;
|
||||
let key_array: [u8; 8] = match key_bytes.as_slice().try_into() {
|
||||
Ok(k) => k,
|
||||
Err(_) => continue,
|
||||
};
|
||||
let key_array: [u8; 8] = key_bytes.as_slice().try_into()?;
|
||||
let decrypted = decrypt_data(data, &key_array);
|
||||
|
||||
if decrypted.starts_with(expected_magic) {
|
||||
@@ -111,18 +107,12 @@ pub fn find_key<'a>(key_array: &'a [&'a str], data: &[u8], expected_magic: &[u8]
|
||||
pub fn find_aes_key_pair<'a>(key_array: &'a [(&'a str, &'a str)], data: &[u8], expected_magic: &[u8], magic_offset: usize) -> Result<Option<([u8; 16], [u8; 8])>, Box<dyn std::error::Error>> {
|
||||
for (aes_key_hex, cust_key_hex) in key_array {
|
||||
let aes_key_bytes = hex::decode(aes_key_hex)?;
|
||||
let aes_key_array: [u8; 16] = match aes_key_bytes.as_slice().try_into() {
|
||||
Ok(k) => k,
|
||||
Err(_) => continue,
|
||||
};
|
||||
let iv = b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
|
||||
let aes_decrypted = decrypt_aes128_cbc_nopad(data, &aes_key_array, iv)?;
|
||||
let aes_key_array: [u8; 16] = aes_key_bytes.as_slice().try_into()?;
|
||||
let iv: [u8; 16] = [0x00; 16];
|
||||
let aes_decrypted = decrypt_aes128_cbc_nopad(data, &aes_key_array, &iv)?;
|
||||
|
||||
let key_bytes = hex::decode(cust_key_hex)?;
|
||||
let key_array: [u8; 8] = match key_bytes.as_slice().try_into() {
|
||||
Ok(k) => k,
|
||||
Err(_) => continue,
|
||||
};
|
||||
let key_array: [u8; 8] = key_bytes.as_slice().try_into()?;
|
||||
let decrypted = decrypt_data(&aes_decrypted, &key_array);
|
||||
|
||||
if decrypted[magic_offset..].starts_with(expected_magic) {
|
||||
@@ -146,13 +136,6 @@ pub fn is_pana_dvd_file(mut file: &File) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
fn decompress_gzip(data: &[u8]) -> std::io::Result<Vec<u8>> {
|
||||
let mut decoder = GzDecoder::new(data);
|
||||
let mut decompressed = Vec::new();
|
||||
decoder.read_to_end(&mut decompressed)?;
|
||||
Ok(decompressed)
|
||||
}
|
||||
|
||||
pub fn extract_pana_dvd(mut file: &File, output_folder: &str) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let init_pos = file.stream_position()?;
|
||||
file.seek(SeekFrom::Start(0))?;
|
||||
@@ -175,10 +158,10 @@ pub fn extract_pana_dvd(mut file: &File, output_folder: &str) -> Result<(), Box<
|
||||
} else if let Some((aes_key_array, key_array)) = find_aes_key_pair(&keys::PANA_DVD_AESPAIR, &enc_header, b"PROG", 96)? {
|
||||
println!("Found AES key pair: aes={} cust={}", hex::encode_upper(aes_key_array), hex::encode_upper(key_array));
|
||||
matching_key = Some(key_array);
|
||||
let iv = b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
|
||||
let iv: [u8; 16] = [0x00; 16];
|
||||
|
||||
println!("Decrypting AES...\n");
|
||||
let aes_decrypted = decrypt_aes128_cbc_nopad(&file_reader.get_ref()[48..], &aes_key_array, iv)?;
|
||||
let aes_decrypted = decrypt_aes128_cbc_nopad(&file_reader.get_ref()[48..], &aes_key_array, &iv)?;
|
||||
file_reader = Cursor::new(aes_decrypted); //set the file reader to use AES decrypted stream
|
||||
|
||||
file_reader.seek(SeekFrom::Start(48))?;
|
||||
|
||||
@@ -9,7 +9,7 @@ use aes::Aes256;
|
||||
use ecb::{Decryptor, cipher::{BlockDecryptMut, KeyInit, generic_array::GenericArray}};
|
||||
use binrw::{BinRead, BinReaderExt};
|
||||
|
||||
use crate::common;
|
||||
use crate::utils::common;
|
||||
use crate::keys;
|
||||
|
||||
#[derive(BinRead)]
|
||||
|
||||
+3
-12
@@ -1,11 +1,10 @@
|
||||
use std::path::{Path};
|
||||
use std::fs::{self, File, OpenOptions};
|
||||
use std::io;
|
||||
use binrw::{BinRead, BinReaderExt};
|
||||
use flate2::read::ZlibDecoder;
|
||||
use std::io::{Write, Read, Seek, SeekFrom};
|
||||
use std::io::{Write, Seek, SeekFrom};
|
||||
|
||||
use crate::common;
|
||||
use crate::utils::common;
|
||||
use crate::utils::compression::{decompress_zlib};
|
||||
|
||||
#[derive(BinRead)]
|
||||
struct Header {
|
||||
@@ -60,14 +59,6 @@ pub fn is_pup_file(file: &File) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
fn decompress_zlib(data: &[u8]) -> io::Result<Vec<u8>> {
|
||||
let mut decoder = ZlibDecoder::new(data);
|
||||
let mut decompressed = Vec::new();
|
||||
decoder.read_to_end(&mut decompressed)?;
|
||||
|
||||
Ok(decompressed)
|
||||
}
|
||||
|
||||
pub fn extract_pup(mut file: &File, output_folder: &str) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let header: Header = file.read_le()?;
|
||||
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ use std::io::{Write, Seek, Read, Cursor};
|
||||
use tar::Archive;
|
||||
use binrw::{BinRead, BinReaderExt};
|
||||
|
||||
use crate::common;
|
||||
use crate::utils::common;
|
||||
use crate::utils::aes::{decrypt_aes128_cbc_nopad, decrypt_aes128_cbc_pcks7};
|
||||
|
||||
static FILE_KEY: [u8; 16] = [
|
||||
|
||||
+2
-2
@@ -3,7 +3,7 @@ use std::fs::{self, File, OpenOptions};
|
||||
use binrw::{BinRead, BinReaderExt};
|
||||
use std::io::{Write, Seek, SeekFrom, Cursor};
|
||||
|
||||
use crate::common;
|
||||
use crate::utils::common;
|
||||
use crate::keys;
|
||||
use crate::utils::aes::{decrypt_aes128_cbc_pcks7};
|
||||
|
||||
@@ -126,7 +126,7 @@ fn actually_extract_ruf(mut file: &File, output_folder: &str, start_offset: u64)
|
||||
|
||||
let mut key: Option<&str> = None;
|
||||
let key_bytes;
|
||||
let iv_bytes = hex::decode("00000000000000000000000000000000")?.as_slice().try_into()?;
|
||||
let iv_bytes: [u8; 16] = [0x00; 16];
|
||||
|
||||
//find key
|
||||
for (prefix, value) in keys::RUF {
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ use std::path::Path;
|
||||
use std::fs::{self, OpenOptions};
|
||||
use std::io::{Write, Read, Cursor, Seek};
|
||||
|
||||
use crate::common;
|
||||
use crate::utils::common;
|
||||
|
||||
fn decrypt_xor(data: &[u8]) -> Vec<u8> {
|
||||
let key_bytes = b"\xCC\xF0\xC8\xC4\xC6\xCA\xCC\xDA\xC6\xCA\xCC\xDA\xC6\xCA\xCC\xDA\xC6\xCA\xCC\xDA\xC6\xCA\xCC\xDA\xC6\xCA\xCC\xDA\xC6\xCA\xCC\xDA";
|
||||
|
||||
@@ -5,7 +5,7 @@ use std::io::{Write};
|
||||
use hex::decode;
|
||||
use sha1::{Digest, Sha1};
|
||||
|
||||
use crate::common;
|
||||
use crate::utils::common;
|
||||
use crate::keys;
|
||||
use crate::utils::aes::{decrypt_aes128_cbc_pcks7};
|
||||
|
||||
|
||||
+3
-11
@@ -1,10 +1,10 @@
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::fs::{self, File, OpenOptions};
|
||||
use std::io::{self, Read, Seek, SeekFrom, Write};
|
||||
use flate2::read::ZlibDecoder;
|
||||
use std::io::{Seek, SeekFrom, Write};
|
||||
|
||||
use crate::common;
|
||||
use crate::utils::common;
|
||||
use crate::utils::aes::{decrypt_aes128_cbc_pcks7};
|
||||
use crate::utils::compression::{decompress_zlib};
|
||||
|
||||
pub fn is_sddl_sec_file(file: &File) -> bool {
|
||||
let header = common::read_file(&file, 0, 8).expect("Failed to read from file.");
|
||||
@@ -56,14 +56,6 @@ fn decipher(s: &[u8], len_: usize) -> Vec<u8> {
|
||||
out
|
||||
}
|
||||
|
||||
fn decompress_zlib(data: &[u8]) -> io::Result<Vec<u8>> {
|
||||
let mut decoder = ZlibDecoder::new(data);
|
||||
let mut decompressed = Vec::new();
|
||||
decoder.read_to_end(&mut decompressed)?;
|
||||
|
||||
Ok(decompressed)
|
||||
}
|
||||
|
||||
pub fn extract_sddl_sec(file: &File, output_folder: &str) -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
let file_size = file.metadata()?.len();
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ use std::fs::{self, File, OpenOptions};
|
||||
use std::io::{Write, Seek, SeekFrom};
|
||||
use binrw::{BinRead, BinReaderExt};
|
||||
|
||||
use crate::common;
|
||||
use crate::utils::common;
|
||||
|
||||
#[derive(BinRead)]
|
||||
struct Header {
|
||||
|
||||
@@ -4,7 +4,7 @@ use std::fs::{self, OpenOptions};
|
||||
use std::io::{Cursor, Write};
|
||||
use binrw::{BinRead, BinReaderExt};
|
||||
|
||||
use crate::common;
|
||||
use crate::utils::common;
|
||||
use crate::formats;
|
||||
|
||||
//thx sony
|
||||
@@ -59,7 +59,7 @@ struct Entry {
|
||||
|
||||
pub fn is_sony_bdp_file(file: &File) -> bool {
|
||||
let header = common::read_file(&file, 0, 4).expect("Failed to read from file.");
|
||||
if header == b"\x01\x73\xEC\xC9" || header == b"\x01\x73\xEC\x1F" { //MSB1x, MSB0x
|
||||
if header == b"\x01\x73\xEC\xC9" || header == b"\x01\x73\xEC\x1F" || header == b"\xEC\x7D\xB0\xB0" { //MSB1x, MSB0x, BDPPxx
|
||||
true
|
||||
} else {
|
||||
false
|
||||
|
||||
+4
-2
@@ -1,3 +1,5 @@
|
||||
//This file is used to store keys for formats that rely on using different keys.
|
||||
|
||||
//samsung old keys
|
||||
//github.com/george-hopkins/samygo-patcher
|
||||
pub static SAMSUNG: &[(&str, &str)] = &[
|
||||
@@ -78,10 +80,10 @@ pub static EPK3: &[(&str, &str)] = &[
|
||||
|
||||
//pana dvd keys (no AES)
|
||||
pub static PANA_DVD_KEYONLY: &[&str] = &[
|
||||
("08E03D859AF9F3EE"), //B3A25A0B9D864F08 # 87 devices, ..-~2011
|
||||
("08E03D859AF9F3EE"), //B3A25A0B9D864F08 # 87 firmwares, ..-~2011
|
||||
];
|
||||
|
||||
//pana dvd keys (PANAEUSB pair (AES + cust))
|
||||
pub static PANA_DVD_AESPAIR: &[(&str, &str)] = &[
|
||||
("62A39E1C5594AE09244EB326EF7938FA", "06C943F3B997F7E0"), //# 8 devices, ~2018
|
||||
("62A39E1C5594AE09244EB326EF7938FA", "06C943F3B997F7E0"), //# 9 firmwares, ~2018
|
||||
];
|
||||
@@ -1,4 +1,3 @@
|
||||
mod common;
|
||||
mod formats;
|
||||
mod keys;
|
||||
mod utils;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
pub mod common;
|
||||
pub mod aes;
|
||||
pub mod pana_dvd_crypto;
|
||||
pub mod lzss;
|
||||
pub mod lzop;
|
||||
pub mod sparse;
|
||||
pub mod compression;
|
||||
@@ -0,0 +1,36 @@
|
||||
use std::io::{self, Read, Cursor};
|
||||
|
||||
use flate2::read::ZlibDecoder;
|
||||
use flate2::read::GzDecoder;
|
||||
use lzma_rs::lzma_decompress;
|
||||
use lz4::block::decompress;
|
||||
|
||||
pub fn decompress_zlib(data: &[u8]) -> io::Result<Vec<u8>> {
|
||||
let mut decoder = ZlibDecoder::new(data);
|
||||
let mut decompressed = Vec::new();
|
||||
decoder.read_to_end(&mut decompressed)?;
|
||||
|
||||
Ok(decompressed)
|
||||
}
|
||||
|
||||
pub fn decompress_gzip(compressed_data: &[u8]) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
|
||||
let mut decoder = GzDecoder::new(compressed_data);
|
||||
let mut decompressed = Vec::new();
|
||||
decoder.read_to_end(&mut decompressed)?;
|
||||
Ok(decompressed)
|
||||
}
|
||||
|
||||
pub fn decompress_lzma(compressed_data: &[u8]) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
|
||||
let mut input = Cursor::new(compressed_data);
|
||||
let mut output = Vec::new();
|
||||
|
||||
lzma_decompress(&mut input, &mut output)?;
|
||||
Ok(output)
|
||||
}
|
||||
|
||||
pub fn decompress_lz4(compressed_data: &[u8], original_size: i32) -> Result<Vec<u8>, std::io::Error> {
|
||||
match decompress(compressed_data, Some(original_size)) {
|
||||
Ok(decompressed) => Ok(decompressed),
|
||||
Err(e) => Err(std::io::Error::new(std::io::ErrorKind::InvalidData, e)),
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -4,7 +4,7 @@ use std::path::{PathBuf};
|
||||
use std::io::{Cursor, Write};
|
||||
|
||||
use simd_adler32::adler32;
|
||||
use crate::common;
|
||||
use crate::utils::common;
|
||||
|
||||
#[derive(BinRead)]
|
||||
struct LzopHeader {
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ use std::fs::OpenOptions;
|
||||
use std::path::{PathBuf};
|
||||
use std::io::{Cursor, Seek, SeekFrom, Write};
|
||||
|
||||
use crate::common;
|
||||
use crate::utils::common;
|
||||
|
||||
#[derive(BinRead)]
|
||||
struct SparseHeader {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
| Panasonic Blu-Ray (PANA_DVD) | Panasonic Blu-Ray Players/Recorders | Only some files are supported (**depends on keys**) | - |
|
||||
| Philips UPG | Philips pre-TPVision TVS 2008-2013 | Only some files are supported (**depends on keys**) | https://github.com/frederic/pflupg-tool |
|
||||
| PUP | Sony PlayStation 4/ PlayStation 5 | File has to be decrypted | https://github.com/Zer0xFF/ps4-pup-unpacker |
|
||||
| Roku | Roku TVs/players | Most files should work, but encrypted images contained within will not be decrypted. | - |
|
||||
| RUF | Samsung Broadcom-based Blu-Ray players | Only BD-P1600 is supported (**depends on keys**) | - |
|
||||
| RVP/MVP | Sharp Blu-Ray players/recorders | Only supports older files (XOR encrypted) | - |
|
||||
| Samsung | Old Samsung TV firmwares pre 2013 | Only some files are supported (**depends on keys**) | https://github.com/george-hopkins/samygo-patcher |
|
||||
|
||||
Reference in New Issue
Block a user