diff --git a/zygiskd/src/main.rs b/zygiskd/src/main.rs index aef46c9..0ae61f3 100644 --- a/zygiskd/src/main.rs +++ b/zygiskd/src/main.rs @@ -43,7 +43,7 @@ fn main() { let cli = Args::parse(); let result = match cli.command { Commands::Watchdog => watchdog::entry(), - Commands::Daemon => zygiskd::entry(lp_select!(false, true)), + Commands::Daemon => zygiskd::entry(), Commands::Companion { fd } => companion::entry(fd), }; diff --git a/zygiskd/src/watchdog.rs b/zygiskd/src/watchdog.rs index 54dc7d7..7ca6738 100644 --- a/zygiskd/src/watchdog.rs +++ b/zygiskd/src/watchdog.rs @@ -1,4 +1,4 @@ -use crate::constants; +use crate::{constants, utils}; use anyhow::{bail, Result}; use nix::fcntl::{flock, FlockArg}; use nix::unistd::{getgid, getuid}; @@ -6,6 +6,8 @@ use std::os::unix::prelude::AsRawFd; use std::process::{Child, Command}; use std::sync::mpsc; use std::{fs, thread}; +use std::path::Path; +use std::time::Duration; static mut LOCK_FILE: Option = None; @@ -61,7 +63,9 @@ fn spawn_daemon() -> Result<()> { let daemon32 = Command::new(constants::PATH_ZYGISKD32).arg("daemon").spawn(); let daemon64 = Command::new(constants::PATH_ZYGISKD64).arg("daemon").spawn(); let (sender, receiver) = mpsc::channel(); - let spawn = |mut daemon: Child| { + let mut waiting = vec![]; + let mut spawn = |mut daemon: Child, socket: &'static str| { + waiting.push(socket); let sender = sender.clone(); thread::spawn(move || { let result = daemon.wait().unwrap(); @@ -70,8 +74,22 @@ fn spawn_daemon() -> Result<()> { sender.send(()).unwrap(); }); }; - if let Ok(it) = daemon32 { spawn(it) } - if let Ok(it) = daemon64 { spawn(it) } + if let Ok(it) = daemon32 { spawn(it, "/dev/socket/zygote_secondary") } + if let Ok(it) = daemon64 { spawn(it, "/dev/socket/zygote") } + + waiting.into_iter().for_each(|socket| wait_zygote(socket)); + log::info!("Zygote ready, restore native bridge"); + utils::restore_native_bridge()?; + let _ = receiver.recv(); bail!("Daemon process died"); } + +fn wait_zygote(socket: &str) -> () { + let path = Path::new(socket); + loop { + if path.exists() { return; } + log::debug!("{socket} not exists, wait for 1s..."); + thread::sleep(Duration::from_secs(1)); + } +} diff --git a/zygiskd/src/zygiskd.rs b/zygiskd/src/zygiskd.rs index 1e000a3..4db845e 100644 --- a/zygiskd/src/zygiskd.rs +++ b/zygiskd/src/zygiskd.rs @@ -1,6 +1,6 @@ use crate::constants::DaemonSocketAction; -use crate::utils::{restore_native_bridge, UnixStreamExt}; -use crate::{constants, utils}; +use crate::utils::UnixStreamExt; +use crate::{constants, lp_select, utils}; use anyhow::{bail, Result}; use memfd::Memfd; use nix::{ @@ -31,10 +31,10 @@ struct Context { modules: Vec, } -pub fn entry(is64: bool) -> Result<()> { +pub fn entry() -> Result<()> { unsafe { libc::prctl(libc::PR_SET_PDEATHSIG, libc::SIGKILL) }; - let arch = get_arch(is64)?; + let arch = get_arch()?; log::debug!("Daemon architecture: {arch}"); log::info!("Load modules"); @@ -47,7 +47,7 @@ pub fn entry(is64: bool) -> Result<()> { let context = Arc::new(context); log::info!("Create socket"); - let listener = create_daemon_socket(is64)?; + let listener = create_daemon_socket()?; log::info!("Handle zygote connections"); for stream in listener.incoming() { @@ -63,18 +63,16 @@ pub fn entry(is64: bool) -> Result<()> { Ok(()) } -fn get_arch(is64: bool) -> Result<&'static str> { +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)?; - let is_arm = system_arch.contains("arm"); - let is_x86 = system_arch.contains("x86"); - match (is_arm, is_x86, is64) { - (true, _, false) => Ok("armeabi-v7a"), - (true, _, true) => Ok("arm64-v8a"), - (_, true, false) => Ok("x86"), - (_, true, true) => Ok("x86_64"), - _ => bail!("Unsupported system architecture: {}", system_arch), + if system_arch.contains("arm") { + return Ok(lp_select!("armeabi-v7a", "arm64-v8a")) } + if system_arch.contains("x86") { + return Ok(lp_select!("x86", "x86_64")) + } + bail!("Unsupported system architecture: {}", system_arch); } fn load_modules(arch: &str) -> Result> { @@ -137,9 +135,9 @@ fn create_memfd(name: &str, so_path: &PathBuf) -> Result { Ok(memfd) } -fn create_daemon_socket(is64: bool) -> Result { +fn create_daemon_socket() -> Result { utils::set_socket_create_context("u:r:zygote:s0")?; - let suffix = if is64 { "zygiskd64" } else { "zygiskd32" }; + let suffix = lp_select!("zygiskd32", "zygiskd64"); let name = String::from(suffix) + constants::SOCKET_PLACEHOLDER; let listener = utils::abstract_namespace_socket(&name)?; log::debug!("Daemon socket: {name}"); @@ -175,7 +173,7 @@ fn handle_daemon_action(mut stream: UnixStream, context: &Context) -> Result<()> log::trace!("New daemon action {:?}", action); match action { DaemonSocketAction::PingHeartbeat => { - restore_native_bridge()?; + // Do nothing } DaemonSocketAction::RequestLogcatFd => { loop {