transfer file from one zip to another, WIP
This commit is contained in:
parent
0fdf619360
commit
8157325a02
3 changed files with 86 additions and 14 deletions
|
|
@ -14,6 +14,7 @@ use extra_fields::{ExtraField, Zip64ExtraField};
|
||||||
use file_header::FileHeader;
|
use file_header::FileHeader;
|
||||||
use local_file_header::LocalFileHeader;
|
use local_file_header::LocalFileHeader;
|
||||||
pub use zip_reader::ZipFileReader;
|
pub use zip_reader::ZipFileReader;
|
||||||
|
pub use zip_writer::ZipFileWriter;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Serializable, Default)]
|
#[derive(Debug, Clone, PartialEq, Eq, Serializable, Default)]
|
||||||
pub struct Signature(pub u32);
|
pub struct Signature(pub u32);
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,13 @@
|
||||||
use apk_frauder::ZipFileReader;
|
use apk_frauder::ZipFileReader;
|
||||||
|
use apk_frauder::ZipFileWriter;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
/*
|
||||||
let file = File::open("app-release.apk").expect("failed to open file");
|
let file = File::open("app-release.apk").expect("failed to open file");
|
||||||
//let file = File::open("tst_64.zip").expect("failed to open file");
|
//let file = File::open("tst_64.zip").expect("failed to open file");
|
||||||
let zip_file = ZipFileReader::new(file);
|
let zip_file = ZipFileReader::new(file);
|
||||||
//println!("{}", zip_file.get_file_names().join("\n"));
|
//println!("{}", zip_file.get_file_names().join("\n"));
|
||||||
/*
|
|
||||||
for file in &zip_file.files {
|
for file in &zip_file.files {
|
||||||
println!("{}", file.get_name());
|
println!("{}", file.get_name());
|
||||||
println!("local: {:?}", file.local_header.malformed_extra_field);
|
println!("local: {:?}", file.local_header.malformed_extra_field);
|
||||||
|
|
@ -33,6 +34,17 @@ fn main() {
|
||||||
println!("Not signed whith scheme >= v2");
|
println!("Not signed whith scheme >= v2");
|
||||||
}
|
}
|
||||||
zip_file.check_holes();
|
zip_file.check_holes();
|
||||||
*/
|
|
||||||
println!("{:#?}", zip_file.get_file_info("classes.dex"));
|
println!("{:#?}", zip_file.get_file_info("classes.dex"));
|
||||||
|
*/
|
||||||
|
|
||||||
|
let file = File::open("app-release.apk").expect("failed to open file");
|
||||||
|
let out_file = File::create("app-release.out.zip").expect("failed to create file");
|
||||||
|
let mut zip_file = ZipFileReader::new(file);
|
||||||
|
let mut out_file =
|
||||||
|
ZipFileWriter::new(out_file, zip_file.zip64_end_of_central_directory.clone());
|
||||||
|
for f in zip_file.files.clone() {
|
||||||
|
out_file.insert_file_from_zip(f, &mut zip_file);
|
||||||
|
}
|
||||||
|
out_file.write_central_directory();
|
||||||
|
//println!("{:#?}", zip_file.zip64_end_of_central_directory);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
use std::io::{Read, Seek, SeekFrom, Write};
|
use std::io::{Read, Seek, SeekFrom, Write};
|
||||||
|
|
||||||
use crate::{
|
use crate::end_of_central_directory::{
|
||||||
end_of_central_directory::EndCentralDirectory,
|
EndCentralDirectory, Zip64EndCentralDirectory, Zip64EndCentralDirectoryLocator,
|
||||||
end_of_central_directory::Zip64EndCentralDirectory, FileInfo, ZipFileReader,
|
|
||||||
};
|
};
|
||||||
|
use crate::{FileInfo, ZipFileReader};
|
||||||
use androscalpel_serializer::Serializable;
|
use androscalpel_serializer::Serializable;
|
||||||
|
|
||||||
pub struct ZipFileWriter<T: Write> {
|
pub struct ZipFileWriter<T: Write> {
|
||||||
|
|
@ -14,6 +14,8 @@ pub struct ZipFileWriter<T: Write> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Write> ZipFileWriter<T> {
|
impl<T: Write> ZipFileWriter<T> {
|
||||||
|
/// If provided, `zip64_info` is used to get the value that are not computable from
|
||||||
|
/// the state, like version needed to extract.
|
||||||
pub fn new(writer: T, zip64_info: Option<Zip64EndCentralDirectory>) -> Self {
|
pub fn new(writer: T, zip64_info: Option<Zip64EndCentralDirectory>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
current_offset: 0,
|
current_offset: 0,
|
||||||
|
|
@ -53,18 +55,75 @@ impl<T: Write> ZipFileWriter<T> {
|
||||||
for file_info in &self.files {
|
for file_info in &self.files {
|
||||||
file_info.header.serialize(&mut self.data).unwrap();
|
file_info.header.serialize(&mut self.data).unwrap();
|
||||||
}
|
}
|
||||||
// TODO: zip64
|
let number_of_entries_in_central_directory_on_disk = self.files.len();
|
||||||
|
let number_of_entries_in_central_directory = self.files.len();
|
||||||
|
let size_central_directory: u64 = self
|
||||||
|
.files
|
||||||
|
.iter()
|
||||||
|
.map(|file| file.header.size() as u64)
|
||||||
|
.sum();
|
||||||
|
let offset_central_directory = self.current_offset;
|
||||||
|
let use_zip64 = (number_of_entries_in_central_directory_on_disk > u16::MAX as usize)
|
||||||
|
|| (number_of_entries_in_central_directory > u16::MAX as usize)
|
||||||
|
|| (size_central_directory > u32::MAX as u64)
|
||||||
|
|| (offset_central_directory > u32::MAX as u64)
|
||||||
|
|| self.zip64_end_of_central_directory.is_some();
|
||||||
|
|
||||||
|
if use_zip64 {
|
||||||
|
if self.zip64_end_of_central_directory.is_none() {
|
||||||
|
self.zip64_end_of_central_directory = Some(Zip64EndCentralDirectory {
|
||||||
|
version_made_by: 45,
|
||||||
|
version_needed_to_extract: 45,
|
||||||
|
number_of_this_disk: 0,
|
||||||
|
disk_number_of_central_directory_start: 0,
|
||||||
|
number_entry_in_central_directory_on_this_disk: 0,
|
||||||
|
number_entry_in_central_directory: 0,
|
||||||
|
size_of_central_directory: 0,
|
||||||
|
offset_central_directory: 0,
|
||||||
|
extensible_data: vec![],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
let zip64_edc = self.zip64_end_of_central_directory.as_mut().unwrap();
|
||||||
|
zip64_edc.number_entry_in_central_directory_on_this_disk =
|
||||||
|
number_of_entries_in_central_directory_on_disk as u64;
|
||||||
|
zip64_edc.number_entry_in_central_directory =
|
||||||
|
number_of_entries_in_central_directory as u64;
|
||||||
|
zip64_edc.size_of_central_directory = size_central_directory;
|
||||||
|
zip64_edc.offset_central_directory = offset_central_directory;
|
||||||
|
zip64_edc.serialize(&mut self.data).unwrap();
|
||||||
|
|
||||||
|
Zip64EndCentralDirectoryLocator {
|
||||||
|
disk_number_of_zip64_end_central_directory_start: 0,
|
||||||
|
offset_zip64_end_of_central_directory_record: offset_central_directory
|
||||||
|
+ size_central_directory,
|
||||||
|
total_number_of_disks: 0,
|
||||||
|
}
|
||||||
|
.serialize(&mut self.data)
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
EndCentralDirectory {
|
EndCentralDirectory {
|
||||||
disk_number: 0,
|
disk_number: 0,
|
||||||
disk_number_of_central_directory_start: 0,
|
disk_number_of_central_directory_start: 0,
|
||||||
number_of_entries_in_central_directory_on_disk: self.files.len() as u16,
|
number_of_entries_in_central_directory_on_disk: if use_zip64 {
|
||||||
number_of_entries_in_central_directory: self.files.len() as u16,
|
u16::MAX
|
||||||
size_central_directory: self
|
} else {
|
||||||
.files
|
number_of_entries_in_central_directory_on_disk as u16
|
||||||
.iter()
|
},
|
||||||
.map(|file| file.local_header.size() as u32 + file.get_compressed_size() as u32)
|
number_of_entries_in_central_directory: if use_zip64 {
|
||||||
.sum(),
|
u16::MAX
|
||||||
offset_central_directory: self.current_offset as u32,
|
} else {
|
||||||
|
number_of_entries_in_central_directory as u16
|
||||||
|
},
|
||||||
|
size_central_directory: if use_zip64 {
|
||||||
|
u32::MAX
|
||||||
|
} else {
|
||||||
|
size_central_directory as u32
|
||||||
|
},
|
||||||
|
offset_central_directory: if use_zip64 {
|
||||||
|
u32::MAX
|
||||||
|
} else {
|
||||||
|
offset_central_directory as u32
|
||||||
|
},
|
||||||
comment: vec![],
|
comment: vec![],
|
||||||
}
|
}
|
||||||
.serialize(&mut self.data)
|
.serialize(&mut self.data)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue