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

View file

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

View file

@ -10,6 +10,7 @@ use std::process::Command;
pub mod apk_signing_block; pub mod apk_signing_block;
pub mod compression; pub mod compression;
mod cp437; mod cp437;
pub mod data_descriptor;
pub mod end_of_central_directory; pub mod end_of_central_directory;
pub mod error; pub mod error;
pub mod extra_fields; pub mod extra_fields;
@ -18,6 +19,7 @@ pub mod local_file_header;
pub mod zip_reader; pub mod zip_reader;
pub mod zip_writer; pub mod zip_writer;
use data_descriptor::DataDescriptor;
use extra_fields::{ExtraField, Zip64ExtraField}; use extra_fields::{ExtraField, Zip64ExtraField};
use file_header::FileHeader; use file_header::FileHeader;
use local_file_header::LocalFileHeader; use local_file_header::LocalFileHeader;
@ -69,8 +71,8 @@ pub mod external_file_attributes {
pub struct FileInfo { pub struct FileInfo {
pub local_header: LocalFileHeader, pub local_header: LocalFileHeader,
pub header: FileHeader, pub header: FileHeader,
pub data_descriptor: Option<DataDescriptor>,
} }
// TODO: support data descriptor (MASK_USE_DATA_DESCRIPTOR)
impl FileInfo { impl FileInfo {
pub fn get_name(&self) -> String { pub fn get_name(&self) -> String {
@ -204,6 +206,7 @@ pub fn replace_dex(
&mut dex, &mut dex,
file_info_ref.header.clone(), file_info_ref.header.clone(),
Some(file_info_ref.local_header.clone()), Some(file_info_ref.local_header.clone()),
file_info_ref.data_descriptor.clone(),
); );
} }
if let Some(mut additionnal_files) = additionnal_files { if let Some(mut additionnal_files) = additionnal_files {
@ -214,6 +217,7 @@ pub fn replace_dex(
data, data,
file_info_ref.header.clone(), file_info_ref.header.clone(),
Some(file_info_ref.local_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::collections::HashMap;
use std::env; use std::env;
use std::fs::File; use std::fs::File;
use std::io::Cursor; use std::io::Cursor;
use apk_frauder::data_descriptor::{DataDescriptor, DataDescriptor32};
fn main() { fn main() {
/*
apk_frauder::replace_dex( apk_frauder::replace_dex(
"app-release.apk", "app-release.apk",
"app-instrumented.apk", "app-instrumented.apk",
@ -18,5 +22,17 @@ fn main() {
env::var("HOME").expect("$HOME not set") env::var("HOME").expect("$HOME not set")
)), )),
None::<HashMap<String, Option<Cursor<&[u8]>>>>, 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::collections::HashMap;
use std::io::{Read, Seek, SeekFrom}; use std::io::{Read, Seek, SeekFrom};
use crate::{ 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::EndCentralDirectory,
end_of_central_directory::Zip64EndCentralDirectory, end_of_central_directory::Zip64EndCentralDirectory,
end_of_central_directory::Zip64EndCentralDirectoryLocator, general_purpose_flags, FileHeader, end_of_central_directory::Zip64EndCentralDirectoryLocator,
FileInfo, LocalFileHeader, Signature, general_purpose_flags, FileHeader, FileInfo, LocalFileHeader, Signature,
}; };
use androscalpel_serializer::Serializable; use androscalpel_serializer::Serializable;
use flate2::read::DeflateDecoder; use flate2::read::DeflateDecoder;
@ -80,18 +84,34 @@ impl<T: Read + Seek> ZipFileReader<T> {
.seek(SeekFrom::Start(header.get_offset_local_header())) .seek(SeekFrom::Start(header.get_offset_local_header()))
.unwrap(); .unwrap();
let local_header = LocalFileHeader::deserialize(&mut zip_file.data).unwrap(); let local_header = LocalFileHeader::deserialize(&mut zip_file.data).unwrap();
zip_file.data.seek(SeekFrom::Start(pos_in_dir)).unwrap(); let data_descriptor = if (local_header.general_purpose_flags
if (local_header.general_purpose_flags
& general_purpose_flags::MASK_USE_DATA_DESCRIPTOR & general_purpose_flags::MASK_USE_DATA_DESCRIPTOR
!= 0) != 0)
|| (header.general_purpose_flags & general_purpose_flags::MASK_USE_DATA_DESCRIPTOR || (header.general_purpose_flags & general_purpose_flags::MASK_USE_DATA_DESCRIPTOR
!= 0) != 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 { zip_file.files.push(FileInfo {
local_header, local_header,
header, header,
data_descriptor,
}); });
} }
assert_eq!(size_read, cd_size); assert_eq!(size_read, cd_size);

View file

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