mirror of
https://github.com/beerpiss/saekawa.git
synced 2025-02-20 03:51:04 +01:00
Fix some bugs with ICF decoding
This commit is contained in:
parent
31fe19a4f5
commit
9cf8803035
37
src/icf.rs
37
src/icf.rs
@ -4,7 +4,6 @@ use aes::cipher::{block_padding::NoPadding, BlockDecryptMut, KeyIvInit};
|
|||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
use binary_reader::{BinaryReader, Endian};
|
use binary_reader::{BinaryReader, Endian};
|
||||||
use chrono::{NaiveDate, NaiveDateTime};
|
use chrono::{NaiveDate, NaiveDateTime};
|
||||||
use log::warn;
|
|
||||||
|
|
||||||
type Aes128CbcDec = cbc::Decryptor<aes::Aes128>;
|
type Aes128CbcDec = cbc::Decryptor<aes::Aes128>;
|
||||||
|
|
||||||
@ -167,8 +166,9 @@ pub fn decode_icf(data: &mut [u8]) -> Result<Vec<IcfData>> {
|
|||||||
|
|
||||||
let mut entries: Vec<IcfData> = Vec::with_capacity(entry_count);
|
let mut entries: Vec<IcfData> = Vec::with_capacity(entry_count);
|
||||||
for _ in 0..entry_count {
|
for _ in 0..entry_count {
|
||||||
let sig = rd.read_bytes(4)?;
|
let sig = rd.read_u32()?;
|
||||||
if sig[0] != 2 || sig[1] != 1 {
|
|
||||||
|
if sig != 0x0102 && sig != 0x0201 {
|
||||||
return Err(anyhow!("Container does not start with signature (0x0102)"));
|
return Err(anyhow!("Container does not start with signature (0x0102)"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,8 +179,6 @@ pub fn decode_icf(data: &mut [u8]) -> Result<Vec<IcfData>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let (version, datetime, required_system_version) = decode_icf_container_data(&mut rd)?;
|
|
||||||
|
|
||||||
let data: IcfData = match container_type {
|
let data: IcfData = match container_type {
|
||||||
0x0000 | 0x0001 | 0x0002 => {
|
0x0000 | 0x0001 | 0x0002 => {
|
||||||
for _ in 0..2 {
|
for _ in 0..2 {
|
||||||
@ -189,6 +187,8 @@ pub fn decode_icf(data: &mut [u8]) -> Result<Vec<IcfData>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let (version, datetime, required_system_version) = decode_icf_container_data(&mut rd)?;
|
||||||
|
|
||||||
match container_type {
|
match container_type {
|
||||||
0x0000 => IcfData::System(IcfInnerData {
|
0x0000 => IcfData::System(IcfInnerData {
|
||||||
id: platform_id.clone(),
|
id: platform_id.clone(),
|
||||||
@ -211,20 +211,29 @@ pub fn decode_icf(data: &mut [u8]) -> Result<Vec<IcfData>> {
|
|||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
0x0101 => {
|
_ => {
|
||||||
let (target_version, _, _) = decode_icf_container_data(&mut rd)?;
|
// PATCH container type also encode the patch's sequence number
|
||||||
|
// in the higher 16 bits.
|
||||||
|
// The lower 16 bits will always be 1.
|
||||||
|
let sequence_number = (container_type >> 8) as u8;
|
||||||
|
|
||||||
|
if (container_type & 1) == 0 || sequence_number == 0 {
|
||||||
|
println!("Unknown ICF container type {container_type:#06x} at byte {:#06x}, skipping", rd.pos);
|
||||||
|
rd.read_bytes(32)?;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let (target_version, target_datetime, _) = decode_icf_container_data(&mut rd)?;
|
||||||
|
let (source_version, _, source_required_system_version) = decode_icf_container_data(&mut rd)?;
|
||||||
|
|
||||||
IcfData::Patch(IcfPatchData {
|
IcfData::Patch(IcfPatchData {
|
||||||
id: app_id.clone(),
|
id: app_id.clone(),
|
||||||
source_version: version,
|
source_version,
|
||||||
target_version,
|
target_version,
|
||||||
required_system_version,
|
required_system_version: source_required_system_version,
|
||||||
datetime,
|
datetime: target_datetime,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
_ => {
|
|
||||||
warn!("Unknown ICF container type {container_type}");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
entries.push(data);
|
entries.push(data);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user