put extra field in another file
This commit is contained in:
parent
fafbdb6537
commit
bea2b9ffc0
3 changed files with 142 additions and 137 deletions
139
apk_frauder/src/extra_fields.rs
Normal file
139
apk_frauder/src/extra_fields.rs
Normal file
|
|
@ -0,0 +1,139 @@
|
||||||
|
use std::io::{Cursor, Write};
|
||||||
|
|
||||||
|
use androscalpel_serializer::{ReadSeek, Result, Serializable};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub enum ExtraField {
|
||||||
|
Zip64(Zip64ExtraField),
|
||||||
|
Generic(GenericExtraField),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExtraField {
|
||||||
|
fn to_generic(&self) -> Result<GenericExtraField> {
|
||||||
|
match self {
|
||||||
|
Self::Zip64(field) => field.to_generic_field(),
|
||||||
|
Self::Generic(field) => Ok(field.clone()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Serializable for ExtraField {
|
||||||
|
fn serialize(&self, output: &mut dyn Write) -> Result<()> {
|
||||||
|
self.to_generic()?.serialize(output)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deserialize(input: &mut dyn ReadSeek) -> Result<Self> {
|
||||||
|
Ok(Self::Generic(GenericExtraField::deserialize(input)?))
|
||||||
|
|
||||||
|
/*
|
||||||
|
match field.id {
|
||||||
|
Zip64ExtraField::ID => Ok(Self::Zip64(Zip64ExtraField::from_generic(&field)?)),
|
||||||
|
_ => Ok(Self::Generic(field)),
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
fn size(&self) -> usize {
|
||||||
|
self.to_generic().unwrap().size()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct Zip64ExtraField {
|
||||||
|
pub original_size: Option<u64>,
|
||||||
|
pub compressed_size: Option<u64>,
|
||||||
|
pub offset_header: Option<u64>,
|
||||||
|
pub disk_number: Option<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Zip64ExtraField {
|
||||||
|
pub const ID: u16 = 0x0001;
|
||||||
|
fn to_generic_field(&self) -> Result<GenericExtraField> {
|
||||||
|
let mut data = Cursor::new(Vec::<u8>::new());
|
||||||
|
if let Some(original_size) = self.original_size {
|
||||||
|
original_size.serialize(&mut data)?;
|
||||||
|
}
|
||||||
|
if let Some(compressed_size) = self.compressed_size {
|
||||||
|
compressed_size.serialize(&mut data)?;
|
||||||
|
}
|
||||||
|
if let Some(offset_header) = self.offset_header {
|
||||||
|
offset_header.serialize(&mut data)?;
|
||||||
|
}
|
||||||
|
if let Some(disk_number) = self.disk_number {
|
||||||
|
disk_number.serialize(&mut data)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(GenericExtraField {
|
||||||
|
id: Self::ID,
|
||||||
|
data: data.into_inner(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_generic(
|
||||||
|
field: &GenericExtraField,
|
||||||
|
original_size: bool,
|
||||||
|
compressed_size: bool,
|
||||||
|
offset_header: bool,
|
||||||
|
disk_number: bool,
|
||||||
|
) -> Result<Self> {
|
||||||
|
assert_eq!(field.id, Self::ID);
|
||||||
|
let mut data = Cursor::new(&field.data);
|
||||||
|
let original_size = if original_size {
|
||||||
|
Some(u64::deserialize(&mut data)?)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
let compressed_size = if compressed_size {
|
||||||
|
Some(u64::deserialize(&mut data)?)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
let offset_header = if offset_header {
|
||||||
|
Some(u64::deserialize(&mut data)?)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
let disk_number = if disk_number {
|
||||||
|
Some(u32::deserialize(&mut data)?)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
Ok(Self {
|
||||||
|
original_size,
|
||||||
|
compressed_size,
|
||||||
|
offset_header,
|
||||||
|
disk_number,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct GenericExtraField {
|
||||||
|
pub id: u16,
|
||||||
|
pub data: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Serializable for GenericExtraField {
|
||||||
|
fn serialize(&self, output: &mut dyn Write) -> Result<()> {
|
||||||
|
self.id.serialize(output)?;
|
||||||
|
(self.data.len() as u16).serialize(output)?;
|
||||||
|
for c in &self.data {
|
||||||
|
c.serialize(output)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deserialize(input: &mut dyn ReadSeek) -> Result<Self> {
|
||||||
|
let id = u16::deserialize(input)?;
|
||||||
|
let data_size = u16::deserialize(input)?;
|
||||||
|
let mut data = vec![];
|
||||||
|
for _ in 0..data_size {
|
||||||
|
data.push(u8::deserialize(input)?);
|
||||||
|
}
|
||||||
|
Ok(Self { id, data })
|
||||||
|
}
|
||||||
|
|
||||||
|
fn size(&self) -> usize {
|
||||||
|
4 + self.data.len()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
use std::io::{Cursor, SeekFrom, Write};
|
use std::io::{SeekFrom, Write};
|
||||||
|
|
||||||
|
use crate::extra_fields::{ExtraField, GenericExtraField, Zip64ExtraField};
|
||||||
use crate::{cp437, Signature};
|
use crate::{cp437, Signature};
|
||||||
use androscalpel_serializer::{ReadSeek, Result, Serializable};
|
use androscalpel_serializer::{ReadSeek, Result, Serializable};
|
||||||
|
|
||||||
|
|
@ -8,142 +9,6 @@ pub enum Encoding {
|
||||||
UTF8,
|
UTF8,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
||||||
pub enum ExtraField {
|
|
||||||
Zip64(Zip64ExtraField),
|
|
||||||
Generic(GenericExtraField),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ExtraField {
|
|
||||||
fn to_generic(&self) -> Result<GenericExtraField> {
|
|
||||||
match self {
|
|
||||||
Self::Zip64(field) => field.to_generic_field(),
|
|
||||||
Self::Generic(field) => Ok(field.clone()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Serializable for ExtraField {
|
|
||||||
fn serialize(&self, output: &mut dyn Write) -> Result<()> {
|
|
||||||
self.to_generic()?.serialize(output)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize(input: &mut dyn ReadSeek) -> Result<Self> {
|
|
||||||
Ok(Self::Generic(GenericExtraField::deserialize(input)?))
|
|
||||||
|
|
||||||
/*
|
|
||||||
match field.id {
|
|
||||||
Zip64ExtraField::ID => Ok(Self::Zip64(Zip64ExtraField::from_generic(&field)?)),
|
|
||||||
_ => Ok(Self::Generic(field)),
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
fn size(&self) -> usize {
|
|
||||||
self.to_generic().unwrap().size()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
||||||
pub struct Zip64ExtraField {
|
|
||||||
original_size: Option<u64>,
|
|
||||||
compressed_size: Option<u64>,
|
|
||||||
offset_header: Option<u64>,
|
|
||||||
disk_number: Option<u32>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Zip64ExtraField {
|
|
||||||
const ID: u16 = 0x0001;
|
|
||||||
fn to_generic_field(&self) -> Result<GenericExtraField> {
|
|
||||||
let mut data = Cursor::new(Vec::<u8>::new());
|
|
||||||
if let Some(original_size) = self.original_size {
|
|
||||||
original_size.serialize(&mut data)?;
|
|
||||||
}
|
|
||||||
if let Some(compressed_size) = self.compressed_size {
|
|
||||||
compressed_size.serialize(&mut data)?;
|
|
||||||
}
|
|
||||||
if let Some(offset_header) = self.offset_header {
|
|
||||||
offset_header.serialize(&mut data)?;
|
|
||||||
}
|
|
||||||
if let Some(disk_number) = self.disk_number {
|
|
||||||
disk_number.serialize(&mut data)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(GenericExtraField {
|
|
||||||
id: Self::ID,
|
|
||||||
data: data.into_inner(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_generic(
|
|
||||||
field: &GenericExtraField,
|
|
||||||
original_size: bool,
|
|
||||||
compressed_size: bool,
|
|
||||||
offset_header: bool,
|
|
||||||
disk_number: bool,
|
|
||||||
) -> Result<Self> {
|
|
||||||
assert_eq!(field.id, Self::ID);
|
|
||||||
let mut data = Cursor::new(&field.data);
|
|
||||||
let original_size = if original_size {
|
|
||||||
Some(u64::deserialize(&mut data)?)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
let compressed_size = if compressed_size {
|
|
||||||
Some(u64::deserialize(&mut data)?)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
let offset_header = if offset_header {
|
|
||||||
Some(u64::deserialize(&mut data)?)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
let disk_number = if disk_number {
|
|
||||||
Some(u32::deserialize(&mut data)?)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
Ok(Self {
|
|
||||||
original_size,
|
|
||||||
compressed_size,
|
|
||||||
offset_header,
|
|
||||||
disk_number,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
||||||
pub struct GenericExtraField {
|
|
||||||
pub id: u16,
|
|
||||||
pub data: Vec<u8>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Serializable for GenericExtraField {
|
|
||||||
fn serialize(&self, output: &mut dyn Write) -> Result<()> {
|
|
||||||
self.id.serialize(output)?;
|
|
||||||
(self.data.len() as u16).serialize(output)?;
|
|
||||||
for c in &self.data {
|
|
||||||
c.serialize(output)?;
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize(input: &mut dyn ReadSeek) -> Result<Self> {
|
|
||||||
let id = u16::deserialize(input)?;
|
|
||||||
let data_size = u16::deserialize(input)?;
|
|
||||||
let mut data = vec![];
|
|
||||||
for _ in 0..data_size {
|
|
||||||
data.push(u8::deserialize(input)?);
|
|
||||||
}
|
|
||||||
Ok(Self { id, data })
|
|
||||||
}
|
|
||||||
|
|
||||||
fn size(&self) -> usize {
|
|
||||||
4 + self.data.len()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct FileHeader {
|
pub struct FileHeader {
|
||||||
// signature: Signature(0x02014b50)
|
// signature: Signature(0x02014b50)
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ use androscalpel_serializer::Serializable;
|
||||||
pub mod apk_signing_block;
|
pub mod apk_signing_block;
|
||||||
mod cp437;
|
mod cp437;
|
||||||
pub mod end_of_central_directory;
|
pub mod end_of_central_directory;
|
||||||
|
pub mod extra_fields;
|
||||||
pub mod file_header;
|
pub mod file_header;
|
||||||
|
|
||||||
use apk_signing_block::*;
|
use apk_signing_block::*;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue