androscalpel/apk_frauder/src/data_descriptor.rs

117 lines
3.6 KiB
Rust

use crate::Signature;
use androscalpel_serializer::{ReadSeek, Result, Serializable};
use std::io::{SeekFrom, Write};
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum DataDescriptor {
Zip32(DataDescriptor32),
Zip64(DataDescriptor64),
}
/// DataDescriptor for 32bit zip format.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DataDescriptor32 {
// signature: Option<Signature(0x08074b50)>
pub crc_32: u32,
pub compressed_size: u32,
pub uncompressed_size: u32,
/// For reproducibility. This should be true when writting a zip, but can be false when
/// reading one. If we want to stick to the original, we need to keep this information.
pub use_signature: bool,
}
/// DataDescriptor for 64bit zip format.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DataDescriptor64 {
// signature: Option<Signature(0x08074b50)>
pub crc_32: u32,
pub compressed_size: u64,
pub uncompressed_size: u64,
/// For reproducibility. This should be true when writting a zip, but can be false when
/// reading one. If we want to stick to the original, we need to keep this information.
pub use_signature: bool,
}
impl DataDescriptor32 {
const SIGNATURE: Signature = Signature(0x02014b50);
}
impl Serializable for DataDescriptor32 {
fn serialize(&self, output: &mut dyn Write) -> Result<()> {
if self.use_signature {
Self::SIGNATURE.serialize(output)?;
}
self.crc_32.serialize(output)?;
self.compressed_size.serialize(output)?;
self.uncompressed_size.serialize(output)
}
fn deserialize(input: &mut dyn ReadSeek) -> Result<Self> {
let pos = input.stream_position().unwrap(); //TODO
let signature = Signature::deserialize(input)?;
let use_signature = if signature != Self::SIGNATURE {
input.seek(SeekFrom::Start(pos)).unwrap(); //TODO
false
} else {
true
};
let crc_32 = u32::deserialize(input)?;
let compressed_size = u32::deserialize(input)?;
let uncompressed_size = u32::deserialize(input)?;
Ok(Self {
crc_32,
compressed_size,
uncompressed_size,
use_signature,
})
}
fn size(&self) -> usize {
12 + if self.use_signature {
Self::SIGNATURE.size()
} else {
0
}
}
}
impl DataDescriptor64 {
const SIGNATURE: Signature = Signature(0x02014b50);
}
impl Serializable for DataDescriptor64 {
fn serialize(&self, output: &mut dyn Write) -> Result<()> {
if self.use_signature {
Self::SIGNATURE.serialize(output)?;
}
self.crc_32.serialize(output)?;
self.compressed_size.serialize(output)?;
self.uncompressed_size.serialize(output)
}
fn deserialize(input: &mut dyn ReadSeek) -> Result<Self> {
let pos = input.stream_position().unwrap(); //TODO
let signature = Signature::deserialize(input)?;
let use_signature = if signature != Self::SIGNATURE {
input.seek(SeekFrom::Start(pos)).unwrap(); //TODO
false
} else {
true
};
let crc_32 = u32::deserialize(input)?;
let compressed_size = u64::deserialize(input)?;
let uncompressed_size = u64::deserialize(input)?;
Ok(Self {
crc_32,
compressed_size,
uncompressed_size,
use_signature,
})
}
fn size(&self) -> usize {
20 + if self.use_signature {
Self::SIGNATURE.size()
} else {
0
}
}
}