From 48817d1df8ba49ed54f1a25ed08c5bf3a04f0f5f Mon Sep 17 00:00:00 2001 From: Jean-Marie 'Histausse' Mineau Date: Tue, 28 Jan 2025 00:03:34 +0100 Subject: [PATCH] wip --- Cargo.lock | 5 +++-- apk_frauder/Cargo.toml | 1 + apk_frauder/src/lib.rs | 6 +++++- apk_frauder/src/main.rs | 16 ++++++++++++++++ apk_frauder/src/zip_reader.rs | 34 +++++++++++++++++++++++++++------- apk_frauder/src/zip_writer.rs | 6 ++++++ 6 files changed, 58 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cc179a4..c06f2ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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" diff --git a/apk_frauder/Cargo.toml b/apk_frauder/Cargo.toml index 5c02076..d51c48b 100644 --- a/apk_frauder/Cargo.toml +++ b/apk_frauder/Cargo.toml @@ -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" diff --git a/apk_frauder/src/lib.rs b/apk_frauder/src/lib.rs index 3d35ae2..e97aae8 100644 --- a/apk_frauder/src/lib.rs +++ b/apk_frauder/src/lib.rs @@ -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, } -// 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(), ); } } diff --git a/apk_frauder/src/main.rs b/apk_frauder/src/main.rs index 77c58a0..dd31eeb 100644 --- a/apk_frauder/src/main.rs +++ b/apk_frauder/src/main.rs @@ -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::>>>, + );*/ + 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, + },),) ); } diff --git a/apk_frauder/src/zip_reader.rs b/apk_frauder/src/zip_reader.rs index 590ef87..8e13e02 100644 --- a/apk_frauder/src/zip_reader.rs +++ b/apk_frauder/src/zip_reader.rs @@ -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 ZipFileReader { .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); diff --git a/apk_frauder/src/zip_writer.rs b/apk_frauder/src/zip_writer.rs index 0d52294..5faf7cd 100644 --- a/apk_frauder/src/zip_writer.rs +++ b/apk_frauder/src/zip_writer.rs @@ -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 ZipFileWriter { file: &mut U, mut header: FileHeader, local_header: Option, + data_descriptor: Option, ) { assert!(header.general_purpose_flags & general_purpose_flags::MASK_ENCRYPTED == 0); assert!( @@ -192,9 +194,13 @@ impl ZipFileWriter { 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); }