From 87cf885070032be36b8f1532a1bb32086d8e6bc4 Mon Sep 17 00:00:00 2001 From: Nullptr Date: Mon, 20 Mar 2023 17:36:35 +0800 Subject: [PATCH] No hex patch --- loader/src/common/daemon.cpp | 22 ++++++++++++++++++++-- loader/src/include/daemon.h | 3 ++- module/src/customize.sh | 17 +++-------------- zygiskd/src/constants.rs | 5 +---- zygiskd/src/magic.rs | 19 +++++++++++++++++++ zygiskd/src/main.rs | 2 ++ zygiskd/src/utils.rs | 22 ++++++++++++++++++++++ zygiskd/src/watchdog.rs | 27 +++++++++++++-------------- zygiskd/src/zygiskd.rs | 4 ++-- 9 files changed, 84 insertions(+), 37 deletions(-) create mode 100644 zygiskd/src/magic.rs diff --git a/loader/src/common/daemon.cpp b/loader/src/common/daemon.cpp index 4ba297b..0162cf0 100644 --- a/loader/src/common/daemon.cpp +++ b/loader/src/common/daemon.cpp @@ -8,19 +8,37 @@ namespace zygiskd { + bool sMagicRead = false; + static std::string sSocketName; + + void ReadMagic() { + sMagicRead = true; + char magic[PATH_MAX]{0}; + auto fp = fopen(kZygiskMagic, "r"); + if (fp == nullptr) { + PLOGE("Open magic file"); + return; + } + fgets(magic, PATH_MAX, fp); + fclose(fp); + sSocketName.append(LP_SELECT("zygiskd32", "zygiskd64")).append(magic); + LOGD("Socket name: %s", sSocketName.data()); + } + int Connect(uint8_t retry) { + if (!sMagicRead) ReadMagic(); int fd = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); struct sockaddr_un addr{ .sun_family = AF_UNIX, .sun_path={0}, }; - strncpy(addr.sun_path + 1, kZygiskSocket.data(), kZygiskSocket.size()); + strcpy(addr.sun_path + 1, sSocketName.data()); socklen_t socklen = sizeof(sa_family_t) + strlen(addr.sun_path + 1) + 1; while (retry--) { int r = connect(fd, reinterpret_cast(&addr), socklen); if (r == 0) return fd; - LOGW("retrying to connect to zygiskd, sleep 1s"); + LOGW("Retrying to connect to zygiskd, sleep 1s"); sleep(1); } diff --git a/loader/src/include/daemon.h b/loader/src/include/daemon.h index ddf7247..f93874f 100644 --- a/loader/src/include/daemon.h +++ b/loader/src/include/daemon.h @@ -10,7 +10,8 @@ #else # define LP_SELECT(lp32, lp64) lp32 #endif -constexpr std::string_view kZygiskSocket = LP_SELECT("zygiskd32", "zygiskd64") "socket_placeholder"; + +constexpr auto kZygiskMagic = "/system/zygisk_magic"; class UniqueFd { using Fd = int; diff --git a/module/src/customize.sh b/module/src/customize.sh index 5b7d4ad..633c5c9 100644 --- a/module/src/customize.sh +++ b/module/src/customize.sh @@ -146,20 +146,9 @@ else fi fi -if [ $DEBUG = false ]; then - ui_print "- Hex patching" - SOCKET_PATCH=$(tr -dc 'a-f0-9' "$MODPATH/system/zygisk_magic" ui_print "- Setting permissions" chmod 0744 "$MODPATH/daemon.sh" diff --git a/zygiskd/src/constants.rs b/zygiskd/src/constants.rs index a3f50ee..f28073f 100644 --- a/zygiskd/src/constants.rs +++ b/zygiskd/src/constants.rs @@ -19,15 +19,12 @@ pub const MAX_LOG_LEVEL: LevelFilter = LevelFilter::Info; pub const PROP_NATIVE_BRIDGE: &str = "ro.dalvik.vm.native.bridge"; pub const PROP_CTL_RESTART: &str = "ctl.restart"; pub const ZYGISK_LOADER: &str = "libzygisk_loader.so"; - -pub const SOCKET_PLACEHOLDER: &str = "socket_placeholder"; +pub const ZYGISK_MAGIC: &str = "/system/zygisk_magic"; pub const PATH_MODULES_DIR: &str = ".."; pub const PATH_MODULE_PROP: &str = "module.prop"; pub const PATH_ZYGISKD32: &str = "bin/zygiskd32"; pub const PATH_ZYGISKD64: &str = "bin/zygiskd64"; -pub const PATH_TMP_DIR: &str = concatcp!("/dev/", SOCKET_PLACEHOLDER); -pub const PATH_TMP_PROP: &str = concatcp!("/dev/", SOCKET_PLACEHOLDER, "/module.prop"); pub const STATUS_LOADED: &str = "😋 Zygisksu is loaded"; pub const STATUS_CRASHED: &str = "❌ Zygiskd has crashed"; diff --git a/zygiskd/src/magic.rs b/zygiskd/src/magic.rs new file mode 100644 index 0000000..d126d02 --- /dev/null +++ b/zygiskd/src/magic.rs @@ -0,0 +1,19 @@ +use std::fs; +use anyhow::Result; +use crate::constants; +use crate::utils::LateInit; + +pub static MAGIC: LateInit = LateInit::new(); +pub static PATH_TMP_DIR: LateInit = LateInit::new(); +pub static PATH_TMP_PROP: LateInit = LateInit::new(); + +pub fn setup() -> Result<()> { + let name = fs::read_to_string(constants::ZYGISK_MAGIC)?; + let path_tmp_dir = format!("/dev/{}", name); + let path_tmp_prop = format!("{}/module.prop", path_tmp_dir); + + MAGIC.init(name); + PATH_TMP_DIR.init(path_tmp_dir); + PATH_TMP_PROP.init(path_tmp_prop); + Ok(()) +} diff --git a/zygiskd/src/main.rs b/zygiskd/src/main.rs index bc165d9..847ec72 100644 --- a/zygiskd/src/main.rs +++ b/zygiskd/src/main.rs @@ -3,6 +3,7 @@ mod companion; mod constants; mod dl; +mod magic; mod root_impl; mod utils; mod watchdog; @@ -39,6 +40,7 @@ fn init_android_logger(tag: &str) { fn start() -> Result<()> { root_impl::setup(); + magic::setup()?; let cli = Args::parse(); match cli.command { Commands::Watchdog => watchdog::entry()?, diff --git a/zygiskd/src/utils.rs b/zygiskd/src/utils.rs index 8a3beaf..6be7ae0 100644 --- a/zygiskd/src/utils.rs +++ b/zygiskd/src/utils.rs @@ -5,6 +5,7 @@ use std::ffi::c_char; use std::os::fd::FromRawFd; use std::os::unix::net::UnixListener; use nix::sys::socket::{AddressFamily, SockFlag, SockType, UnixAddr}; +use once_cell::sync::OnceCell; use rand::distributions::{Alphanumeric, DistString}; #[cfg(target_pointer_width = "64")] @@ -18,6 +19,27 @@ macro_rules! lp_select { ($lp32:expr, $lp64:expr) => { $lp32 }; } +pub struct LateInit { + cell: OnceCell, +} + +impl LateInit { + pub const fn new() -> Self { + LateInit { cell: OnceCell::new() } + } + + pub fn init(&self, value: T) { + assert!(self.cell.set(value).is_ok()) + } +} + +impl std::ops::Deref for LateInit { + type Target = T; + fn deref(&self) -> &T { + self.cell.get().unwrap() + } +} + pub fn random_string() -> String { Alphanumeric.sample_string(&mut rand::thread_rng(), 8) } diff --git a/zygiskd/src/watchdog.rs b/zygiskd/src/watchdog.rs index c9f0d32..f1bc4b3 100644 --- a/zygiskd/src/watchdog.rs +++ b/zygiskd/src/watchdog.rs @@ -1,4 +1,4 @@ -use crate::{constants, root_impl, utils}; +use crate::{constants, magic, root_impl, utils}; use anyhow::{bail, Result}; use nix::unistd::{getgid, getuid, Pid}; use std::process::{Child, Command}; @@ -12,10 +12,10 @@ use binder::IBinder; use nix::errno::Errno; use nix::libc; use nix::sys::signal::{kill, Signal}; -use once_cell::sync::OnceCell; +use crate::utils::LateInit; -static LOCK: OnceCell = OnceCell::new(); -static PROP_SECTIONS: OnceCell<[String; 2]> = OnceCell::new(); +static LOCK: LateInit = LateInit::new(); +static PROP_SECTIONS: LateInit<[String; 2]> = LateInit::new(); pub fn entry() -> Result<()> { log::info!("Start zygisksu watchdog"); @@ -55,9 +55,9 @@ fn check_permission() -> Result<()> { fn ensure_single_instance() -> Result<()> { log::info!("Ensure single instance"); - let name = String::from("zygiskwd") + constants::SOCKET_PLACEHOLDER; + let name = format!("zygiskwd{}", magic::MAGIC.as_str()); match utils::abstract_namespace_socket(&name) { - Ok(socket) => { let _ = LOCK.set(socket); } + Ok(socket) => LOCK.init(socket), Err(e) => bail!("Failed to acquire lock: {e}. Maybe another instance is running?") } Ok(()) @@ -91,15 +91,15 @@ fn mount_prop() -> Result<()> { sections[section].push('\n'); } } - let _ = PROP_SECTIONS.set(sections); + PROP_SECTIONS.init(sections); - fs::create_dir(constants::PATH_TMP_DIR)?; - fs::File::create(constants::PATH_TMP_PROP)?; + fs::create_dir(magic::PATH_TMP_DIR.as_str())?; + fs::File::create(magic::PATH_TMP_PROP.as_str())?; // FIXME: sys_mount cannot be compiled on 32 bit unsafe { let r = libc::mount( - CString::new(constants::PATH_TMP_PROP)?.as_ptr(), + CString::new(magic::PATH_TMP_PROP.as_str())?.as_ptr(), CString::new(module_prop)?.as_ptr(), std::ptr::null(), libc::MS_BIND, @@ -112,13 +112,12 @@ fn mount_prop() -> Result<()> { } fn set_prop_hint(hint: &str) -> Result<()> { - let mut file = fs::File::create(constants::PATH_TMP_PROP)?; - let sections = PROP_SECTIONS.get().unwrap(); - file.write_all(sections[0].as_bytes())?; + let mut file = fs::File::create(magic::PATH_TMP_PROP.as_str())?; + file.write_all(PROP_SECTIONS[0].as_bytes())?; file.write_all(b"[")?; file.write_all(hint.as_bytes())?; file.write_all(b"] ")?; - file.write_all(sections[1].as_bytes())?; + file.write_all(PROP_SECTIONS[1].as_bytes())?; Ok(()) } diff --git a/zygiskd/src/zygiskd.rs b/zygiskd/src/zygiskd.rs index 1ed620e..6611613 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, root_impl, utils}; +use crate::{constants, lp_select, magic, root_impl, utils}; use anyhow::{bail, Result}; use memfd::Memfd; use nix::{ @@ -135,7 +135,7 @@ fn create_memfd(so_path: &PathBuf) -> Result { fn create_daemon_socket() -> Result { utils::set_socket_create_context("u:r:zygote:s0")?; let prefix = lp_select!("zygiskd32", "zygiskd64"); - let name = String::from(prefix) + constants::SOCKET_PLACEHOLDER; + let name = format!("{}{}", prefix, magic::MAGIC.as_str()); let listener = utils::abstract_namespace_socket(&name)?; log::debug!("Daemon socket: {name}"); Ok(listener)