This commit is contained in:
Jean-Marie 'Histausse' Mineau 2025-01-28 00:03:34 +01:00
parent 59d01d04db
commit 48817d1df8
Signed by: histausse
GPG key ID: B66AEEDA9B645AD2
6 changed files with 58 additions and 10 deletions

5
Cargo.lock generated
View file

@ -68,6 +68,7 @@ version = "0.1.0"
dependencies = [
"androscalpel_serializer",
"flate2",
"log",
"rand",
]
@ -260,9 +261,9 @@ checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4"
[[package]]
name = "log"
version = "0.4.20"
version = "0.4.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f"
[[package]]
name = "memchr"

View file

@ -8,4 +8,5 @@ edition = "2021"
[dependencies]
androscalpel_serializer = { version = "0.1.0", path = "../androscalpel_serializer" }
flate2 = { version = "1.0.28", features = ["rust_backend"] }
log = "0.4.25"
rand = "0.8.5"

View file

@ -10,6 +10,7 @@ use std::process::Command;
pub mod apk_signing_block;
pub mod compression;
mod cp437;
pub mod data_descriptor;
pub mod end_of_central_directory;
pub mod error;
pub mod extra_fields;
@ -18,6 +19,7 @@ pub mod local_file_header;
pub mod zip_reader;
pub mod zip_writer;
use data_descriptor::DataDescriptor;
use extra_fields::{ExtraField, Zip64ExtraField};
use file_header::FileHeader;
use local_file_header::LocalFileHeader;
@ -69,8 +71,8 @@ pub mod external_file_attributes {
pub struct FileInfo {
pub local_header: LocalFileHeader,
pub header: FileHeader,
pub data_descriptor: Option<DataDescriptor>,
}
// TODO: support data descriptor (MASK_USE_DATA_DESCRIPTOR)
impl FileInfo {
pub fn get_name(&self) -> String {
@ -204,6 +206,7 @@ pub fn replace_dex(
&mut dex,
file_info_ref.header.clone(),
Some(file_info_ref.local_header.clone()),
file_info_ref.data_descriptor.clone(),
);
}
if let Some(mut additionnal_files) = additionnal_files {
@ -214,6 +217,7 @@ pub fn replace_dex(
data,
file_info_ref.header.clone(),
Some(file_info_ref.local_header.clone()),
file_info_ref.data_descriptor.clone(),
);
}
}

View file

@ -1,9 +1,13 @@
use apk_frauder::ZipFileReader;
use std::collections::HashMap;
use std::env;
use std::fs::File;
use std::io::Cursor;
use apk_frauder::data_descriptor::{DataDescriptor, DataDescriptor32};
fn main() {
/*
apk_frauder::replace_dex(
"app-release.apk",
"app-instrumented.apk",
@ -18,5 +22,17 @@ fn main() {
env::var("HOME").expect("$HOME not set")
)),
None::<HashMap<String, Option<Cursor<&[u8]>>>>,
);*/
let mut file = File::open("test_data_descriptor.zip").expect("failed to open file");
let reader = ZipFileReader::new(&mut file);
println!("{:#?}", &reader.files[..4]);
assert_eq!(
reader.files[0].clone().data_descriptor,
Some(DataDescriptor::Zip32(DataDescriptor32 {
crc_32: reader.files[0].header.crc_32,
compressed_size: reader.files[0].header.compressed_size,
uncompressed_size: reader.files[0].header.uncompressed_size,
use_signature: false,
},),)
);
}

View file

@ -1,12 +1,16 @@
use log::warn;
use std::collections::HashMap;
use std::io::{Read, Seek, SeekFrom};
use crate::{
apk_signing_block::ApkSigningBlock, apk_signing_block::Magic, compression::CompressionMethod,
apk_signing_block::ApkSigningBlock,
apk_signing_block::Magic,
compression::CompressionMethod,
data_descriptor::{DataDescriptor, DataDescriptor32, DataDescriptor64},
end_of_central_directory::EndCentralDirectory,
end_of_central_directory::Zip64EndCentralDirectory,
end_of_central_directory::Zip64EndCentralDirectoryLocator, general_purpose_flags, FileHeader,
FileInfo, LocalFileHeader, Signature,
end_of_central_directory::Zip64EndCentralDirectoryLocator,
general_purpose_flags, FileHeader, FileInfo, LocalFileHeader, Signature,
};
use androscalpel_serializer::Serializable;
use flate2::read::DeflateDecoder;
@ -80,18 +84,34 @@ impl<T: Read + Seek> ZipFileReader<T> {
.seek(SeekFrom::Start(header.get_offset_local_header()))
.unwrap();
let local_header = LocalFileHeader::deserialize(&mut zip_file.data).unwrap();
zip_file.data.seek(SeekFrom::Start(pos_in_dir)).unwrap();
if (local_header.general_purpose_flags
let data_descriptor = if (local_header.general_purpose_flags
& general_purpose_flags::MASK_USE_DATA_DESCRIPTOR
!= 0)
|| (header.general_purpose_flags & general_purpose_flags::MASK_USE_DATA_DESCRIPTOR
!= 0)
{
panic!("Data Descriptor not yet suported");
}
warn!("Data Descriptor not yet suported");
zip_file
.data
.seek(SeekFrom::Current(header.compressed_size as i64))
.unwrap();
if zip_file.zip64_end_of_central_directory.is_some() {
Some(DataDescriptor::Zip64(
DataDescriptor64::deserialize(&mut zip_file.data).unwrap(),
))
} else {
Some(DataDescriptor::Zip32(
DataDescriptor32::deserialize(&mut zip_file.data).unwrap(),
))
}
} else {
None
};
zip_file.data.seek(SeekFrom::Start(pos_in_dir)).unwrap();
zip_file.files.push(FileInfo {
local_header,
header,
data_descriptor,
});
}
assert_eq!(size_read, cd_size);

View file

@ -2,6 +2,7 @@ use std::io;
use std::io::{Cursor, Read, Seek, SeekFrom, Write};
use crate::compression::CompressionMethod;
use crate::data_descriptor::DataDescriptor;
use crate::end_of_central_directory::{
EndCentralDirectory, Zip64EndCentralDirectory, Zip64EndCentralDirectoryLocator,
};
@ -63,6 +64,7 @@ impl<T: Write> ZipFileWriter<T> {
file: &mut U,
mut header: FileHeader,
local_header: Option<LocalFileHeader>,
data_descriptor: Option<DataDescriptor>,
) {
assert!(header.general_purpose_flags & general_purpose_flags::MASK_ENCRYPTED == 0);
assert!(
@ -192,9 +194,13 @@ impl<T: Write> ZipFileWriter<T> {
header.general_purpose_flags &= !(general_purpose_flags::MASK_COMPRESS_OPTION_1
| general_purpose_flags::MASK_COMPRESS_OPTION_2);
if data_descriptor.is_some() {
panic!("Writing file with data_descriptor is not yet implemented");
}
let file_info = FileInfo {
local_header,
header,
data_descriptor,
};
self.files.push(file_info);
}