self unpacking zip, quick and dirty code

This commit is contained in:
Jean-Marie 'Histausse' Mineau 2024-03-14 13:28:15 +01:00
parent d47494f8f6
commit 76a39f35df
Signed by: histausse
GPG key ID: B66AEEDA9B645AD2
2 changed files with 92 additions and 0 deletions

View file

@ -1,6 +1,7 @@
use std::env;
use std::fs::File;
/*
fn main() {
apk_frauder::replace_dex(
"app-release.apk",
@ -16,4 +17,77 @@ fn main() {
env::var("HOME").expect("$HOME not set")
)),
);
}*/
fn main() {
let args: Vec<String> = env::args().collect();
if args.len() != 3 {
panic!("Usage: {} <folder to zip> <header file>", args[0]);
}
let folder = &args[1];
let header_file = &args[2];
let archive_name = format!("{folder}.zip");
let file = File::create(archive_name).expect("failed to create file");
let mut zip = apk_frauder::zip_writer::ZipFileWriter::new(file, None);
zip.insert_untracked_file(
&mut File::open(header_file)
.unwrap_or_else(|_| panic!("failed to open file {header_file}")),
);
insert_to_zip(std::path::Path::new(folder), &mut zip, None);
zip.write_central_directory();
}
fn insert_to_zip(
file: &std::path::Path,
zip: &mut apk_frauder::zip_writer::ZipFileWriter<File>,
root: Option<&std::path::Path>,
) {
let root = if let Some(root) = root { root } else { file };
let internal_path =
&std::path::Path::new(root.file_name().unwrap()).join(file.strip_prefix(root).unwrap());
if file.is_dir() {
zip.insert_file(
&mut std::io::Cursor::new(vec![]),
apk_frauder::file_header::FileHeader {
external_file_attributes: apk_frauder::external_file_attributes::DIR_FILE
| apk_frauder::external_file_attributes::PERM_UR
| apk_frauder::external_file_attributes::PERM_UW
| apk_frauder::external_file_attributes::PERM_GR
| apk_frauder::external_file_attributes::PERM_OR
| apk_frauder::external_file_attributes::PERM_UX
| apk_frauder::external_file_attributes::PERM_GX
| apk_frauder::external_file_attributes::PERM_OX,
..apk_frauder::file_header::FileHeader::new_default(internal_path.to_str().unwrap())
},
None,
);
for entry in std::fs::read_dir(file).unwrap() {
let entry = entry.unwrap();
let path = entry.path();
insert_to_zip(path.as_ref(), zip, Some(root));
}
} else {
//use std::os::unix::fs::PermissionsExt;
let mut f = File::open(file)
.unwrap_or_else(|_| panic!("failed to open file {}", file.to_str().unwrap()));
//let metadata = f.metadata().unwrap();
//let permissions = metadata.permissions();
//let external_file_attributes = permissions.mode(); does not work?
let external_file_attributes = apk_frauder::external_file_attributes::REGULAR_FILE
| apk_frauder::external_file_attributes::PERM_UR
| apk_frauder::external_file_attributes::PERM_UW
| apk_frauder::external_file_attributes::PERM_GR
| apk_frauder::external_file_attributes::PERM_OR
| apk_frauder::external_file_attributes::PERM_UX
| apk_frauder::external_file_attributes::PERM_GX
| apk_frauder::external_file_attributes::PERM_OX;
zip.insert_file(
&mut f,
apk_frauder::file_header::FileHeader {
external_file_attributes,
..apk_frauder::file_header::FileHeader::new_default(internal_path.to_str().unwrap())
},
None,
);
}
}

View file

@ -54,6 +54,24 @@ impl<T: Write> ZipFileWriter<T> {
self.files.push(file_info);
}
/// Insert a file at the begining of archive that will not be tracked.
pub fn insert_untracked_file<U: Read + Seek>(&mut self, file: &mut U) {
let pos = file.stream_position().unwrap();
let pos_end = file.seek(SeekFrom::End(0)).unwrap();
file.seek(SeekFrom::Start(pos)).unwrap();
let file_size = pos_end - pos;
let mut remaining_size = file_size;
let mut buffer = [0u8; 4096];
while remaining_size != 0 {
let read = file
.read(&mut buffer[0..core::cmp::min(4096, remaining_size as usize)])
.unwrap();
self.data.write_all(&buffer[0..read]).unwrap();
remaining_size -= read as u64;
}
self.current_offset += file_size;
}
/// Insert a file
/// `header` provide for the values that are not computed from the file.
/// `local_header` can be provided is information in the local header differ