You've already forked ReZygisk
mirror of
https://github.com/PerformanC/ReZygisk.git
synced 2025-09-06 06:37:01 +00:00
Log to zygiskd
This commit is contained in:
@@ -29,7 +29,6 @@ namespace zygiskd {
|
||||
}
|
||||
|
||||
bool PingHeartbeat() {
|
||||
LOGD("Daemon socket: %s", kZygiskSocket.data());
|
||||
UniqueFd fd = Connect(5);
|
||||
if (fd == -1) {
|
||||
PLOGE("Connect to zygiskd");
|
||||
@@ -39,6 +38,16 @@ namespace zygiskd {
|
||||
return true;
|
||||
}
|
||||
|
||||
int RequestLogcatFd() {
|
||||
int fd = Connect(1);
|
||||
if (fd == -1) {
|
||||
PLOGE("RequestLogcatFd");
|
||||
return -1;
|
||||
}
|
||||
socket_utils::write_u8(fd, (uint8_t) SocketAction::RequestLogcatFd);
|
||||
return fd;
|
||||
}
|
||||
|
||||
std::string ReadNativeBridge() {
|
||||
UniqueFd fd = Connect(1);
|
||||
if (fd == -1) {
|
||||
|
||||
36
loader/src/common/logging.cpp
Normal file
36
loader/src/common/logging.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#include <android/log.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "logging.h"
|
||||
#include "socket_utils.h"
|
||||
|
||||
namespace logging {
|
||||
static int logfd = -1;
|
||||
|
||||
void setfd(int fd) {
|
||||
close(logfd);
|
||||
logfd = fd;
|
||||
}
|
||||
|
||||
int getfd() {
|
||||
return logfd;
|
||||
}
|
||||
|
||||
void log(int prio, const char* tag, const char* fmt, ...) {
|
||||
if (logfd == -1) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
__android_log_vprint(prio, tag, fmt, ap);
|
||||
va_end(ap);
|
||||
} else {
|
||||
char buf[BUFSIZ];
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||
va_end(ap);
|
||||
socket_utils::write_u8(logfd, prio);
|
||||
socket_utils::write_string(logfd, tag);
|
||||
socket_utils::write_string(logfd, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -110,6 +110,10 @@ namespace socket_utils {
|
||||
return write_exact<uint8_t>(fd, val);
|
||||
}
|
||||
|
||||
bool write_string(int fd, std::string_view str) {
|
||||
return write_usize(fd, str.size()) && str.size() == xwrite(fd, str.data(), str.size());
|
||||
}
|
||||
|
||||
int recv_fd(int sockfd) {
|
||||
char cmsgbuf[CMSG_SPACE(sizeof(int))];
|
||||
|
||||
|
||||
@@ -52,6 +52,7 @@ namespace zygiskd {
|
||||
|
||||
enum class SocketAction {
|
||||
PingHeartBeat,
|
||||
RequestLogcatFd,
|
||||
ReadNativeBridge,
|
||||
ReadModules,
|
||||
RequestCompanionSocket,
|
||||
@@ -60,6 +61,8 @@ namespace zygiskd {
|
||||
|
||||
bool PingHeartbeat();
|
||||
|
||||
int RequestLogcatFd();
|
||||
|
||||
std::string ReadNativeBridge();
|
||||
|
||||
std::vector<Module> ReadModules();
|
||||
|
||||
@@ -20,15 +20,24 @@
|
||||
#define LOGE(...)
|
||||
#else
|
||||
#ifndef NDEBUG
|
||||
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
|
||||
#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)
|
||||
#define LOGD(...) logging::log(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
|
||||
#define LOGV(...) logging::log(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)
|
||||
#else
|
||||
#define LOGD(...)
|
||||
#define LOGV(...)
|
||||
#endif
|
||||
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
|
||||
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
|
||||
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
|
||||
#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL, LOG_TAG, __VA_ARGS__)
|
||||
#define LOGI(...) logging::log(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
|
||||
#define LOGW(...) logging::log(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
|
||||
#define LOGE(...) logging::log(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
|
||||
#define LOGF(...) logging::log(ANDROID_LOG_FATAL, LOG_TAG, __VA_ARGS__)
|
||||
#define PLOGE(fmt, args...) LOGE(fmt " failed with %d: %s", ##args, errno, strerror(errno))
|
||||
#endif
|
||||
|
||||
namespace logging {
|
||||
void setfd(int fd);
|
||||
|
||||
int getfd();
|
||||
|
||||
[[gnu::format(printf, 3, 4)]]
|
||||
void log(int prio, const char* tag, const char* fmt, ...);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include "logging.h"
|
||||
|
||||
@@ -21,4 +22,6 @@ namespace socket_utils {
|
||||
int recv_fd(int fd);
|
||||
|
||||
bool write_usize(int fd, size_t val);
|
||||
|
||||
bool write_string(int fd, std::string_view str);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include "daemon.h"
|
||||
#include "logging.h"
|
||||
#include "zygisk.hpp"
|
||||
#include "module.hpp"
|
||||
@@ -17,8 +18,10 @@ static void zygisk_cleanup_wait() {
|
||||
|
||||
extern "C" [[gnu::visibility("default")]]
|
||||
void entry(void *handle) {
|
||||
LOGD("Load injector successfully");
|
||||
logging::setfd(zygiskd::RequestLogcatFd());
|
||||
self_handle = handle;
|
||||
|
||||
LOGD("Load injector successfully");
|
||||
hook_functions();
|
||||
}
|
||||
|
||||
|
||||
@@ -204,7 +204,17 @@ DCL_HOOK_FUNC(int, unshare, int flags) {
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Zygisksu changed: No android_log_close hook */
|
||||
// Close logd_fd if necessary to prevent crashing
|
||||
// For more info, check comments in zygisk_log_write
|
||||
DCL_HOOK_FUNC(void, android_log_close) {
|
||||
if (g_ctx == nullptr) {
|
||||
// Happens during un-managed fork like nativeForkApp, nativeForkUsap
|
||||
logging::setfd(-1);
|
||||
} else if (!g_ctx->flags[SKIP_FD_SANITIZATION]) {
|
||||
logging::setfd(-1);
|
||||
}
|
||||
old_android_log_close();
|
||||
}
|
||||
|
||||
// Last point before process secontext changes
|
||||
DCL_HOOK_FUNC(int, selinux_android_setcontext,
|
||||
@@ -595,7 +605,7 @@ void HookContext::app_specialize_post() {
|
||||
// Cleanups
|
||||
env->ReleaseStringUTFChars(args.app->nice_name, process);
|
||||
g_ctx = nullptr;
|
||||
/* Zygisksu changed: No android_log_close */
|
||||
logging::setfd(-1);
|
||||
}
|
||||
|
||||
void HookContext::unload_zygisk() {
|
||||
@@ -668,7 +678,9 @@ void HookContext::nativeForkAndSpecialize_pre() {
|
||||
|
||||
flags[APP_FORK_AND_SPECIALIZE] = true;
|
||||
/* Zygisksu changed: No args.app->fds_to_ignore check since we are Android 10+ */
|
||||
flags[SKIP_FD_SANITIZATION] = true;
|
||||
if (logging::getfd() != -1) {
|
||||
exempted_fds.push_back(logging::getfd());
|
||||
}
|
||||
|
||||
fork_pre();
|
||||
if (pid == 0) {
|
||||
@@ -729,7 +741,7 @@ void hook_functions() {
|
||||
PLT_HOOK_REGISTER(android_runtime_dev, android_runtime_inode, unshare);
|
||||
PLT_HOOK_REGISTER(android_runtime_dev, android_runtime_inode, jniRegisterNativeMethods);
|
||||
PLT_HOOK_REGISTER(android_runtime_dev, android_runtime_inode, selinux_android_setcontext);
|
||||
/* Zygisksu changed: No android_log_close hook */
|
||||
PLT_HOOK_REGISTER_SYM(android_runtime_dev, android_runtime_inode, "__android_log_close", android_log_close);
|
||||
hook_commit();
|
||||
|
||||
// Remove unhooked methods
|
||||
|
||||
@@ -42,9 +42,10 @@ void Constructor() {
|
||||
|
||||
std::string native_bridge;
|
||||
do {
|
||||
LOGD("Ping heartbeat");
|
||||
if (!zygiskd::PingHeartbeat()) break;
|
||||
|
||||
logging::setfd(zygiskd::RequestLogcatFd());
|
||||
|
||||
LOGI("Read native bridge");
|
||||
native_bridge = zygiskd::ReadNativeBridge();
|
||||
|
||||
@@ -63,32 +64,37 @@ void Constructor() {
|
||||
reinterpret_cast<void (*)(void*)>(entry)(handle);
|
||||
} while (false);
|
||||
|
||||
if (native_bridge.empty() || native_bridge == "0") return;
|
||||
LOGI("Load original native bridge: %s", native_bridge.data());
|
||||
sOriginalBridge = dlopen(native_bridge.data(), RTLD_NOW);
|
||||
if (sOriginalBridge == nullptr) {
|
||||
LOGE("dlopen failed: %s", dlerror());
|
||||
return;
|
||||
}
|
||||
do {
|
||||
if (native_bridge.empty() || native_bridge == "0") break;
|
||||
|
||||
auto* original_native_bridge_itf = dlsym(sOriginalBridge, "NativeBridgeItf");
|
||||
if (original_native_bridge_itf == nullptr) {
|
||||
LOGE("dlsym failed: %s", dlerror());
|
||||
return;
|
||||
}
|
||||
LOGI("Load original native bridge: %s", native_bridge.data());
|
||||
sOriginalBridge = dlopen(native_bridge.data(), RTLD_NOW);
|
||||
if (sOriginalBridge == nullptr) {
|
||||
LOGE("dlopen failed: %s", dlerror());
|
||||
break;
|
||||
}
|
||||
|
||||
long sdk = 0;
|
||||
char value[PROP_VALUE_MAX + 1];
|
||||
if (__system_property_get("ro.build.version.sdk", value) > 0) {
|
||||
sdk = strtol(value, nullptr, 10);
|
||||
}
|
||||
auto* original_native_bridge_itf = dlsym(sOriginalBridge, "NativeBridgeItf");
|
||||
if (original_native_bridge_itf == nullptr) {
|
||||
LOGE("dlsym failed: %s", dlerror());
|
||||
break;
|
||||
}
|
||||
|
||||
auto callbacks_size = 0;
|
||||
if (sdk >= __ANDROID_API_R__) {
|
||||
callbacks_size = sizeof(NativeBridgeCallbacks<__ANDROID_API_R__>);
|
||||
} else if (sdk == __ANDROID_API_Q__) {
|
||||
callbacks_size = sizeof(NativeBridgeCallbacks<__ANDROID_API_Q__>);
|
||||
}
|
||||
long sdk = 0;
|
||||
char value[PROP_VALUE_MAX + 1];
|
||||
if (__system_property_get("ro.build.version.sdk", value) > 0) {
|
||||
sdk = strtol(value, nullptr, 10);
|
||||
}
|
||||
|
||||
memcpy(NativeBridgeItf, original_native_bridge_itf, callbacks_size);
|
||||
auto callbacks_size = 0;
|
||||
if (sdk >= __ANDROID_API_R__) {
|
||||
callbacks_size = sizeof(NativeBridgeCallbacks<__ANDROID_API_R__>);
|
||||
} else if (sdk == __ANDROID_API_Q__) {
|
||||
callbacks_size = sizeof(NativeBridgeCallbacks<__ANDROID_API_Q__>);
|
||||
}
|
||||
|
||||
memcpy(NativeBridgeItf, original_native_bridge_itf, callbacks_size);
|
||||
} while (false);
|
||||
|
||||
logging::setfd(-1);
|
||||
}
|
||||
|
||||
@@ -49,7 +49,6 @@ androidComponents.onVariants { variant ->
|
||||
from("$projectDir/src") {
|
||||
include("customize.sh", "daemon.sh")
|
||||
val tokens = mapOf(
|
||||
"ZYGISK_API" to (verCode / 1000).toString(),
|
||||
"DEBUG" to if (buildTypeLowered == "debug") "true" else "false"
|
||||
)
|
||||
filter<ReplaceTokens>("tokens" to tokens)
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
# shellcheck disable=SC2034
|
||||
SKIPUNZIP=1
|
||||
|
||||
ZYGISK_API="@ZYGISK_API@"
|
||||
|
||||
if [ $BOOTMODE ] && [ "$KSU" == "true" ]; then
|
||||
ui_print "- Installing from KernelSU app"
|
||||
else
|
||||
@@ -13,10 +11,16 @@ else
|
||||
fi
|
||||
|
||||
VERSION=$(grep_prop version "${TMPDIR}/module.prop")
|
||||
ui_print "- Installing Zygisksu $VERSION (ZYGISK API $ZYGISK_API)"
|
||||
ui_print "- Installing Zygisksu $VERSION"
|
||||
|
||||
# check KernelSU
|
||||
# ui_print "- KernelSU version: $KSU_VER ($KSU_VER_CODE)"
|
||||
ui_print "- KernelSU version: $KSU_VER ($KSU_VER_CODE)"
|
||||
if [ "$KSU_VER_CODE" -lt 10200 ]; then
|
||||
ui_print "*********************************************************"
|
||||
ui_print "! KernelSU version is too old!"
|
||||
ui_print "! Please update KernelSU to latest version"
|
||||
abort "*********************************************************"
|
||||
fi
|
||||
|
||||
# check android
|
||||
if [ "$API" -lt 29 ]; then
|
||||
@@ -39,11 +43,20 @@ if [ ! -f "$TMPDIR/verify.sh" ]; then
|
||||
ui_print "*********************************************************"
|
||||
ui_print "! Unable to extract verify.sh!"
|
||||
ui_print "! This zip may be corrupted, please try downloading again"
|
||||
abort "*********************************************************"
|
||||
abort "*********************************************************"
|
||||
fi
|
||||
. "$TMPDIR/verify.sh"
|
||||
extract "$ZIPFILE" 'customize.sh' "$TMPDIR/.vunzip"
|
||||
extract "$ZIPFILE" 'verify.sh' "$TMPDIR/.vunzip"
|
||||
extract "$ZIPFILE" 'customize.sh' "$TMPDIR/.vunzip"
|
||||
extract "$ZIPFILE" 'verify.sh' "$TMPDIR/.vunzip"
|
||||
extract "$ZIPFILE" 'sepolicy.rule' "$TMPDIR"
|
||||
|
||||
ui_print "- Checking SELinux patches"
|
||||
if ! /data/adb/ksud sepolicy check "$TMPDIR/sepolicy.rule"; then
|
||||
ui_print "*********************************************************"
|
||||
ui_print "! Unable to apply SELinux patches!"
|
||||
ui_print "! Your kernel may not support SELinux patch fully"
|
||||
abort "*********************************************************"
|
||||
fi
|
||||
|
||||
ui_print "- Extracting module files"
|
||||
extract "$ZIPFILE" 'daemon.sh' "$MODPATH"
|
||||
|
||||
@@ -15,6 +15,7 @@ pub const PATH_DAEMON_LOCK: &str = concatcp!(PATH_ZYGISKSU_DIR, "/zygiskd.lock")
|
||||
#[repr(u8)]
|
||||
pub enum DaemonSocketAction {
|
||||
PingHeartbeat,
|
||||
RequestLogcatFd,
|
||||
ReadNativeBridge,
|
||||
ReadModules,
|
||||
RequestCompanionSocket,
|
||||
|
||||
@@ -39,8 +39,10 @@ pub trait UnixStreamExt {
|
||||
fn read_u8(&mut self) -> Result<u8>;
|
||||
fn read_u32(&mut self) -> Result<u32>;
|
||||
fn read_usize(&mut self) -> Result<usize>;
|
||||
fn read_string(&mut self) -> Result<String>;
|
||||
fn write_u8(&mut self, value: u8) -> Result<()>;
|
||||
fn write_usize(&mut self, value: usize) -> Result<()>;
|
||||
fn write_string(&mut self, value: &str) -> Result<()>;
|
||||
}
|
||||
|
||||
impl UnixStreamExt for UnixStream {
|
||||
@@ -62,6 +64,13 @@ impl UnixStreamExt for UnixStream {
|
||||
Ok(usize::from_ne_bytes(buf))
|
||||
}
|
||||
|
||||
fn read_string(&mut self) -> Result<String> {
|
||||
let len = self.read_usize()?;
|
||||
let mut buf = vec![0u8; len];
|
||||
self.read_exact(&mut buf)?;
|
||||
Ok(String::from_utf8(buf)?)
|
||||
}
|
||||
|
||||
fn write_u8(&mut self, value: u8) -> Result<()> {
|
||||
self.write_all(&value.to_ne_bytes())?;
|
||||
Ok(())
|
||||
@@ -71,6 +80,12 @@ impl UnixStreamExt for UnixStream {
|
||||
self.write_all(&value.to_ne_bytes())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_string(&mut self, value: &str) -> Result<()> {
|
||||
self.write_usize(value.len())?;
|
||||
self.write_all(value.as_bytes())?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Replace with SockAddrExt::from_abstract_name when it's stable
|
||||
|
||||
@@ -8,10 +8,9 @@ use nix::{
|
||||
unistd::getppid,
|
||||
};
|
||||
use passfd::FdPassingExt;
|
||||
use std::io::Write;
|
||||
use std::sync::Arc;
|
||||
use std::thread;
|
||||
use std::ffi::c_void;
|
||||
use std::ffi::{c_char, c_void};
|
||||
use std::fs;
|
||||
use std::os::unix::{
|
||||
net::{UnixListener, UnixStream},
|
||||
@@ -187,15 +186,28 @@ fn handle_daemon_action(mut stream: UnixStream, context: &Context) -> Result<()>
|
||||
DaemonSocketAction::PingHeartbeat => {
|
||||
restore_native_bridge()?;
|
||||
}
|
||||
DaemonSocketAction::RequestLogcatFd => {
|
||||
loop {
|
||||
let level = match stream.read_u8() {
|
||||
Ok(level) => level,
|
||||
Err(_) => break,
|
||||
};
|
||||
let tag = stream.read_string()?;
|
||||
let tag = std::ffi::CString::new(tag)?;
|
||||
let message = stream.read_string()?;
|
||||
let message = std::ffi::CString::new(message)?;
|
||||
unsafe {
|
||||
__android_log_print(level as i32, tag.as_ptr(), message.as_ptr());
|
||||
}
|
||||
}
|
||||
}
|
||||
DaemonSocketAction::ReadNativeBridge => {
|
||||
stream.write_usize(context.native_bridge.len())?;
|
||||
stream.write_all(context.native_bridge.as_bytes())?;
|
||||
stream.write_string(&context.native_bridge)?;
|
||||
}
|
||||
DaemonSocketAction::ReadModules => {
|
||||
stream.write_usize(context.modules.len())?;
|
||||
for module in context.modules.iter() {
|
||||
stream.write_usize(module.name.len())?;
|
||||
stream.write_all(module.name.as_bytes())?;
|
||||
stream.write_string(&module.name)?;
|
||||
stream.send_fd(module.memfd.as_raw_fd())?;
|
||||
}
|
||||
}
|
||||
@@ -225,3 +237,7 @@ fn handle_daemon_action(mut stream: UnixStream, context: &Context) -> Result<()>
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
fn __android_log_print(prio: i32, tag: *const c_char, fmt: *const c_char, ...) -> i32;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user