From f465cbf81066910ecdc7e47b36b207ba9e2b3d69 Mon Sep 17 00:00:00 2001 From: Nullptr Date: Tue, 28 Feb 2023 17:29:26 +0800 Subject: [PATCH] Refactor to better support Magisk --- build.gradle.kts | 2 +- loader/src/loader/loader.cpp | 4 ++-- module/build.gradle.kts | 4 ++-- module/src/customize.sh | 1 - module/src/daemon.sh | 11 ----------- module/src/post-fs-data.sh | 5 ++--- module/src/service.sh | 8 ++++++++ zygiskd/src/dl.rs | 2 +- zygiskd/src/utils.rs | 24 ++++++++++++++++++++++++ zygiskd/src/watchdog.rs | 29 ++++++++++++++++------------- zygiskd/src/zygiskd.rs | 14 ++------------ 11 files changed, 58 insertions(+), 46 deletions(-) delete mode 100644 module/src/daemon.sh diff --git a/build.gradle.kts b/build.gradle.kts index 5cd62f8..264e9b7 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -36,7 +36,7 @@ val verCode by extra(gitCommitCount) val minKsuVersion by extra(10654) val minKsudVersion by extra(10647) val maxKsuVersion by extra(20000) -val minMagiskVersion by extra(25000) +val minMagiskVersion by extra(25208) val androidMinSdkVersion by extra(29) val androidTargetSdkVersion by extra(33) diff --git a/loader/src/loader/loader.cpp b/loader/src/loader/loader.cpp index 61e433b..21ad1f3 100644 --- a/loader/src/loader/loader.cpp +++ b/loader/src/loader/loader.cpp @@ -70,13 +70,13 @@ void Constructor() { LOGI("Load original native bridge: %s", native_bridge.data()); sOriginalBridge = dlopen(native_bridge.data(), RTLD_NOW); if (sOriginalBridge == nullptr) { - LOGE("dlopen failed: %s", dlerror()); + LOGE("%s", dlerror()); break; } auto* original_native_bridge_itf = dlsym(sOriginalBridge, "NativeBridgeItf"); if (original_native_bridge_itf == nullptr) { - LOGE("dlsym failed: %s", dlerror()); + LOGE("%s", dlerror()); break; } diff --git a/module/build.gradle.kts b/module/build.gradle.kts index 6a7e663..9b6ca60 100644 --- a/module/build.gradle.kts +++ b/module/build.gradle.kts @@ -38,7 +38,7 @@ androidComponents.onVariants { variant -> into(moduleDir) from("${rootProject.projectDir}/README.md") from("$projectDir/src") { - exclude("module.prop", "customize.sh", "daemon.sh") + exclude("module.prop", "customize.sh", "service.sh") filter("eol" to FixCrLfFilter.CrLf.newInstance("lf")) } from("$projectDir/src") { @@ -51,7 +51,7 @@ androidComponents.onVariants { variant -> ) } from("$projectDir/src") { - include("customize.sh", "daemon.sh") + include("customize.sh", "service.sh") val tokens = mapOf( "DEBUG" to if (buildTypeLowered == "debug") "true" else "false", "MIN_KSU_VERSION" to "$minKsuVersion", diff --git a/module/src/customize.sh b/module/src/customize.sh index 51a0dfd..eb885c1 100644 --- a/module/src/customize.sh +++ b/module/src/customize.sh @@ -91,7 +91,6 @@ if [ "$KSU" ]; then fi ui_print "- Extracting module files" -extract "$ZIPFILE" 'daemon.sh' "$MODPATH" extract "$ZIPFILE" 'module.prop' "$MODPATH" extract "$ZIPFILE" 'post-fs-data.sh' "$MODPATH" extract "$ZIPFILE" 'sepolicy.rule' "$MODPATH" diff --git a/module/src/daemon.sh b/module/src/daemon.sh deleted file mode 100644 index 2347bb4..0000000 --- a/module/src/daemon.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/system/bin/sh - -DEBUG=@DEBUG@ - -# shellcheck disable=SC2155 -export NATIVE_BRIDGE=$(getprop ro.dalvik.vm.native.bridge) -[ "$DEBUG" = true ] && export RUST_BACKTRACE=1 - -log -p i -t "zygisksu" "Start watchdog" -resetprop ro.dalvik.vm.native.bridge libzygiskloader.so -exec "bin/zygiskwd" "watchdog" >/dev/null 2>&1 diff --git a/module/src/post-fs-data.sh b/module/src/post-fs-data.sh index 855b70e..5a3d300 100644 --- a/module/src/post-fs-data.sh +++ b/module/src/post-fs-data.sh @@ -6,7 +6,8 @@ if [ "$ZYGISK_ENABLED" ]; then fi cd "$MODDIR" -export NATIVE_BRIDGE=$(getprop ro.dalvik.vm.native.bridge) +getprop ro.dalvik.vm.native.bridge > /dev/.native_bridge +resetprop ro.dalvik.vm.native.bridge libzygiskloader.so if [ "$(which magisk)" ] && [ ".." -ef "/data/adb/modules" ]; then for file in ../*; do @@ -20,5 +21,3 @@ if [ "$(which magisk)" ] && [ ".." -ef "/data/adb/modules" ]; then fi done fi - -sh -c "./daemon.sh $@&" diff --git a/module/src/service.sh b/module/src/service.sh index 3d0dc50..76760a1 100644 --- a/module/src/service.sh +++ b/module/src/service.sh @@ -1,11 +1,15 @@ #!/system/bin/sh +DEBUG=@DEBUG@ + MODDIR=${0%/*} if [ "$ZYGISK_ENABLED" ]; then exit 0 fi cd "$MODDIR" +export NATIVE_BRIDGE=$(cat /dev/.native_bridge) +rm /dev/.native_bridge if [ "$(which magisk)" ] && [ ".." -ef "/data/adb/modules" ]; then for file in ../*; do @@ -19,3 +23,7 @@ if [ "$(which magisk)" ] && [ ".." -ef "/data/adb/modules" ]; then fi done fi + +log -p i -t "zygisksu" "Start watchdog" +[ "$DEBUG" = true ] && export RUST_BACKTRACE=1 +exec "bin/zygiskwd" "watchdog" >/dev/null 2>&1 diff --git a/zygiskd/src/dl.rs b/zygiskd/src/dl.rs index b212dd7..f96f27d 100644 --- a/zygiskd/src/dl.rs +++ b/zygiskd/src/dl.rs @@ -76,7 +76,7 @@ pub unsafe fn dlopen(path: &str, flags: i32) -> Result<*mut c_void> { let result = android_dlopen_ext(filename, flags, &info); if result.is_null() { let e = std::ffi::CStr::from_ptr(libc::dlerror()).to_string_lossy(); - bail!("dlopen failed: {}", e); + bail!(e); } Ok(result) } diff --git a/zygiskd/src/utils.rs b/zygiskd/src/utils.rs index d65323d..8a3beaf 100644 --- a/zygiskd/src/utils.rs +++ b/zygiskd/src/utils.rs @@ -1,6 +1,7 @@ use anyhow::Result; use nix::unistd::gettid; use std::{fs, io::{Read, Write}, os::unix::net::UnixStream, process::Command}; +use std::ffi::c_char; use std::os::fd::FromRawFd; use std::os::unix::net::UnixListener; use nix::sys::socket::{AddressFamily, SockFlag, SockType, UnixAddr}; @@ -37,6 +38,24 @@ pub fn get_native_bridge() -> String { std::env::var("NATIVE_BRIDGE").unwrap_or_default() } +pub fn log_raw(level: i32, tag: &str, message: &str) -> Result<()> { + let tag = std::ffi::CString::new(tag)?; + let message = std::ffi::CString::new(message)?; + unsafe { + __android_log_print(level as i32, tag.as_ptr(), message.as_ptr()); + } + Ok(()) +} + +pub fn get_property(name: &str) -> Result { + let name = std::ffi::CString::new(name)?; + let mut buf = vec![0u8; 92]; + unsafe { + __system_property_get(name.as_ptr(), buf.as_mut_ptr() as *mut c_char); + } + Ok(String::from_utf8(buf)?) +} + pub fn set_property(name: &str, value: &str) -> Result<()> { Command::new("resetprop") .arg(name) @@ -113,3 +132,8 @@ pub fn abstract_namespace_socket(name: &str) -> Result { let listener = unsafe { UnixListener::from_raw_fd(socket) }; Ok(listener) } + +extern "C" { + fn __android_log_print(prio: i32, tag: *const c_char, fmt: *const c_char, ...) -> i32; + fn __system_property_get(name: *const c_char, value: *mut c_char) -> u32; +} diff --git a/zygiskd/src/watchdog.rs b/zygiskd/src/watchdog.rs index 914c984..c9f0d32 100644 --- a/zygiskd/src/watchdog.rs +++ b/zygiskd/src/watchdog.rs @@ -25,7 +25,7 @@ pub fn entry() -> Result<()> { if check_and_set_hint()? == false { log::warn!("Requirements not met, exiting"); utils::set_property(constants::PROP_NATIVE_BRIDGE, &utils::get_native_bridge())?; - return Ok(()) + return Ok(()); } let end = spawn_daemon(); set_prop_hint(constants::STATUS_CRASHED)?; @@ -64,10 +64,21 @@ fn ensure_single_instance() -> Result<()> { } fn mount_prop() -> Result<()> { - let module_prop = fs::File::open(constants::PATH_MODULE_PROP)?; + let module_prop = if let root_impl::RootImpl::Magisk = root_impl::get_impl() { + let magisk_path = Command::new("magisk").arg("--path").output()?; + let mut magisk_path = String::from_utf8(magisk_path.stdout)?; + magisk_path.pop(); // Removing '\n' + let cwd = std::env::current_dir()?; + let dir = cwd.file_name().unwrap().to_string_lossy(); + format!("{magisk_path}/.magisk/modules/{dir}/{}", constants::PATH_MODULE_PROP) + } else { + constants::PATH_MODULE_PROP.to_string() + }; + log::info!("Mount {module_prop}"); + let module_prop_file = fs::File::open(&module_prop)?; let mut section = 0; let mut sections: [String; 2] = [String::new(), String::new()]; - let lines = io::BufReader::new(module_prop).lines(); + let lines = io::BufReader::new(module_prop_file).lines(); for line in lines { let line = line?; if line.starts_with("description=") { @@ -83,21 +94,13 @@ fn mount_prop() -> Result<()> { let _ = PROP_SECTIONS.set(sections); fs::create_dir(constants::PATH_TMP_DIR)?; + fs::File::create(constants::PATH_TMP_PROP)?; // FIXME: sys_mount cannot be compiled on 32 bit unsafe { - let r = libc::mount( - CString::new("tmpfs")?.as_ptr(), - CString::new(constants::PATH_TMP_DIR)?.as_ptr(), - CString::new("tmpfs")?.as_ptr(), - 0, - CString::new("mode=755")?.as_ptr() as *const libc::c_void, - ); - Errno::result(r)?; - let _file = fs::File::create(constants::PATH_TMP_PROP)?; let r = libc::mount( CString::new(constants::PATH_TMP_PROP)?.as_ptr(), - CString::new(constants::PATH_MODULE_PROP)?.as_ptr(), + CString::new(module_prop)?.as_ptr(), std::ptr::null(), libc::MS_BIND, std::ptr::null(), diff --git a/zygiskd/src/zygiskd.rs b/zygiskd/src/zygiskd.rs index 9d4271b..1ed620e 100644 --- a/zygiskd/src/zygiskd.rs +++ b/zygiskd/src/zygiskd.rs @@ -10,7 +10,6 @@ use nix::{ use passfd::FdPassingExt; use std::sync::{Arc, Mutex}; use std::thread; -use std::ffi::c_char; use std::fs; use std::os::unix::{ net::{UnixListener, UnixStream}, @@ -64,8 +63,7 @@ pub fn entry() -> Result<()> { } 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 system_arch = utils::get_property("ro.product.cpu.abi")?; if system_arch.contains("arm") { return Ok(lp_select!("armeabi-v7a", "arm64-v8a")); } @@ -181,12 +179,8 @@ fn handle_daemon_action(mut stream: UnixStream, context: &Context) -> Result<()> 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()); - } + utils::log_raw(level as i32, &tag, &message)?; } } DaemonSocketAction::ReadNativeBridge => { @@ -244,7 +238,3 @@ 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; -}