diff --git a/loader/src/common/daemon.cpp b/loader/src/common/daemon.cpp index b096573..b7a4f23 100644 --- a/loader/src/common/daemon.cpp +++ b/loader/src/common/daemon.cpp @@ -125,4 +125,15 @@ namespace zygiskd { PLOGE("Failed to request ZygoteRestart"); } } + + void SystemServerStarted() { + UniqueFd fd = Connect(1); + if (fd == -1) { + PLOGE("Failed to report system server started"); + } else { + if (!socket_utils::write_u8(fd, (uint8_t) SocketAction::SystemServerStarted)) { + PLOGE("Failed to report system server started"); + } + } + } } diff --git a/loader/src/include/daemon.h b/loader/src/include/daemon.h index c762a75..d5b70aa 100644 --- a/loader/src/include/daemon.h +++ b/loader/src/include/daemon.h @@ -60,6 +60,7 @@ namespace zygiskd { RequestCompanionSocket, GetModuleDir, ZygoteRestart, + SystemServerStarted, }; void Init(const char *path = TMP_PATH); @@ -77,4 +78,6 @@ namespace zygiskd { int GetModuleDir(size_t index); void ZygoteRestart(); + + void SystemServerStarted(); } diff --git a/loader/src/injector/hook.cpp b/loader/src/injector/hook.cpp index 01ad7d0..16c3f01 100644 --- a/loader/src/injector/hook.cpp +++ b/loader/src/injector/hook.cpp @@ -634,6 +634,7 @@ void ZygiskContext::nativeForkSystemServer_pre() { return; run_modules_pre(); + zygiskd::SystemServerStarted(); sanitize_fds(); } diff --git a/loader/src/ptracer/main.hpp b/loader/src/ptracer/main.hpp index 35de0c9..72fa101 100644 --- a/loader/src/ptracer/main.hpp +++ b/loader/src/ptracer/main.hpp @@ -15,6 +15,7 @@ enum Command { DAEMON32_SET_INFO = 7, DAEMON64_SET_ERROR_INFO = 8, DAEMON32_SET_ERROR_INFO = 9, + SYSTEM_SERVER_STARTED = 10 }; void send_control_command(Command cmd); diff --git a/loader/src/ptracer/monitor.cpp b/loader/src/ptracer/monitor.cpp index 193b666..4308d9e 100644 --- a/loader/src/ptracer/monitor.cpp +++ b/loader/src/ptracer/monitor.cpp @@ -108,6 +108,7 @@ public: }; static TracingState tracing_state = TRACING; +static std::string prop_path; struct Status { @@ -170,7 +171,7 @@ struct SocketHandler : public EventHandler { LOGE("read %zu < %zu", nread, sizeof(Command)); continue; } - if (msg.cmd >= Command::DAEMON64_SET_INFO) { + if (msg.cmd >= Command::DAEMON64_SET_INFO && msg.cmd != Command::SYSTEM_SERVER_STARTED) { if (nread != sizeof(msg)) { LOGE("cmd %d size %zu != %zu", msg.cmd, nread, sizeof(MsgHead)); continue; @@ -253,6 +254,12 @@ struct SocketHandler : public EventHandler { status32.daemon_error_info = std::string(msg.data); updateStatus(); break; + case SYSTEM_SERVER_STARTED: + LOGD("system server started, mounting prop"); + if (mount(prop_path.c_str(), "/data/adb/modules/zygisksu/module.prop", nullptr, MS_BIND, nullptr) == -1) { + PLOGE("failed to mount prop"); + } + break; } } } @@ -282,9 +289,12 @@ bool should_stop_inject##abi() { \ CREATE_ZYGOTE_START_COUNTER(64) CREATE_ZYGOTE_START_COUNTER(32) - static bool ensure_daemon_created(bool is_64bit) { auto &status = is_64bit ? status64 : status32; + if (is_64bit) { + LOGD("new zygote started, unmounting prop ..."); + umount2(prop_path.c_str(), MNT_DETACH); + } status.zygote_injected = false; if (status.daemon_pid == -1) { auto pid = fork(); @@ -480,7 +490,6 @@ public: } }; -static std::string prop_path; static std::string pre_section; static std::string post_section; @@ -568,10 +577,6 @@ static bool prepare_environment() { PLOGE("chdir %s", wd); return false; } - if (mount(prop_path.c_str(), "/data/adb/modules/zygisksu/module.prop", nullptr, MS_BIND, nullptr) == -1) { - PLOGE("failed to mount prop"); - return false; - } if (!switch_mnt_ns(0, &old_ns)) return false; if (chdir(wd) == -1) { PLOGE("chdir %s", wd); diff --git a/zygiskd/src/constants.rs b/zygiskd/src/constants.rs index 97b5825..c4a60cb 100644 --- a/zygiskd/src/constants.rs +++ b/zygiskd/src/constants.rs @@ -23,6 +23,7 @@ pub const PATH_MODULE_PROP: &str = "module.prop"; pub const ZYGOTE_INJECTED: i32 = lp_select!(5, 4); pub const DAEMON_SET_INFO: i32 = lp_select!(7, 6); pub const DAEMON_SET_ERROR_INFO: i32 = lp_select!(9, 8); +pub const SYSTEM_SERVER_STARTED: i32 = 10; pub const TMP_DIR: &str = "/debug_ramdisk/zygisksu"; pub const CONTROLLER_SOCKET: &str = concatcp!(TMP_DIR, "/init_monitor"); pub const PATH_CP_NAME: &str = concatcp!(TMP_DIR, lp_select!("/cp32.sock", "/cp64.sock")); @@ -39,6 +40,7 @@ pub enum DaemonSocketAction { RequestCompanionSocket, GetModuleDir, ZygoteRestart, + SystemServerStarted, } // Zygisk process flags diff --git a/zygiskd/src/zygiskd.rs b/zygiskd/src/zygiskd.rs index dcb4378..273439a 100644 --- a/zygiskd/src/zygiskd.rs +++ b/zygiskd/src/zygiskd.rs @@ -80,6 +80,10 @@ pub fn main() -> Result<()> { companion.take(); } } + DaemonSocketAction::SystemServerStarted => { + let value = constants::SYSTEM_SERVER_STARTED; + utils::unix_datagram_sendto(constants::CONTROLLER_SOCKET, &value.to_le_bytes())?; + } _ => { thread::spawn(move || { if let Err(e) = handle_daemon_action(action, stream, &context) {