diff --git a/loader/src/injector/entry.cpp b/loader/src/injector/entry.cpp index c1f8dc3..d4b169f 100644 --- a/loader/src/injector/entry.cpp +++ b/loader/src/injector/entry.cpp @@ -26,10 +26,3 @@ void entry(void *handle) { LOGD("Load injector successfully"); hook_functions(); } - -// The following code runs in zygote/app process - -static inline bool should_load_modules(uint32_t flags) { - return (flags & UNMOUNT_MASK) != UNMOUNT_MASK && - (flags & PROCESS_IS_MAGISK_APP) != PROCESS_IS_MAGISK_APP; -} diff --git a/loader/src/injector/module.hpp b/loader/src/injector/module.hpp index a21982c..77f2987 100644 --- a/loader/src/injector/module.hpp +++ b/loader/src/injector/module.hpp @@ -111,10 +111,9 @@ namespace { PROCESS_GRANTED_ROOT = zygisk::StateFlag::PROCESS_GRANTED_ROOT, PROCESS_ON_DENYLIST = zygisk::StateFlag::PROCESS_ON_DENYLIST, - PROCESS_IS_SYS_UI = (1u << 30), - PROCESS_IS_KSU_APP = (1u << 31), + PROCESS_IS_SYS_UI = (1u << 31), - PRIVATE_MASK = (PROCESS_IS_SYS_UI | PROCESS_IS_KSU_APP) + PRIVATE_MASK = PROCESS_IS_SYS_UI }; struct api_abi_base { diff --git a/zygiskd/src/constants.rs b/zygiskd/src/constants.rs index af88d37..4fea015 100644 --- a/zygiskd/src/constants.rs +++ b/zygiskd/src/constants.rs @@ -38,7 +38,13 @@ pub enum DaemonSocketAction { PingHeartbeat, RequestLogcatFd, ReadNativeBridge, + GetProcessFlags, ReadModules, RequestCompanionSocket, GetModuleDir, } + +// Zygisk process flags +pub const PROCESS_GRANTED_ROOT: u32 = 1 << 0; +pub const PROCESS_ON_DENYLIST: u32 = 1 << 1; +pub const PROCESS_IS_SYSUI: u32 = 1 << 31; diff --git a/zygiskd/src/main.rs b/zygiskd/src/main.rs index 0ae61f3..4c94d1b 100644 --- a/zygiskd/src/main.rs +++ b/zygiskd/src/main.rs @@ -3,6 +3,7 @@ mod companion; mod constants; mod dl; +mod root_impl; mod utils; mod watchdog; mod zygiskd; diff --git a/zygiskd/src/root_impl/kernelsu.rs b/zygiskd/src/root_impl/kernelsu.rs new file mode 100644 index 0000000..3ba96a6 --- /dev/null +++ b/zygiskd/src/root_impl/kernelsu.rs @@ -0,0 +1,29 @@ +use nix::libc::prctl; + +const KERNEL_SU_OPTION: i32 = 0xdeadbeefu32 as i32; + +const CMD_GET_VERSION: u64 = 2; +const CMD_GET_ALLOW_LIST: u64 = 5; +const CMD_GET_DENY_LIST: u64 = 6; + +pub fn is_kernel_su() -> bool { + let mut version = 0; + unsafe { prctl(KERNEL_SU_OPTION, CMD_GET_VERSION, &mut version as *mut i32) }; + version > 0 +} + +pub fn uid_on_allowlist(uid: i32) -> bool { + let mut size = 1024u32; + let mut uids = vec![0; size as usize]; + unsafe { prctl(KERNEL_SU_OPTION, CMD_GET_ALLOW_LIST, uids.as_mut_ptr(), &mut size as *mut u32) }; + uids.resize(size as usize, 0); + uids.contains(&uid) +} + +pub fn uid_on_denylist(uid: i32) -> bool { + let mut size = 1024u32; + let mut uids = vec![0; size as usize]; + unsafe { prctl(KERNEL_SU_OPTION, CMD_GET_DENY_LIST, uids.as_mut_ptr(), &mut size as *mut u32) }; + uids.resize(size as usize, 0); + uids.contains(&uid) +} diff --git a/zygiskd/src/root_impl/magisk.rs b/zygiskd/src/root_impl/magisk.rs new file mode 100644 index 0000000..e2d487c --- /dev/null +++ b/zygiskd/src/root_impl/magisk.rs @@ -0,0 +1,13 @@ + + +pub fn is_magisk() -> bool { + todo!("is_magisk") +} + +pub fn uid_on_allowlist(uid: i32) -> bool { + todo!("uid_on_allowlist") +} + +pub fn uid_on_denylist(uid: i32) -> bool { + todo!("uid_on_denylist") +} diff --git a/zygiskd/src/root_impl/mod.rs b/zygiskd/src/root_impl/mod.rs new file mode 100644 index 0000000..870579c --- /dev/null +++ b/zygiskd/src/root_impl/mod.rs @@ -0,0 +1,24 @@ +mod kernelsu; +mod magisk; + +pub fn uid_on_allowlist(uid: i32) -> bool { + if kernelsu::is_kernel_su() { + kernelsu::uid_on_allowlist(uid) + } else if magisk::is_magisk() { + magisk::uid_on_allowlist(uid) + } else { + log::warn!("Unknown root implementation"); + false + } +} + +pub fn uid_on_denylist(uid: i32) -> bool { + if kernelsu::is_kernel_su() { + kernelsu::uid_on_denylist(uid) + } else if magisk::is_magisk() { + magisk::uid_on_denylist(uid) + } else { + log::warn!("Unknown root implementation"); + false + } +} diff --git a/zygiskd/src/utils.rs b/zygiskd/src/utils.rs index d5fb3f3..c30abc8 100644 --- a/zygiskd/src/utils.rs +++ b/zygiskd/src/utils.rs @@ -40,6 +40,7 @@ pub trait UnixStreamExt { fn read_usize(&mut self) -> Result; fn read_string(&mut self) -> Result; fn write_u8(&mut self, value: u8) -> Result<()>; + fn write_u32(&mut self, value: u32) -> Result<()>; fn write_usize(&mut self, value: usize) -> Result<()>; fn write_string(&mut self, value: &str) -> Result<()>; } @@ -75,6 +76,11 @@ impl UnixStreamExt for UnixStream { Ok(()) } + fn write_u32(&mut self, value: u32) -> Result<()> { + self.write_all(&value.to_ne_bytes())?; + Ok(()) + } + fn write_usize(&mut self, value: usize) -> Result<()> { self.write_all(&value.to_ne_bytes())?; Ok(()) diff --git a/zygiskd/src/zygiskd.rs b/zygiskd/src/zygiskd.rs index 40bb324..54484ef 100644 --- a/zygiskd/src/zygiskd.rs +++ b/zygiskd/src/zygiskd.rs @@ -1,6 +1,6 @@ use crate::constants::DaemonSocketAction; use crate::utils::UnixStreamExt; -use crate::{constants, lp_select, utils}; +use crate::{constants, lp_select, root_impl, utils}; use anyhow::{bail, Result}; use memfd::Memfd; use nix::{ @@ -67,10 +67,10 @@ fn get_arch() -> Result<&'static str> { let output = Command::new("getprop").arg("ro.product.cpu.abi").output()?; let system_arch = String::from_utf8(output.stdout)?; if system_arch.contains("arm") { - return Ok(lp_select!("armeabi-v7a", "arm64-v8a")) + return Ok(lp_select!("armeabi-v7a", "arm64-v8a")); } if system_arch.contains("x86") { - return Ok(lp_select!("x86", "x86_64")) + return Ok(lp_select!("x86", "x86_64")); } bail!("Unsupported system architecture: {}", system_arch); } @@ -193,6 +193,18 @@ fn handle_daemon_action(mut stream: UnixStream, context: &Context) -> Result<()> DaemonSocketAction::ReadNativeBridge => { stream.write_string(&context.native_bridge)?; } + DaemonSocketAction::GetProcessFlags => { + let uid = stream.read_u32()? as i32; + let mut flags = 0u32; + if root_impl::uid_on_allowlist(uid) { + flags |= constants::PROCESS_GRANTED_ROOT; + } + if root_impl::uid_on_denylist(uid) { + flags |= constants::PROCESS_ON_DENYLIST; + } + // TODO: PROCESS_IS_SYSUI? + stream.write_u32(flags)?; + } DaemonSocketAction::ReadModules => { stream.write_usize(context.modules.len())?; for module in context.modules.iter() {