From 2db38962af44346466b537abe95a33ab7806a69e Mon Sep 17 00:00:00 2001 From: lifegpc Date: Sun, 2 Nov 2025 22:50:59 +0800 Subject: [PATCH] Add xor key to schema --- src/scripts/musica/archive/paz.json | 3 ++- src/scripts/musica/archive/paz.rs | 33 +++++++++++++++++++---------- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/scripts/musica/archive/paz.json b/src/scripts/musica/archive/paz.json index 1271199..9b82e13 100644 --- a/src/scripts/musica/archive/paz.json +++ b/src/scripts/musica/archive/paz.json @@ -41,6 +41,7 @@ "sc": "WdLwefCN", "avi": "wdiz7GQH" }, - "Signature": 2223998086 + "Signature": 2223998086, + "XorKey": 225 } } \ No newline at end of file diff --git a/src/scripts/musica/archive/paz.rs b/src/scripts/musica/archive/paz.rs index 4946ce4..b5e8056 100644 --- a/src/scripts/musica/archive/paz.rs +++ b/src/scripts/musica/archive/paz.rs @@ -31,6 +31,7 @@ struct Schema { type_keys: HashMap, /// PAZ file signature signature: u32, + xor_key: u8, } impl Schema { @@ -266,6 +267,7 @@ impl PazArc { start_offset += 4; let xor_key = (index_size >> 24) as u8; if xor_key != 0 { + eprintln!("Xor Key: {}", xor_key); let t = xor_key as u32; index_size ^= t << 24 | t << 16 | t << 8 | t; } @@ -588,7 +590,8 @@ impl PazArcWriter { writer.write_u32(0)?; // Placeholder for index size { let blowfish: Blowfish = Blowfish::new(&arc_key.index_key)?; - let mut index_stream = BlowfishEncryptor::new(blowfish, &mut writer); + let stream = XoredStream::new(&mut writer, schema.xor_key); + let mut index_stream = BlowfishEncryptor::new(blowfish, stream); index_stream.write_u32(entries.len() as u32)?; if let Some(mov_data) = &mov_key { index_stream.write_all(mov_data)?; @@ -602,7 +605,12 @@ impl PazArcWriter { if index_size >> 24 != 0 { return Err(anyhow::anyhow!("PAZ index size too large")); } - writer.write_u32_at(start_offset, index_size)?; + if schema.xor_key != 0 { + let mut stream = XoredStream::new(&mut writer, schema.xor_key); + stream.write_u32_at(start_offset, index_size)?; + } else { + writer.write_u32_at(start_offset, index_size)?; + }; Ok(PazArcWriter { writer, headers: entries, @@ -634,7 +642,8 @@ impl Archive for PazArcWriter { if let Some(data_key) = &self.arc_key.data_key { let blowfish: Blowfish = Blowfish::new(&data_key.bytes)?; entry.offset = self.writer.stream_position()?; - let stream = BlowfishEncryptor::new(blowfish, &mut self.writer); + let stream = XoredStream::new(&mut self.writer, self.schema.xor_key); + let stream = BlowfishEncryptor::new(blowfish, stream); let mut type_key = None; if self.schema.version > 0 { if let Some(tkey) = self.schema.get_type_key(&entry, self.is_audio) { @@ -642,7 +651,7 @@ impl Archive for PazArcWriter { } } let writer = MemDataKeyWriter { - inner: stream, + inner: Box::new(stream), cache: MemWriter::new(), type_key, entry, @@ -677,7 +686,8 @@ impl Archive for PazArcWriter { } let blowfish: Blowfish = Blowfish::new(&data_key.bytes)?; entry.offset = self.writer.stream_position()?; - let stream = BlowfishEncryptor::new(blowfish, &mut self.writer); + let stream = XoredStream::new(&mut self.writer, self.schema.xor_key); + let stream = BlowfishEncryptor::new(blowfish, stream); if self.schema.version > 0 { if let Some(tkey) = self.schema.get_type_key(&entry, self.is_audio) { let key = format!("{} {:08X} {}", entry.name.to_ascii_lowercase(), size, tkey); @@ -710,7 +720,8 @@ impl Archive for PazArcWriter { self.writer.seek(SeekFrom::Start(start_offset))?; { let blowfish: Blowfish = Blowfish::new(&self.arc_key.index_key)?; - let mut index_stream = BlowfishEncryptor::new(blowfish, &mut self.writer); + let stream = XoredStream::new(&mut self.writer, self.schema.xor_key); + let mut index_stream = BlowfishEncryptor::new(blowfish, stream); index_stream.write_u32(self.headers.len() as u32)?; if let Some(mov_data) = &self.mov_key { index_stream.write_all(mov_data)?; @@ -747,8 +758,8 @@ impl<'a> Drop for DateKeyWriter<'a> { } } -struct MemDataKeyWriter<'a, T: Write + Seek> { - inner: BlowfishEncryptor, +struct MemDataKeyWriter<'a> { + inner: Box, cache: MemWriter, type_key: Option, entry: &'a mut PazEntry, @@ -756,7 +767,7 @@ struct MemDataKeyWriter<'a, T: Write + Seek> { version: u32, } -impl<'a, T: Write + Seek> Write for MemDataKeyWriter<'a, T> { +impl<'a> Write for MemDataKeyWriter<'a> { fn write(&mut self, buf: &[u8]) -> std::io::Result { self.cache.write(buf) } @@ -766,7 +777,7 @@ impl<'a, T: Write + Seek> Write for MemDataKeyWriter<'a, T> { } } -impl<'a, T: Write + Seek> Seek for MemDataKeyWriter<'a, T> { +impl<'a> Seek for MemDataKeyWriter<'a> { fn seek(&mut self, pos: std::io::SeekFrom) -> std::io::Result { self.cache.seek(pos) } @@ -780,7 +791,7 @@ impl<'a, T: Write + Seek> Seek for MemDataKeyWriter<'a, T> { } } -impl<'a, T: Write + Seek> Drop for MemDataKeyWriter<'a, T> { +impl<'a> Drop for MemDataKeyWriter<'a> { fn drop(&mut self) { let data = &self.cache.data; self.entry.unpacked_size = data.len() as u32;