mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-12-22 16:07:39 +00:00
Small refactor
This commit is contained in:
parent
81493475f9
commit
2359cfc480
@ -12,7 +12,7 @@ use std::{io, mem, ptr, slice};
|
|||||||
|
|
||||||
use libc::{c_char, c_uint, dirent, mode_t, EEXIST, ENOENT, O_CLOEXEC, O_PATH, O_RDONLY, O_RDWR};
|
use libc::{c_char, c_uint, dirent, mode_t, EEXIST, ENOENT, O_CLOEXEC, O_PATH, O_RDONLY, O_RDWR};
|
||||||
|
|
||||||
use crate::{bfmt_cstr, copy_cstr, cstr, errno, error, LibcReturn, Utf8CStr};
|
use crate::{bfmt_cstr, copy_cstr, cstr, errno, error, FlatData, LibcReturn, Utf8CStr};
|
||||||
|
|
||||||
pub fn __open_fd_impl(path: &Utf8CStr, flags: i32, mode: mode_t) -> io::Result<OwnedFd> {
|
pub fn __open_fd_impl(path: &Utf8CStr, flags: i32, mode: mode_t) -> io::Result<OwnedFd> {
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -101,6 +101,7 @@ pub fn mkdirs(path: &Utf8CStr, mode: mode_t) -> io::Result<()> {
|
|||||||
|
|
||||||
pub trait ReadExt {
|
pub trait ReadExt {
|
||||||
fn skip(&mut self, len: usize) -> io::Result<()>;
|
fn skip(&mut self, len: usize) -> io::Result<()>;
|
||||||
|
fn read_flat_data<F: FlatData>(&mut self, data: &mut F) -> io::Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Read> ReadExt for T {
|
impl<T: Read> ReadExt for T {
|
||||||
@ -114,6 +115,10 @@ impl<T: Read> ReadExt for T {
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn read_flat_data<F: FlatData>(&mut self, data: &mut F) -> io::Result<()> {
|
||||||
|
self.read_exact(data.as_raw_bytes_mut())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ReadSeekExt {
|
pub trait ReadSeekExt {
|
||||||
@ -162,7 +167,7 @@ impl<T: BufRead> BufReadExt for T {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if let Some((key, value)) = line.split_once('=') {
|
if let Some((key, value)) = line.split_once('=') {
|
||||||
return f(key, value);
|
return f(key.trim(), value.trim());
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::{Read, Seek, SeekFrom};
|
use std::io::{Cursor, Read, Seek, SeekFrom};
|
||||||
use std::os::fd::{FromRawFd, RawFd};
|
use std::os::fd::{FromRawFd, RawFd};
|
||||||
|
|
||||||
use base::*;
|
use base::*;
|
||||||
@ -38,20 +38,20 @@ macro_rules! bad_apk {
|
|||||||
* within the APK v2 signature block.
|
* within the APK v2 signature block.
|
||||||
*/
|
*/
|
||||||
pub fn read_certificate(fd: RawFd, version: i32) -> Vec<u8> {
|
pub fn read_certificate(fd: RawFd, version: i32) -> Vec<u8> {
|
||||||
fn inner(apk: &mut File, version: i32) -> Result<Vec<u8>, io::Error> {
|
fn inner(apk: &mut File, version: i32) -> io::Result<Vec<u8>> {
|
||||||
let mut u32_value = 0u32;
|
let mut u32_val = 0u32;
|
||||||
let mut u64_value = 0u64;
|
let mut u64_val = 0u64;
|
||||||
|
|
||||||
// Find EOCD
|
// Find EOCD
|
||||||
for i in 0u16.. {
|
for i in 0u16.. {
|
||||||
let mut comment_sz = 0u16;
|
let mut comment_sz = 0u16;
|
||||||
apk.seek(SeekFrom::End(-(comment_sz.bytes_size() as i64) - i as i64))?;
|
apk.seek(SeekFrom::End(-(comment_sz.bytes_size() as i64) - i as i64))?;
|
||||||
apk.read_exact(comment_sz.as_raw_bytes_mut())?;
|
apk.read_flat_data(&mut comment_sz)?;
|
||||||
|
|
||||||
if comment_sz == i {
|
if comment_sz == i {
|
||||||
apk.seek(SeekFrom::Current(-22))?;
|
apk.seek(SeekFrom::Current(-22))?;
|
||||||
let mut magic = 0u32;
|
let mut magic = 0u32;
|
||||||
apk.read_exact(magic.as_raw_bytes_mut())?;
|
apk.read_flat_data(&mut magic)?;
|
||||||
if magic == EOCD_MAGIC {
|
if magic == EOCD_MAGIC {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -65,20 +65,19 @@ pub fn read_certificate(fd: RawFd, version: i32) -> Vec<u8> {
|
|||||||
// Seek and read central_dir_off to find the start of the central directory
|
// Seek and read central_dir_off to find the start of the central directory
|
||||||
let mut central_dir_off = 0u32;
|
let mut central_dir_off = 0u32;
|
||||||
apk.seek(SeekFrom::Current(12))?;
|
apk.seek(SeekFrom::Current(12))?;
|
||||||
|
apk.read_flat_data(&mut central_dir_off)?;
|
||||||
apk.read_exact(central_dir_off.as_raw_bytes_mut())?;
|
|
||||||
|
|
||||||
// Code for parse APK comment to get version code
|
// Code for parse APK comment to get version code
|
||||||
if version >= 0 {
|
if version >= 0 {
|
||||||
let mut comment_sz = 0u16;
|
let mut comment_sz = 0u16;
|
||||||
apk.read_exact(comment_sz.as_raw_bytes_mut())?;
|
apk.read_flat_data(&mut comment_sz)?;
|
||||||
let mut comment = vec![0u8; comment_sz as usize];
|
let mut comment = vec![0u8; comment_sz as usize];
|
||||||
apk.read_exact(&mut comment)?;
|
apk.read_exact(&mut comment)?;
|
||||||
let mut comment = io::Cursor::new(&comment);
|
let mut comment = Cursor::new(&comment);
|
||||||
let mut apk_ver = 0;
|
let mut apk_ver = 0;
|
||||||
comment.foreach_props(|k, v| {
|
comment.foreach_props(|k, v| {
|
||||||
if k == "versionCode" {
|
if k == "versionCode" {
|
||||||
apk_ver = v.trim().parse::<i32>().unwrap_or(0);
|
apk_ver = v.parse::<i32>().unwrap_or(0);
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
true
|
true
|
||||||
@ -91,54 +90,53 @@ pub fn read_certificate(fd: RawFd, version: i32) -> Vec<u8> {
|
|||||||
|
|
||||||
// Next, find the start of the APK signing block
|
// Next, find the start of the APK signing block
|
||||||
apk.seek(SeekFrom::Start((central_dir_off - 24) as u64))?;
|
apk.seek(SeekFrom::Start((central_dir_off - 24) as u64))?;
|
||||||
apk.read_exact(u64_value.as_raw_bytes_mut())?; // u64_value = block_sz_
|
apk.read_flat_data(&mut u64_val)?; // u64_value = block_sz_
|
||||||
let mut magic = [0u8; 16];
|
let mut magic = [0u8; 16];
|
||||||
apk.read_exact(magic.as_raw_bytes_mut())?;
|
apk.read_exact(&mut magic)?;
|
||||||
if magic != APK_SIGNING_BLOCK_MAGIC {
|
if magic != APK_SIGNING_BLOCK_MAGIC {
|
||||||
return Err(bad_apk!("invalid signing block magic"));
|
return Err(bad_apk!("invalid signing block magic"));
|
||||||
}
|
}
|
||||||
let mut signing_blk_sz = 0u64;
|
let mut signing_blk_sz = 0u64;
|
||||||
apk.seek(SeekFrom::Current(
|
apk.seek(SeekFrom::Current(
|
||||||
-(u64_value as i64) - (signing_blk_sz.bytes_size() as i64),
|
-(u64_val as i64) - (signing_blk_sz.bytes_size() as i64),
|
||||||
))?;
|
))?;
|
||||||
apk.read_exact(signing_blk_sz.as_raw_bytes_mut())?;
|
apk.read_flat_data(&mut signing_blk_sz)?;
|
||||||
if signing_blk_sz != u64_value {
|
if signing_blk_sz != u64_val {
|
||||||
return Err(bad_apk!("invalid signing block size"));
|
return Err(bad_apk!("invalid signing block size"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, we are now at the beginning of the id-value pair sequence
|
// Finally, we are now at the beginning of the id-value pair sequence
|
||||||
loop {
|
loop {
|
||||||
apk.read_exact(u64_value.as_raw_bytes_mut())?; // id-value pair length
|
apk.read_flat_data(&mut u64_val)?; // id-value pair length
|
||||||
if u64_value == signing_blk_sz {
|
if u64_val == signing_blk_sz {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut id = 0u32;
|
let mut id = 0u32;
|
||||||
apk.read_exact(id.as_raw_bytes_mut())?;
|
apk.read_flat_data(&mut id)?;
|
||||||
if id == SIGNATURE_SCHEME_V2_MAGIC {
|
if id == SIGNATURE_SCHEME_V2_MAGIC {
|
||||||
// Skip [signer sequence length] + [1st signer length] + [signed data length]
|
// Skip [signer sequence length] + [1st signer length] + [signed data length]
|
||||||
apk.seek(SeekFrom::Current((u32_value.bytes_size() * 3) as i64))?;
|
apk.seek(SeekFrom::Current((u32_val.bytes_size() * 3) as i64))?;
|
||||||
|
|
||||||
apk.read_exact(u32_value.as_raw_bytes_mut())?; // digest sequence length
|
apk.read_flat_data(&mut u32_val)?; // digest sequence length
|
||||||
apk.seek(SeekFrom::Current(u32_value as i64))?; // skip all digests
|
apk.seek(SeekFrom::Current(u32_val as i64))?; // skip all digests
|
||||||
|
|
||||||
apk.seek(SeekFrom::Current(u32_value.bytes_size() as i64))?; // cert sequence length
|
apk.seek(SeekFrom::Current(u32_val.bytes_size() as i64))?; // cert sequence length
|
||||||
apk.read_exact(u32_value.as_raw_bytes_mut())?; // 1st cert length
|
apk.read_flat_data(&mut u32_val)?; // 1st cert length
|
||||||
|
|
||||||
let mut cert = vec![0; u32_value as usize];
|
let mut cert = vec![0; u32_val as usize];
|
||||||
apk.read_exact(cert.as_mut())?;
|
apk.read_exact(cert.as_mut())?;
|
||||||
return Ok(cert);
|
return Ok(cert);
|
||||||
} else {
|
} else {
|
||||||
// Skip this id-value pair
|
// Skip this id-value pair
|
||||||
apk.seek(SeekFrom::Current(
|
apk.seek(SeekFrom::Current(u64_val as i64 - (id.bytes_size() as i64)))?;
|
||||||
u64_value as i64 - (id.bytes_size() as i64),
|
|
||||||
))?;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(bad_apk!("cannot find certificate"))
|
Err(bad_apk!("cannot find certificate"))
|
||||||
}
|
}
|
||||||
inner(unsafe { &mut File::from_raw_fd(libc::dup(fd)) }, version)
|
let mut file = unsafe { File::from_raw_fd(fd) };
|
||||||
.log()
|
let r = inner(&mut file, version).log().unwrap_or(vec![]);
|
||||||
.unwrap_or(vec![])
|
std::mem::forget(file);
|
||||||
|
r
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user