mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-25 02:55:33 +00:00
Move find_apk_path to Rust
This commit is contained in:
parent
40f25f4d56
commit
f33f1d25d0
@ -20,48 +20,6 @@ int fd_pathat(int dirfd, const char *name, char *path, size_t size) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Func>
|
|
||||||
static void post_order_walk(int dirfd, const Func &fn) {
|
|
||||||
auto dir = xopen_dir(dirfd);
|
|
||||||
if (!dir) return;
|
|
||||||
|
|
||||||
for (dirent *entry; (entry = xreaddir(dir.get()));) {
|
|
||||||
if (entry->d_type == DT_DIR)
|
|
||||||
post_order_walk(xopenat(dirfd, entry->d_name, O_RDONLY | O_CLOEXEC), fn);
|
|
||||||
fn(dirfd, entry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum walk_result {
|
|
||||||
CONTINUE, SKIP, ABORT
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Func>
|
|
||||||
static walk_result pre_order_walk(int dirfd, const Func &fn) {
|
|
||||||
auto dir = xopen_dir(dirfd);
|
|
||||||
if (!dir) {
|
|
||||||
close(dirfd);
|
|
||||||
return SKIP;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (dirent *entry; (entry = xreaddir(dir.get()));) {
|
|
||||||
switch (fn(dirfd, entry)) {
|
|
||||||
case CONTINUE:
|
|
||||||
break;
|
|
||||||
case SKIP:
|
|
||||||
continue;
|
|
||||||
case ABORT:
|
|
||||||
return ABORT;
|
|
||||||
}
|
|
||||||
if (entry->d_type == DT_DIR) {
|
|
||||||
int fd = xopenat(dirfd, entry->d_name, O_RDONLY | O_CLOEXEC);
|
|
||||||
if (pre_order_walk(fd, fn) == ABORT)
|
|
||||||
return ABORT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mv_path(const char *src, const char *dest) {
|
void mv_path(const char *src, const char *dest) {
|
||||||
file_attr attr;
|
file_attr attr;
|
||||||
getattr(src, &attr);
|
getattr(src, &attr);
|
||||||
@ -447,23 +405,6 @@ mmap_data::~mmap_data() {
|
|||||||
munmap(_buf, _sz);
|
munmap(_buf, _sz);
|
||||||
}
|
}
|
||||||
|
|
||||||
string find_apk_path(const char *pkg) {
|
|
||||||
char buf[PATH_MAX];
|
|
||||||
size_t len = strlen(pkg);
|
|
||||||
pre_order_walk(xopen("/data/app", O_RDONLY), [&](int dfd, dirent *entry) -> walk_result {
|
|
||||||
if (entry->d_type != DT_DIR)
|
|
||||||
return SKIP;
|
|
||||||
if (strncmp(entry->d_name, pkg, len) == 0 && entry->d_name[len] == '-') {
|
|
||||||
fd_pathat(dfd, entry->d_name, buf, sizeof(buf));
|
|
||||||
return ABORT;
|
|
||||||
} else if (strncmp(entry->d_name, "~~", 2) == 0) {
|
|
||||||
return CONTINUE;
|
|
||||||
} else return SKIP;
|
|
||||||
});
|
|
||||||
string path(buf);
|
|
||||||
return path.append("/base.apk");
|
|
||||||
}
|
|
||||||
|
|
||||||
string resolve_preinit_dir(const char *base_dir) {
|
string resolve_preinit_dir(const char *base_dir) {
|
||||||
string dir = base_dir;
|
string dir = base_dir;
|
||||||
if (access((dir + "/unencrypted").data(), F_OK) == 0) {
|
if (access((dir + "/unencrypted").data(), F_OK) == 0) {
|
||||||
|
@ -92,7 +92,6 @@ void parse_prop_file(const char *file,
|
|||||||
const std::function<bool(std::string_view, std::string_view)> &fn);
|
const std::function<bool(std::string_view, std::string_view)> &fn);
|
||||||
void clone_dir(int src, int dest);
|
void clone_dir(int src, int dest);
|
||||||
std::vector<mount_info> parse_mount_info(const char *pid);
|
std::vector<mount_info> parse_mount_info(const char *pid);
|
||||||
std::string find_apk_path(const char *pkg);
|
|
||||||
std::string resolve_preinit_dir(const char *base_dir);
|
std::string resolve_preinit_dir(const char *base_dir);
|
||||||
|
|
||||||
using sFILE = std::unique_ptr<FILE, decltype(&fclose)>;
|
using sFILE = std::unique_ptr<FILE, decltype(&fclose)>;
|
||||||
|
@ -202,6 +202,13 @@ struct byte_data : public byte_view {
|
|||||||
std::vector<size_t> patch(byte_view from, byte_view to);
|
std::vector<size_t> patch(byte_view from, byte_view to);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<size_t N>
|
||||||
|
struct byte_array : public byte_data {
|
||||||
|
byte_array() : byte_data(arr, N), arr{0} {}
|
||||||
|
private:
|
||||||
|
uint8_t arr[N];
|
||||||
|
};
|
||||||
|
|
||||||
class byte_channel;
|
class byte_channel;
|
||||||
|
|
||||||
struct heap_data : public byte_data {
|
struct heap_data : public byte_data {
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
use crate::logging::{magisk_logging, zygisk_logging};
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
|
use std::io;
|
||||||
use std::sync::{Mutex, OnceLock};
|
use std::sync::{Mutex, OnceLock};
|
||||||
|
|
||||||
|
use base::{copy_str, cstr, Directory, ResultExt, WalkResult};
|
||||||
|
|
||||||
|
use crate::logging::{magisk_logging, zygisk_logging};
|
||||||
|
|
||||||
// Global magiskd singleton
|
// Global magiskd singleton
|
||||||
pub static MAGISKD: OnceLock<MagiskD> = OnceLock::new();
|
pub static MAGISKD: OnceLock<MagiskD> = OnceLock::new();
|
||||||
|
|
||||||
@ -29,3 +33,30 @@ pub fn get_magiskd() -> &'static MagiskD {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl MagiskD {}
|
impl MagiskD {}
|
||||||
|
|
||||||
|
pub fn find_apk_path(pkg: &[u8], data: &mut [u8]) -> usize {
|
||||||
|
use WalkResult::*;
|
||||||
|
fn inner(pkg: &[u8], data: &mut [u8]) -> io::Result<usize> {
|
||||||
|
let mut len = 0_usize;
|
||||||
|
Directory::open(cstr!("/data/app"))?.pre_order_walk(|e| {
|
||||||
|
if !e.is_dir() {
|
||||||
|
return Ok(Skip);
|
||||||
|
}
|
||||||
|
let d_name = e.d_name().to_bytes();
|
||||||
|
if d_name.starts_with(pkg) && d_name[pkg.len()] == b'-' {
|
||||||
|
// Found the APK path, we can abort now
|
||||||
|
len = e.path(data)?;
|
||||||
|
return Ok(Abort);
|
||||||
|
}
|
||||||
|
if d_name.starts_with(b"~~") {
|
||||||
|
return Ok(Continue);
|
||||||
|
}
|
||||||
|
Ok(Skip)
|
||||||
|
})?;
|
||||||
|
if len > 0 {
|
||||||
|
len += copy_str(&mut data[len..], "/base.apk");
|
||||||
|
}
|
||||||
|
Ok(len)
|
||||||
|
}
|
||||||
|
inner(pkg, data).log().unwrap_or(0)
|
||||||
|
}
|
||||||
|
@ -21,6 +21,7 @@ pub mod ffi {
|
|||||||
fn android_logging();
|
fn android_logging();
|
||||||
fn magisk_logging();
|
fn magisk_logging();
|
||||||
fn zygisk_logging();
|
fn zygisk_logging();
|
||||||
|
fn find_apk_path(pkg: &[u8], data: &mut [u8]) -> usize;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[namespace = "rust"]
|
#[namespace = "rust"]
|
||||||
|
@ -169,8 +169,9 @@ int get_manager(int user_id, string *pkg, bool install) {
|
|||||||
if (stat(app_path, &st) == 0) {
|
if (stat(app_path, &st) == 0) {
|
||||||
int app_id = to_app_id(st.st_uid);
|
int app_id = to_app_id(st.st_uid);
|
||||||
|
|
||||||
string apk = find_apk_path(str[SU_MANAGER].data());
|
byte_array<PATH_MAX> apk;
|
||||||
int fd = xopen(apk.data(), O_RDONLY | O_CLOEXEC);
|
find_apk_path(byte_view(str[SU_MANAGER]), apk);
|
||||||
|
int fd = xopen((const char *) apk.buf(), O_RDONLY | O_CLOEXEC);
|
||||||
string cert = read_certificate(fd);
|
string cert = read_certificate(fd);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
@ -178,7 +179,7 @@ int get_manager(int user_id, string *pkg, bool install) {
|
|||||||
if (str[SU_MANAGER] == *mgr_pkg) {
|
if (str[SU_MANAGER] == *mgr_pkg) {
|
||||||
if (app_id != mgr_app_id || cert != *mgr_cert) {
|
if (app_id != mgr_app_id || cert != *mgr_cert) {
|
||||||
// app ID or cert should never change
|
// app ID or cert should never change
|
||||||
LOGE("pkg: repackaged APK signature invalid: %s\n", apk.data());
|
LOGE("pkg: repackaged APK signature invalid: %s\n", apk.buf());
|
||||||
uninstall_pkg(mgr_pkg->data());
|
uninstall_pkg(mgr_pkg->data());
|
||||||
invalid = true;
|
invalid = true;
|
||||||
install = true;
|
install = true;
|
||||||
|
Loading…
Reference in New Issue
Block a user