From db60c3185e39c2bade15c3801a07cad5a9544054 Mon Sep 17 00:00:00 2001 From: 5ec1cff Date: Tue, 12 Dec 2023 00:43:30 +0800 Subject: [PATCH] show injection status --- loader/src/ptracer/main.hpp | 7 ++++-- loader/src/ptracer/monitor.cpp | 39 +++++++++++++++++++++------------- zygiskd/src/constants.rs | 1 + zygiskd/src/utils.rs | 19 +++++++++++++++-- zygiskd/src/zygiskd.rs | 8 ++++++- 5 files changed, 54 insertions(+), 20 deletions(-) diff --git a/loader/src/ptracer/main.hpp b/loader/src/ptracer/main.hpp index 0ec8f35..0e3313e 100644 --- a/loader/src/ptracer/main.hpp +++ b/loader/src/ptracer/main.hpp @@ -6,8 +6,11 @@ bool trace_zygote(int pid); enum Command { START = 1, - STOP, - EXIT + STOP = 2, + EXIT = 3, + // sent from daemon + ZYGOTE64_INJECTED = 4, + ZYGOTE32_INJECTED = 5 }; void send_control_command(Command cmd); diff --git a/loader/src/ptracer/monitor.cpp b/loader/src/ptracer/monitor.cpp index b9e72c4..c692599 100644 --- a/loader/src/ptracer/monitor.cpp +++ b/loader/src/ptracer/monitor.cpp @@ -114,6 +114,18 @@ public: static TracingState tracing_state = TRACING; + +struct Status { + bool supported = false; + bool zygote_injected = false; + bool daemon_running = false; + pid_t daemon_pid = -1; + std::string daemon_crash_reason; +}; + +static Status status64; +static Status status32; + struct SocketHandler : public EventHandler { int sock_fd_; @@ -182,6 +194,14 @@ struct SocketHandler : public EventHandler { updateStatus(); loop.Stop(); break; + case ZYGOTE64_INJECTED: + status64.zygote_injected = true; + updateStatus(); + break; + case ZYGOTE32_INJECTED: + status32.zygote_injected = true; + updateStatus(); + break; } } } @@ -211,19 +231,10 @@ bool should_stop_inject##abi() { \ CREATE_ZYGOTE_START_COUNTER(64) CREATE_ZYGOTE_START_COUNTER(32) -struct Status { - bool supported = false; - bool zygote_injected = false; - bool daemon_running = false; - pid_t daemon_pid = -1; - std::string daemon_crash_reason; -}; - -static Status status64; -static Status status32; static bool ensure_daemon_created(bool is_64bit) { auto &status = is_64bit ? status64 : status32; + status.zygote_injected = false; if (status.daemon_pid == -1) { auto pid = fork(); if (pid < 0) { @@ -239,7 +250,6 @@ static bool ensure_daemon_created(bool is_64bit) { status.supported = true; status.daemon_pid = pid; status.daemon_running = true; - updateStatus(); return true; } } else { @@ -363,7 +373,6 @@ public: LOGW("zygote" #abi " restart too much times, stop injecting"); \ tracing_state = STOPPING; \ monitor_stop_reason = "zygote crashed"; \ - updateStatus(); \ ptrace(PTRACE_INTERRUPT, 1, 0, 0); \ break; \ } \ @@ -371,7 +380,6 @@ public: LOGW("daemon" #abi " not running, stop injecting"); \ tracing_state = STOPPING; \ monitor_stop_reason = "daemon not running"; \ - updateStatus(); \ ptrace(PTRACE_INTERRUPT, 1, 0, 0); \ break; \ } \ @@ -401,6 +409,7 @@ public: } } } while (false); + updateStatus(); } else { LOGE("process %d received unknown status %s", pid, parse_status(status).c_str()); @@ -445,7 +454,7 @@ static void updateStatus() { status_text += monitor_stop_reason; status_text += ")"; } - status_text += ", "; + status_text += ","; #define WRITE_STATUS_ABI(suffix) \ if (status##suffix.supported) { \ status_text += " zygote" #suffix ":"; \ @@ -464,7 +473,7 @@ static void updateStatus() { } WRITE_STATUS_ABI(64) WRITE_STATUS_ABI(32) - fprintf(prop.get(), "%s[%s]%s", pre_section.c_str(), status_text.c_str(), post_section.c_str()); + fprintf(prop.get(), "%s[%s] %s", pre_section.c_str(), status_text.c_str(), post_section.c_str()); } static bool prepare_environment() { diff --git a/zygiskd/src/constants.rs b/zygiskd/src/constants.rs index a2b82ef..ffa3c62 100644 --- a/zygiskd/src/constants.rs +++ b/zygiskd/src/constants.rs @@ -25,6 +25,7 @@ pub const PATH_CP_BIN32: &str = "bin/zygisk-cp32"; 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 MAX_RESTART_COUNT: i32 = 5; diff --git a/zygiskd/src/utils.rs b/zygiskd/src/utils.rs index 3c953e6..2c01e67 100644 --- a/zygiskd/src/utils.rs +++ b/zygiskd/src/utils.rs @@ -2,10 +2,12 @@ use anyhow::Result; use std::{fs, io::{Read, Write}, os::unix::net::UnixStream}; use std::ffi::{c_char, c_void, CStr, CString}; use std::os::fd::{AsFd, AsRawFd}; -use std::os::unix::net::UnixListener; +use std::os::unix::net::{UnixDatagram, UnixListener}; use std::process::Command; use std::sync::OnceLock; -use rustix::net::{AddressFamily, bind_unix, listen, socket, SocketAddrUnix, SocketType}; +use bitflags::Flags; +use rustix::net::{AddressFamily, bind_unix, connect_unix, listen, SendFlags, sendto_unix, socket, SocketAddrUnix, SocketType}; +use rustix::path::Arg; use rustix::thread::gettid; #[cfg(target_pointer_width = "64")] @@ -63,6 +65,11 @@ pub fn set_socket_create_context(context: &str) -> Result<()> { } } +pub fn get_current_attr() -> Result { + let s = fs::read("/proc/self/attr/current")?; + Ok(s.to_string_lossy().to_string()) +} + pub fn chcon(path: &str, context: &str) -> Result<()> { Command::new("chcon").arg(context).arg(path).status()?; Ok(()) @@ -195,6 +202,14 @@ pub fn unix_listener_from_path(path: &str) -> Result { Ok(UnixListener::from(socket)) } +pub fn unix_datagram_sendto_abstract(path: &str, buf: &[u8]) -> Result<()> { + 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)?; + Ok(()) +} + pub fn check_unix_socket(stream: &UnixStream, block: bool) -> bool { unsafe { let mut pfd = libc::pollfd { diff --git a/zygiskd/src/zygiskd.rs b/zygiskd/src/zygiskd.rs index 0b3d75b..11ee31b 100644 --- a/zygiskd/src/zygiskd.rs +++ b/zygiskd/src/zygiskd.rs @@ -50,7 +50,13 @@ pub fn main() -> Result<()> { log::trace!("New daemon action {:?}", action); match action { DaemonSocketAction::PingHeartbeat => { - // Do nothing + 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")?; } DaemonSocketAction::ZygoteRestart => { info!("Zygote restarted, clean up companions");