From feb34c701da0abc182198c4d05f80f9f27629ae5 Mon Sep 17 00:00:00 2001 From: 5ec1cff Date: Tue, 12 Dec 2023 12:12:42 +0800 Subject: [PATCH] show loaded modules --- loader/src/ptracer/main.hpp | 4 +- loader/src/ptracer/monitor.cpp | 70 +++++++++++++++++++++++++++------- zygiskd/src/constants.rs | 1 + zygiskd/src/utils.rs | 3 ++ zygiskd/src/zygiskd.rs | 22 ++++++++--- 5 files changed, 80 insertions(+), 20 deletions(-) diff --git a/loader/src/ptracer/main.hpp b/loader/src/ptracer/main.hpp index 0e3313e..8e547c1 100644 --- a/loader/src/ptracer/main.hpp +++ b/loader/src/ptracer/main.hpp @@ -10,7 +10,9 @@ enum Command { EXIT = 3, // sent from daemon ZYGOTE64_INJECTED = 4, - ZYGOTE32_INJECTED = 5 + ZYGOTE32_INJECTED = 5, + DAEMON64_SET_INFO = 6, + DAEMON32_SET_INFO = 7, }; void send_control_command(Command cmd); diff --git a/loader/src/ptracer/monitor.cpp b/loader/src/ptracer/monitor.cpp index 90aaab9..e617693 100644 --- a/loader/src/ptracer/monitor.cpp +++ b/loader/src/ptracer/monitor.cpp @@ -120,7 +120,7 @@ struct Status { bool zygote_injected = false; bool daemon_running = false; pid_t daemon_pid = -1; - std::string daemon_crash_reason; + std::string daemon_info; }; static Status status64; @@ -154,20 +154,54 @@ struct SocketHandler : public EventHandler { } void HandleEvent(EventLoop &loop, uint32_t event) override { - Command cmd; + struct [[gnu::packed]] MsgHead { + Command cmd; + int length; + char data[0]; + }; for (;;) { - auto nread = read(sock_fd_, &cmd, sizeof(cmd)); + std::vector buf; + buf.resize(sizeof(MsgHead), 0); + MsgHead &msg = *reinterpret_cast(buf.data()); + ssize_t real_size; + auto nread = recv(sock_fd_, &msg, sizeof(msg), MSG_PEEK); if (nread == -1) { if (errno == EAGAIN) { break; } PLOGE("read socket"); } - if (nread != sizeof(cmd)) { - LOGE("read %zu != %zu", nread, sizeof(cmd)); + if (static_cast(nread) < sizeof(Command)) { + LOGE("read %zu < %zu", nread, sizeof(Command)); continue; } - switch (cmd) { + if (msg.cmd >= Command::DAEMON64_SET_INFO) { + if (nread != sizeof(msg)) { + LOGE("cmd %d size %zu != %zu", msg.cmd, nread, sizeof(MsgHead)); + continue; + } + real_size = sizeof(MsgHead) + msg.length; + } else { + if (nread != sizeof(Command)) { + LOGE("cmd %d size %zu != %zu", msg.cmd, nread, sizeof(Command)); + continue; + } + real_size = sizeof(Command); + } + buf.resize(real_size); + nread = recv(sock_fd_, &msg, real_size, 0); + if (nread == -1) { + if (errno == EAGAIN) { + break; + } + PLOGE("recv"); + continue; + } + if (nread != real_size) { + LOGE("real size %zu != %zu", real_size, nread); + continue; + } + switch (msg.cmd) { case START: if (tracing_state == STOPPING) { tracing_state = TRACING; @@ -202,6 +236,16 @@ struct SocketHandler : public EventHandler { status32.zygote_injected = true; updateStatus(); break; + case DAEMON64_SET_INFO: + LOGD("received daemon64 info %s", msg.data); + status64.daemon_info = std::string(msg.data); + updateStatus(); + break; + case DAEMON32_SET_INFO: + LOGD("received daemon32 info %s", msg.data); + status32.daemon_info = std::string(msg.data); + updateStatus(); + break; } } } @@ -341,8 +385,8 @@ public: auto status_str = parse_status(status); \ LOGW("daemon" #abi "pid %d exited: %s", pid, status_str.c_str()); \ status##abi.daemon_running = false; \ - if (status##abi.daemon_crash_reason.empty()) { \ - status##abi.daemon_crash_reason = status_str; \ + if (status##abi.daemon_info.empty()) { \ + status##abi.daemon_info = status_str; \ } \ updateStatus(); \ continue; \ @@ -465,11 +509,11 @@ static void updateStatus() { if (status##suffix.daemon_running) status_text += "😋running"; \ else { \ status_text += "❌crashed"; \ - if (!status##suffix.daemon_crash_reason.empty()) { \ - status_text += "("; \ - status_text += status##suffix.daemon_crash_reason; \ - status_text += ")"; \ - } \ + } \ + if (!status##suffix.daemon_info.empty()) { \ + status_text += "("; \ + status_text += status##suffix.daemon_info; \ + status_text += ")"; \ } \ } WRITE_STATUS_ABI(64) diff --git a/zygiskd/src/constants.rs b/zygiskd/src/constants.rs index ffa3c62..fbf0ce7 100644 --- a/zygiskd/src/constants.rs +++ b/zygiskd/src/constants.rs @@ -26,6 +26,7 @@ pub const PATH_CP_BIN64: &str = "bin/zygisk-cp64"; pub const PATH_PT_BIN32: &str = "bin/zygisk-ptracer32"; pub const PATH_PT_BIN64: &str = "bin/zygisk-ptracer64"; pub const ZYGOTE_INJECTED: i32 = lp_select!(5, 4); +pub const DAEMON_SET_INFO: i32 = lp_select!(7, 6); pub const MAX_RESTART_COUNT: i32 = 5; diff --git a/zygiskd/src/utils.rs b/zygiskd/src/utils.rs index 2c01e67..7cd80d2 100644 --- a/zygiskd/src/utils.rs +++ b/zygiskd/src/utils.rs @@ -203,10 +203,13 @@ pub fn unix_listener_from_path(path: &str) -> Result { } pub fn unix_datagram_sendto_abstract(path: &str, buf: &[u8]) -> Result<()> { + // FIXME: shall we set create context every time? + set_socket_create_context(get_current_attr()?.as_str())?; let addr = SocketAddrUnix::new_abstract_name(path.as_bytes())?; let socket = socket(AddressFamily::UNIX, SocketType::DGRAM, None)?; connect_unix(&socket, &addr)?; sendto_unix(socket, buf, SendFlags::empty(), &addr)?; + set_socket_create_context("u:r:zygote:s0")?; Ok(()) } diff --git a/zygiskd/src/zygiskd.rs b/zygiskd/src/zygiskd.rs index 22454ba..99efcda 100644 --- a/zygiskd/src/zygiskd.rs +++ b/zygiskd/src/zygiskd.rs @@ -32,11 +32,26 @@ struct Context { pub fn main() -> Result<()> { log::info!("Welcome to Zygisk Next ({}) !", constants::ZKSU_VERSION); + let magic_path = std::env::var("MAGIC")?; + let controller_path = format!("init_monitor{}", magic_path); + log::info!("socket path {}", controller_path); let arch = get_arch()?; log::debug!("Daemon architecture: {arch}"); let modules = load_modules(arch)?; + { + let module_names: Vec<_> = modules.iter() + .map(|m| m.name.as_str()).collect(); + let module_info = format!("loaded {} module(s):{}", modules.len(), module_names.join(",")); + let mut msg = Vec::::new(); + msg.extend_from_slice(&constants::DAEMON_SET_INFO.to_le_bytes()); + msg.extend_from_slice(&(module_info.len() as u32 + 1).to_le_bytes()); + msg.extend_from_slice(module_info.as_bytes()); + msg.extend_from_slice(&[0u8]); + utils::unix_datagram_sendto_abstract(controller_path.as_str(), msg.as_slice()).expect("failed to send info"); + } + let context = Context { modules, }; @@ -50,13 +65,8 @@ pub fn main() -> Result<()> { log::trace!("New daemon action {:?}", action); match action { DaemonSocketAction::PingHeartbeat => { - utils::set_socket_create_context(utils::get_current_attr()?.as_str())?; - let magic_path = std::env::var("MAGIC")?; - let socket_path = format!("init_monitor{}", magic_path); - log::info!("socket path {}", socket_path); let value = constants::ZYGOTE_INJECTED; - utils::unix_datagram_sendto_abstract(socket_path.as_str(), &value.to_le_bytes())?; - utils::set_socket_create_context("u:r:zygote:s0")?; + utils::unix_datagram_sendto_abstract(controller_path.as_str(), &value.to_le_bytes())?; } DaemonSocketAction::ZygoteRestart => { info!("Zygote restarted, clean up companions");