Drop 32 bit support

This commit is contained in:
Nullptr
2023-10-20 19:23:40 +08:00
parent 9051f59bf6
commit 8c0d5b5395
11 changed files with 35 additions and 112 deletions

View File

@@ -35,6 +35,7 @@ android {
defaultConfig { defaultConfig {
externalNativeBuild { externalNativeBuild {
ndkBuild { ndkBuild {
abiFilters("arm64-v8a", "x86_64")
ccachePatch?.let { ccachePatch?.let {
arguments += "NDK_CCACHE=$it" arguments += "NDK_CCACHE=$it"
} }

View File

@@ -5,13 +5,7 @@
#include <unistd.h> #include <unistd.h>
#include <vector> #include <vector>
#if defined(__LP64__) constexpr auto kCPSocketPath = "/dev/zygisk/cp.sock";
# define LP_SELECT(lp32, lp64) lp64
#else
# define LP_SELECT(lp32, lp64) lp32
#endif
constexpr auto kCPSocketPath = "/dev/zygisk/" LP_SELECT("cp32", "cp64") ".sock";
class UniqueFd { class UniqueFd {
using Fd = int; using Fd = int;

View File

@@ -5,11 +5,7 @@
#include <string.h> #include <string.h>
#ifndef LOG_TAG #ifndef LOG_TAG
#if defined(__LP64__) #define LOG_TAG "zygisk-core"
# define LOG_TAG "zygisksu64"
#else
# define LOG_TAG "zygisksu32"
#endif
#endif #endif
#ifdef LOG_DISABLED #ifdef LOG_DISABLED

View File

@@ -61,7 +61,7 @@ else
fi fi
# check architecture # check architecture
if [ "$ARCH" != "arm" ] && [ "$ARCH" != "arm64" ] && [ "$ARCH" != "x86" ] && [ "$ARCH" != "x64" ]; then if [ "$ARCH" != "arm64" ] && [ "$ARCH" != "x64" ]; then
abort "! Unsupported platform: $ARCH" abort "! Unsupported platform: $ARCH"
else else
ui_print "- Device platform: $ARCH" ui_print "- Device platform: $ARCH"
@@ -101,46 +101,28 @@ extract "$ZIPFILE" 'post-fs-data.sh' "$MODPATH"
extract "$ZIPFILE" 'service.sh' "$MODPATH" extract "$ZIPFILE" 'service.sh' "$MODPATH"
mv "$TMPDIR/sepolicy.rule" "$MODPATH" mv "$TMPDIR/sepolicy.rule" "$MODPATH"
HAS32BIT=false && [ -d "/system/lib" ] && HAS32BIT=true
mkdir "$MODPATH/bin" mkdir "$MODPATH/bin"
mkdir "$MODPATH/system" mkdir "$MODPATH/system"
mkdir "$MODPATH/system/lib64" mkdir "$MODPATH/system/lib64"
[ "$HAS32BIT" = true ] && mkdir "$MODPATH/system/lib"
if [ "$ARCH" = "x86" ] || [ "$ARCH" = "x64" ]; then
if [ "$HAS32BIT" = true ]; then
ui_print "- Extracting x86 libraries"
extract "$ZIPFILE" 'bin/x86/zygiskd' "$MODPATH/bin" true
mv "$MODPATH/bin/zygiskd" "$MODPATH/bin/zygisk-cp32"
extract "$ZIPFILE" 'lib/x86/libzygisk.so' "$MODPATH/system/lib" true
fi
if [ "$ARCH" = "x64" ]; then
ui_print "- Extracting x64 libraries" ui_print "- Extracting x64 libraries"
extract "$ZIPFILE" 'bin/x86_64/zygiskd' "$MODPATH/bin" true extract "$ZIPFILE" 'bin/x86_64/zygiskd' "$MODPATH/bin" true
extract "$ZIPFILE" 'lib/x86_64/libzygisk.so' "$MODPATH/system/lib64" true extract "$ZIPFILE" 'lib/x86_64/libzygisk.so' "$MODPATH/system/lib64" true
ln -sf "zygiskd" "$MODPATH/bin/zygisk-wd" ln -sf "zygiskd" "$MODPATH/bin/zygisk-wd"
ln -sf "zygiskd" "$MODPATH/bin/zygisk-fuse" ln -sf "zygiskd" "$MODPATH/bin/zygisk-fuse"
ln -sf "zygiskd" "$MODPATH/bin/zygisk-cp64" ln -sf "zygiskd" "$MODPATH/bin/zygisk-cp"
else else
if [ "$HAS32BIT" = true ]; then
ui_print "- Extracting arm libraries"
extract "$ZIPFILE" 'bin/armeabi-v7a/zygiskd' "$MODPATH/bin" true
mv "$MODPATH/bin/zygiskd" "$MODPATH/bin/zygisk-cp32"
extract "$ZIPFILE" 'lib/armeabi-v7a/libzygisk.so' "$MODPATH/system/lib" true
fi
ui_print "- Extracting arm64 libraries" ui_print "- Extracting arm64 libraries"
extract "$ZIPFILE" 'bin/arm64-v8a/zygiskd' "$MODPATH/bin" true extract "$ZIPFILE" 'bin/arm64-v8a/zygiskd' "$MODPATH/bin" true
extract "$ZIPFILE" 'lib/arm64-v8a/libzygisk.so' "$MODPATH/system/lib64" true extract "$ZIPFILE" 'lib/arm64-v8a/libzygisk.so' "$MODPATH/system/lib64" true
ln -sf "zygiskd" "$MODPATH/bin/zygisk-wd" ln -sf "zygiskd" "$MODPATH/bin/zygisk-wd"
ln -sf "zygiskd" "$MODPATH/bin/zygisk-fuse" ln -sf "zygiskd" "$MODPATH/bin/zygisk-fuse"
ln -sf "zygiskd" "$MODPATH/bin/zygisk-cp64" ln -sf "zygiskd" "$MODPATH/bin/zygisk-cp"
fi fi
ui_print "- Setting permissions" ui_print "- Setting permissions"
set_perm_recursive "$MODPATH/bin" 0 0 0755 0755 set_perm_recursive "$MODPATH/bin" 0 0 0755 0755
set_perm_recursive "$MODPATH/system/lib" 0 0 0755 0644 u:object_r:system_lib_file:s0
set_perm_recursive "$MODPATH/system/lib64" 0 0 0755 0644 u:object_r:system_lib_file:s0 set_perm_recursive "$MODPATH/system/lib64" 0 0 0755 0644 u:object_r:system_lib_file:s0
# If Huawei's Maple is enabled, system_server is created with a special way which is out of Zygisk's control # If Huawei's Maple is enabled, system_server is created with a special way which is out of Zygisk's control

View File

@@ -18,7 +18,7 @@ cargo {
module = "." module = "."
libname = "zygiskd" libname = "zygiskd"
targetIncludes = arrayOf("zygiskd") targetIncludes = arrayOf("zygiskd")
targets = listOf("arm64", "arm", "x86", "x86_64") targets = listOf("arm64", "x86_64")
targetDirectory = "build/intermediates/rust" targetDirectory = "build/intermediates/rust"
val isDebug = gradle.startParameter.taskNames.any { it.toLowerCase().contains("debug") } val isDebug = gradle.startParameter.taskNames.any { it.toLowerCase().contains("debug") }
profile = if (isDebug) "debug" else "release" profile = if (isDebug) "debug" else "release"

View File

@@ -21,21 +21,16 @@ pub const PROP_CTL_RESTART: &str = "ctl.restart";
pub const ZYGISK_LIBRARY: &str = "libzygisk.so"; pub const ZYGISK_LIBRARY: &str = "libzygisk.so";
pub const PATH_PCL: &str = "/system/etc/preloaded-classes"; pub const PATH_PCL: &str = "/system/etc/preloaded-classes";
pub const PATH_SYSTEM_LIB32: &str = "/system/lib"; pub const PATH_SYSTEM_LIB: &str = "/system/lib64";
pub const PATH_SYSTEM_LIB64: &str = "/system/lib64";
pub const PATH_WORK_DIR: &str = "/dev/zygisk"; // TODO: Replace with /debug_ramdisk/zygisk pub const PATH_WORK_DIR: &str = "/dev/zygisk"; // TODO: Replace with /debug_ramdisk/zygisk
pub const PATH_PROP_OVERLAY: &str = concatcp!(PATH_WORK_DIR, "/module.prop"); pub const PATH_PROP_OVERLAY: &str = concatcp!(PATH_WORK_DIR, "/module.prop");
#[cfg(target_pointer_width = "64")] pub const PATH_CP_SOCKET: &str = concatcp!(PATH_WORK_DIR, "/cp.sock");
pub const PATH_CP_SOCKET: &str = concatcp!(PATH_WORK_DIR, "/cp64.sock");
#[cfg(target_pointer_width = "32")]
pub const PATH_CP_SOCKET: &str = concatcp!(PATH_WORK_DIR, "/cp32.sock");
pub const PATH_FUSE_DIR: &str = concatcp!(PATH_WORK_DIR, "/fuse"); pub const PATH_FUSE_DIR: &str = concatcp!(PATH_WORK_DIR, "/fuse");
pub const PATH_FUSE_PCL: &str = concatcp!(PATH_FUSE_DIR, "/preloaded-classes"); pub const PATH_FUSE_PCL: &str = concatcp!(PATH_FUSE_DIR, "/preloaded-classes");
pub const PATH_MODULES_DIR: &str = ".."; pub const PATH_MODULES_DIR: &str = "..";
pub const PATH_MODULE_PROP: &str = "module.prop"; pub const PATH_MODULE_PROP: &str = "module.prop";
pub const PATH_CP32_BIN: &str = "bin/zygisk-cp32"; pub const PATH_CP_BIN: &str = "bin/zygisk-cp";
pub const PATH_CP64_BIN: &str = "bin/zygisk-cp64";
pub const STATUS_LOADED: &str = "😋 Zygisksu is loaded"; pub const STATUS_LOADED: &str = "😋 Zygisksu is loaded";
pub const STATUS_CRASHED: &str = "❌ Zygiskd has crashed"; pub const STATUS_CRASHED: &str = "❌ Zygiskd has crashed";

View File

@@ -83,10 +83,8 @@ impl Filesystem for DelegateFilesystem {
let process = fs::read_to_string(process).unwrap(); let process = fs::read_to_string(process).unwrap();
let process = &process[..process.find('\0').unwrap()]; let process = &process[..process.find('\0').unwrap()];
info!("Process {} is reading preloaded-classes", process); info!("Process {} is reading preloaded-classes", process);
match process { if process == "zygote64" {
// "zygote" => ptrace_zygote(pid, false).unwrap(), ptrace_zygote(pid).unwrap()
"zygote64" => ptrace_zygote(pid, true).unwrap(),
_ => (),
} }
} }
reply.opened(0, 0); reply.opened(0, 0);
@@ -156,14 +154,10 @@ fn find_remote_procedure(
Ok(local_addr - local_module.start() + remote_module.start()) Ok(local_addr - local_module.start() + remote_module.start())
} }
fn ptrace_zygote(pid: u32, is64: bool) -> Result<()> { fn ptrace_zygote(pid: u32) -> Result<()> {
static LAST_32: Mutex<u32> = Mutex::new(0); static LAST: Mutex<u32> = Mutex::new(0);
static LAST_64: Mutex<u32> = Mutex::new(0);
let mut last = match is64 { let mut last = LAST.lock().unwrap();
true => LAST_64.lock().unwrap(),
false => LAST_32.lock().unwrap(),
};
if *last == pid { if *last == pid {
return Ok(()); return Ok(());
} }
@@ -171,13 +165,9 @@ fn ptrace_zygote(pid: u32, is64: bool) -> Result<()> {
let (sender, receiver) = mpsc::channel::<()>(); let (sender, receiver) = mpsc::channel::<()>();
let worker = move || -> Result<()> { let worker = move || -> Result<()> {
info!("Injecting into pid {}, is64 = {}", pid, is64); info!("Injecting into pid {}", pid);
let lib_dir = match is64 { let zygisk_lib = format!("{}/{}", constants::PATH_SYSTEM_LIB, constants::ZYGISK_LIBRARY);
true => constants::PATH_SYSTEM_LIB64, let lib_dir = CString::new(constants::PATH_SYSTEM_LIB)?;
false => constants::PATH_SYSTEM_LIB32,
};
let zygisk_lib = format!("{}/{}", lib_dir, constants::ZYGISK_LIBRARY);
let lib_dir = CString::new(lib_dir)?;
let zygisk_lib = CString::new(zygisk_lib)?; let zygisk_lib = CString::new(zygisk_lib)?;
let libc_base = find_module_for_pid(pid as i32, ANDROID_LIBC)?.start(); let libc_base = find_module_for_pid(pid as i32, ANDROID_LIBC)?.start();
let mmap_remote = find_remote_procedure( let mmap_remote = find_remote_procedure(

View File

@@ -25,8 +25,7 @@ async fn start(name: &str) -> Result<()> {
match name.trim_start_matches("zygisk-") { match name.trim_start_matches("zygisk-") {
"wd" => watchdog::main().await?, "wd" => watchdog::main().await?,
"fuse" => fuse::main()?, "fuse" => fuse::main()?,
"cp32" => zygiskd::main()?, "cp" => zygiskd::main()?,
"cp64" => zygiskd::main()?,
_ => println!("Available commands: wd, fuse, cp"), _ => println!("Available commands: wd, fuse, cp"),
} }
Ok(()) Ok(())

View File

@@ -7,17 +7,6 @@ use std::sync::OnceLock;
use rustix::net::{AddressFamily, bind_unix, listen, socket, SocketAddrUnix, SocketType}; use rustix::net::{AddressFamily, bind_unix, listen, socket, SocketAddrUnix, SocketType};
use rustix::thread::gettid; use rustix::thread::gettid;
#[cfg(target_pointer_width = "64")]
#[macro_export]
macro_rules! lp_select {
($lp32:expr, $lp64:expr) => { $lp64 };
}
#[cfg(target_pointer_width = "32")]
#[macro_export]
macro_rules! lp_select {
($lp32:expr, $lp64:expr) => { $lp32 };
}
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
#[macro_export] #[macro_export]
macro_rules! debug_select { macro_rules! debug_select {

View File

@@ -8,7 +8,7 @@ use std::time::Duration;
use binder::IBinder; use binder::IBinder;
use futures::stream::FuturesUnordered; use futures::stream::FuturesUnordered;
use futures::StreamExt; use futures::StreamExt;
use log::info; use log::{debug, error, info};
use rustix::mount::mount_bind; use rustix::mount::mount_bind;
use rustix::process::{getgid, getuid, kill_process, Pid, Signal}; use rustix::process::{getgid, getuid, kill_process, Pid, Signal};
use tokio::process::{Child, Command}; use tokio::process::{Child, Command};
@@ -124,23 +124,14 @@ async fn spawn_daemon() -> Result<()> {
let mut lives = 5; let mut lives = 5;
loop { loop {
let mut futures = FuturesUnordered::<Pin<Box<dyn Future<Output=Result<()>>>>>::new(); let mut futures = FuturesUnordered::<Pin<Box<dyn Future<Output=Result<()>>>>>::new();
let mut child_ids = vec![]; let daemon = Command::new(constants::PATH_CP_BIN).spawn()?;
let daemon_pid = daemon.id().unwrap();
let daemon32 = Command::new(constants::PATH_CP32_BIN).spawn(); async fn daemon_holder(mut daemon: Child) -> Result<()> {
let daemon64 = Command::new(constants::PATH_CP64_BIN).spawn();
async fn spawn_daemon(mut daemon: Child) -> Result<()> {
let result = daemon.wait().await?; let result = daemon.wait().await?;
log::error!("Daemon process {} died: {}", daemon.id().unwrap(), result); bail!("Daemon process {} died: {}", daemon.id().unwrap(), result);
Ok(())
}
if let Ok(it) = daemon32 {
child_ids.push(it.id().unwrap());
futures.push(Box::pin(spawn_daemon(it)));
}
if let Ok(it) = daemon64 {
child_ids.push(it.id().unwrap());
futures.push(Box::pin(spawn_daemon(it)));
} }
futures.push(Box::pin(daemon_holder(daemon)));
async fn binder_listener() -> Result<()> { async fn binder_listener() -> Result<()> {
let mut binder = loop { let mut binder = loop {
@@ -159,26 +150,23 @@ async fn spawn_daemon() -> Result<()> {
if binder.ping_binder().is_err() { break; } if binder.ping_binder().is_err() { break; }
tokio::time::sleep(Duration::from_secs(1)).await; tokio::time::sleep(Duration::from_secs(1)).await;
} }
log::error!("System server died"); bail!("System server died");
Ok(())
} }
futures.push(Box::pin(binder_listener())); futures.push(Box::pin(binder_listener()));
if let Err(e) = futures.next().await.unwrap() { if let Err(e) = futures.next().await.unwrap() {
log::error!("{}", e); error!("{}", e);
} }
for child in child_ids { debug!("Killing child process {}", daemon_pid);
log::debug!("Killing child process {}", child); let _ = kill_process(Pid::from_raw(daemon_pid as i32).unwrap(), Signal::Kill);
let _ = kill_process(Pid::from_raw(child as i32).unwrap(), Signal::Kill);
}
lives -= 1; lives -= 1;
if lives == 0 { if lives == 0 {
bail!("Too many crashes, abort"); bail!("Too many crashes, abort");
} }
log::error!("Restarting zygote..."); error!("Restarting zygote...");
utils::set_property(constants::PROP_CTL_RESTART, "zygote")?; utils::set_property(constants::PROP_CTL_RESTART, "zygote")?;
} }
} }

View File

@@ -1,8 +1,8 @@
use std::ffi::c_void; use std::ffi::c_void;
use crate::constants::{DaemonSocketAction, ProcessFlags}; use crate::constants::{DaemonSocketAction, ProcessFlags};
use crate::utils::UnixStreamExt; use crate::utils::UnixStreamExt;
use crate::{constants, dl, lp_select, root_impl, utils}; use crate::{constants, dl, root_impl, utils};
use anyhow::{bail, Result}; use anyhow::Result;
use passfd::FdPassingExt; use passfd::FdPassingExt;
use std::sync::Arc; use std::sync::Arc;
use std::thread; use std::thread;
@@ -31,11 +31,11 @@ struct Context {
pub fn main() -> Result<()> { pub fn main() -> Result<()> {
set_parent_process_death_signal(Some(Signal::Kill))?; set_parent_process_death_signal(Some(Signal::Kill))?;
let arch = get_arch()?; let arch = utils::get_property("ro.product.cpu.abi")?;
log::debug!("Daemon architecture: {arch}"); log::debug!("Daemon architecture: {arch}");
log::info!("Load modules"); log::info!("Load modules");
let modules = load_modules(arch)?; let modules = load_modules(&arch)?;
let context = Context { let context = Context {
modules, modules,
@@ -59,17 +59,6 @@ pub fn main() -> Result<()> {
Ok(()) Ok(())
} }
fn get_arch() -> Result<&'static str> {
let system_arch = utils::get_property("ro.product.cpu.abi")?;
if system_arch.contains("arm") {
return Ok(lp_select!("armeabi-v7a", "arm64-v8a"));
}
if system_arch.contains("x86") {
return Ok(lp_select!("x86", "x86_64"));
}
bail!("Unsupported system architecture: {}", system_arch);
}
fn load_modules(arch: &str) -> Result<Vec<Module>> { fn load_modules(arch: &str) -> Result<Vec<Module>> {
let mut modules = Vec::new(); let mut modules = Vec::new();
let dir = match fs::read_dir(constants::PATH_MODULES_DIR) { let dir = match fs::read_dir(constants::PATH_MODULES_DIR) {