From d51ee6de78da621f72ce3c51b05b2b110b357571 Mon Sep 17 00:00:00 2001 From: Jean-Marie Mineau Date: Fri, 24 Jan 2025 13:39:34 +0100 Subject: [PATCH] experimental feature: reading from zip --- androscalpel/src/apk.rs | 4 +++ apk_frauder/src/zip_reader.rs | 54 +++++++++++++++++++++++++++++++---- 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/androscalpel/src/apk.rs b/androscalpel/src/apk.rs index e1bddbc..3bc07c7 100644 --- a/androscalpel/src/apk.rs +++ b/androscalpel/src/apk.rs @@ -2986,6 +2986,10 @@ impl Apk { } } + /// Load all android files in an application. + /// This **does not include any .dex file that android would not load. + pub fn load_apk() -> Self {} + // TODO: change cache to true when cache invalidation is setup /// Add the content of a dex file to the apk. /// diff --git a/apk_frauder/src/zip_reader.rs b/apk_frauder/src/zip_reader.rs index 440cb14..8a17cb2 100644 --- a/apk_frauder/src/zip_reader.rs +++ b/apk_frauder/src/zip_reader.rs @@ -1,13 +1,15 @@ +use std::collections::HashMap; use std::io::{Read, Seek, SeekFrom}; use crate::{ - apk_signing_block::ApkSigningBlock, apk_signing_block::Magic, + apk_signing_block::ApkSigningBlock, apk_signing_block::Magic, compression::CompressionMethod, end_of_central_directory::EndCentralDirectory, end_of_central_directory::Zip64EndCentralDirectory, end_of_central_directory::Zip64EndCentralDirectoryLocator, general_purpose_flags, FileHeader, FileInfo, LocalFileHeader, Signature, }; use androscalpel_serializer::Serializable; +use flate2::read::DeflateDecoder; #[derive(Debug, PartialEq, Eq)] pub struct ZipFileReader { @@ -285,10 +287,33 @@ impl ZipFileReader { pub fn get_bin(&mut self, offset: u64, size: usize) -> Vec { self.data.seek(SeekFrom::Start(offset)).unwrap(); - let mut data = vec![]; + let mut data = vec![0u8; size]; + self.data.read_exact(&mut data).unwrap(); + /* for _ in 0..size { data.push(u8::deserialize(&mut self.data).unwrap()); } + */ + data + } + + pub fn read_file_as_vec(&mut self, file: &FileInfo) -> Vec { + let offset = file.get_file_offset(); + let size_c = file.header.compressed_size as usize; + let size = file.header.uncompressed_size as usize; + let mut data = vec![0u8; size_c]; + self.data.seek(SeekFrom::Start(offset)).unwrap(); + self.data.read_exact(&mut data).unwrap(); + match file.header.compression_method { + CompressionMethod::Stored => {} + CompressionMethod::Deflated => { + let mut decomp_data = vec![0u8; size]; + let mut deflater = DeflateDecoder::new(&data[..]); + deflater.read_exact(&mut decomp_data).unwrap(); + data = decomp_data + } + _ => unimplemented!(), + } data } @@ -297,12 +322,29 @@ impl ZipFileReader { } pub fn get_classes_file_info(&self) -> Vec<&FileInfo> { - // TODO: check for holes: if classesN.dex does not exist, - // classesM.dex for M>N are ignored. - self.files + let files_map: HashMap = self + .files .iter() + .by_ref() .filter(|&file| match_dexfile_name(&file.get_name())) - .collect() + .map(|file| (file.get_name(), file)) + .collect(); + let mut files = vec![]; + let mut i = 0; + loop { + let name = if i == 0 { + "classes.dex".into() + } else { + format!("classes{}.dex", i + 1) + }; + if let Some(file) = files_map.get(&name) { + files.push(*file); + } else { + break; + } + i += 1; + } + files } }