diff --git a/loader/src/injector/hook.cpp b/loader/src/injector/hook.cpp index be3193e..01ad7d0 100644 --- a/loader/src/injector/hook.cpp +++ b/loader/src/injector/hook.cpp @@ -582,7 +582,12 @@ void ZygiskContext::run_modules_post() { void ZygiskContext::app_specialize_pre() { flags[APP_SPECIALIZE] = true; info_flags = zygiskd::GetProcessFlags(g_ctx->args.app->uid); - run_modules_pre(); + if ((info_flags & (PROCESS_IS_MANAGER | PROCESS_ROOT_IS_MAGISK)) == (PROCESS_IS_MANAGER | PROCESS_ROOT_IS_MAGISK)) { + LOGI("current uid %d is manager!", g_ctx->args.app->uid); + setenv("ZYGISK_ENABLED", "1", 1); + } else { + run_modules_pre(); + } } diff --git a/loader/src/injector/module.hpp b/loader/src/injector/module.hpp index bc2ec1a..7454a3a 100644 --- a/loader/src/injector/module.hpp +++ b/loader/src/injector/module.hpp @@ -112,6 +112,7 @@ namespace { PROCESS_GRANTED_ROOT = zygisk::StateFlag::PROCESS_GRANTED_ROOT, PROCESS_ON_DENYLIST = zygisk::StateFlag::PROCESS_ON_DENYLIST, + PROCESS_IS_MANAGER = (1u << 28), PROCESS_ROOT_IS_KSU = (1u << 29), PROCESS_ROOT_IS_MAGISK = (1u << 30), PROCESS_IS_SYS_UI = (1u << 31), diff --git a/module/src/sepolicy.rule b/module/src/sepolicy.rule index a99f9ef..9a6f6ec 100644 --- a/module/src/sepolicy.rule +++ b/module/src/sepolicy.rule @@ -18,3 +18,4 @@ allow zygote system_file dir mounton allow zygote labeledfs filesystem mount allow zygote fs_type filesystem unmount allow zygote zygote process execmem +allow zygote adb_data_file file mounton diff --git a/zygiskd/src/constants.rs b/zygiskd/src/constants.rs index c3a95f0..97b5825 100644 --- a/zygiskd/src/constants.rs +++ b/zygiskd/src/constants.rs @@ -47,6 +47,7 @@ bitflags! { pub struct ProcessFlags: u32 { const PROCESS_GRANTED_ROOT = 1 << 0; const PROCESS_ON_DENYLIST = 1 << 1; + const PROCESS_IS_MANAGER = 1 << 28; const PROCESS_ROOT_IS_KSU = 1 << 29; const PROCESS_ROOT_IS_MAGISK = 1 << 30; const PROCESS_IS_SYSUI = 1 << 31; diff --git a/zygiskd/src/root_impl/kernelsu.rs b/zygiskd/src/root_impl/kernelsu.rs index d629b20..18e4dec 100644 --- a/zygiskd/src/root_impl/kernelsu.rs +++ b/zygiskd/src/root_impl/kernelsu.rs @@ -67,3 +67,11 @@ pub fn uid_should_umount(uid: i32) -> bool { } umount } + +// TODO: signature +pub fn uid_is_manager(uid: i32) -> bool { + if let Ok(s) = rustix::fs::stat("/data/user_de/0/me.weishu.kernelsu") { + return s.st_uid == uid as u32 + } + false +} diff --git a/zygiskd/src/root_impl/magisk.rs b/zygiskd/src/root_impl/magisk.rs index 22a5fe3..e6d3803 100644 --- a/zygiskd/src/root_impl/magisk.rs +++ b/zygiskd/src/root_impl/magisk.rs @@ -61,3 +61,36 @@ pub fn uid_should_umount(uid: i32) -> bool { .and_then(|output| String::from_utf8(output.stdout).ok()) .map(|output| output.is_empty()) == Some(false) } + +// TODO: signature +// TODO: magisk random package name +pub fn uid_is_manager(uid: i32) -> bool { + let output = Command::new("magisk") + .arg("--sqlite") + .arg(format!("select value from strings where key=\"requester\" limit 1")) + .stdout(Stdio::piped()) + .spawn().ok() + .and_then(|child| child.wait_with_output().ok()) + .and_then(|output| String::from_utf8(output.stdout).ok()) + .map(|output| output.trim().to_string()); + if let Some(output) = output { + if let Some(manager) = output.strip_prefix("value=") { + if let Ok(s) = rustix::fs::stat(format!("/data/user_de/0/{}", manager)) { + return s.st_uid == uid as u32; + } else { + return false; + } + } + } + if let Ok(s) = rustix::fs::stat("/data/user_de/0/com.topjohnwu.magisk") { + if s.st_uid == uid as u32 { + return true; + } + } + if let Ok(s) = rustix::fs::stat("/data/user_de/0/io.github.vvb2060.magisk") { + if s.st_uid == uid as u32 { + return true; + } + } + false +} diff --git a/zygiskd/src/root_impl/mod.rs b/zygiskd/src/root_impl/mod.rs index 4cb3976..e5b07b5 100644 --- a/zygiskd/src/root_impl/mod.rs +++ b/zygiskd/src/root_impl/mod.rs @@ -56,3 +56,11 @@ pub fn uid_should_umount(uid: i32) -> bool { _ => panic!("uid_should_umount: unknown root impl {:?}", get_impl()), } } + +pub fn uid_is_manager(uid: i32) -> bool { + match get_impl() { + RootImpl::KernelSU => kernelsu::uid_is_manager(uid), + RootImpl::Magisk => magisk::uid_is_manager(uid), + _ => panic!("uid_is_manager: unknown root impl {:?}", get_impl()), + } +} diff --git a/zygiskd/src/zygiskd.rs b/zygiskd/src/zygiskd.rs index 7e6fd56..905e264 100644 --- a/zygiskd/src/zygiskd.rs +++ b/zygiskd/src/zygiskd.rs @@ -223,11 +223,15 @@ fn handle_daemon_action(action: DaemonSocketAction, mut stream: UnixStream, cont DaemonSocketAction::GetProcessFlags => { let uid = stream.read_u32()? as i32; let mut flags = ProcessFlags::empty(); - if root_impl::uid_granted_root(uid) { - flags |= ProcessFlags::PROCESS_GRANTED_ROOT; - } - if root_impl::uid_should_umount(uid) { - flags |= ProcessFlags::PROCESS_ON_DENYLIST; + if root_impl::uid_is_manager(uid) { + flags |= ProcessFlags::PROCESS_IS_MANAGER; + } else { + if root_impl::uid_granted_root(uid) { + flags |= ProcessFlags::PROCESS_GRANTED_ROOT; + } + if root_impl::uid_should_umount(uid) { + flags |= ProcessFlags::PROCESS_ON_DENYLIST; + } } match root_impl::get_impl() { root_impl::RootImpl::KernelSU => flags |= ProcessFlags::PROCESS_ROOT_IS_KSU,