No hex patch

This commit is contained in:
Nullptr
2023-03-20 17:36:35 +08:00
parent b775d28c23
commit 87cf885070
9 changed files with 84 additions and 37 deletions

View File

@@ -8,19 +8,37 @@
namespace zygiskd { namespace zygiskd {
bool sMagicRead = false;
static std::string sSocketName;
void ReadMagic() {
sMagicRead = true;
char magic[PATH_MAX]{0};
auto fp = fopen(kZygiskMagic, "r");
if (fp == nullptr) {
PLOGE("Open magic file");
return;
}
fgets(magic, PATH_MAX, fp);
fclose(fp);
sSocketName.append(LP_SELECT("zygiskd32", "zygiskd64")).append(magic);
LOGD("Socket name: %s", sSocketName.data());
}
int Connect(uint8_t retry) { int Connect(uint8_t retry) {
if (!sMagicRead) ReadMagic();
int fd = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); int fd = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
struct sockaddr_un addr{ struct sockaddr_un addr{
.sun_family = AF_UNIX, .sun_family = AF_UNIX,
.sun_path={0}, .sun_path={0},
}; };
strncpy(addr.sun_path + 1, kZygiskSocket.data(), kZygiskSocket.size()); strcpy(addr.sun_path + 1, sSocketName.data());
socklen_t socklen = sizeof(sa_family_t) + strlen(addr.sun_path + 1) + 1; socklen_t socklen = sizeof(sa_family_t) + strlen(addr.sun_path + 1) + 1;
while (retry--) { while (retry--) {
int r = connect(fd, reinterpret_cast<struct sockaddr*>(&addr), socklen); int r = connect(fd, reinterpret_cast<struct sockaddr*>(&addr), socklen);
if (r == 0) return fd; if (r == 0) return fd;
LOGW("retrying to connect to zygiskd, sleep 1s"); LOGW("Retrying to connect to zygiskd, sleep 1s");
sleep(1); sleep(1);
} }

View File

@@ -10,7 +10,8 @@
#else #else
# define LP_SELECT(lp32, lp64) lp32 # define LP_SELECT(lp32, lp64) lp32
#endif #endif
constexpr std::string_view kZygiskSocket = LP_SELECT("zygiskd32", "zygiskd64") "socket_placeholder";
constexpr auto kZygiskMagic = "/system/zygisk_magic";
class UniqueFd { class UniqueFd {
using Fd = int; using Fd = int;

View File

@@ -146,20 +146,9 @@ else
fi fi
fi fi
if [ $DEBUG = false ]; then ui_print "- Generating magic"
ui_print "- Hex patching" MAGIC=$(tr -dc 'a-f0-9' </dev/urandom | head -c 18)
SOCKET_PATCH=$(tr -dc 'a-f0-9' </dev/urandom | head -c 18) echo -n "$MAGIC" > "$MODPATH/system/zygisk_magic"
if [ "$HAS32BIT" = true ]; then
sed -i "s/socket_placeholder/$SOCKET_PATCH/g" "$MODPATH/bin/zygiskd32"
sed -i "s/socket_placeholder/$SOCKET_PATCH/g" "$MODPATH/system/lib/libzygisk_injector.so"
sed -i "s/socket_placeholder/$SOCKET_PATCH/g" "$MODPATH/system/lib/libzygisk_loader.so"
fi
if [ "$HAS64BIT" = true ]; then
sed -i "s/socket_placeholder/$SOCKET_PATCH/g" "$MODPATH/bin/zygiskd64"
sed -i "s/socket_placeholder/$SOCKET_PATCH/g" "$MODPATH/system/lib64/libzygisk_injector.so"
sed -i "s/socket_placeholder/$SOCKET_PATCH/g" "$MODPATH/system/lib64/libzygisk_loader.so"
fi
fi
ui_print "- Setting permissions" ui_print "- Setting permissions"
chmod 0744 "$MODPATH/daemon.sh" chmod 0744 "$MODPATH/daemon.sh"

View File

@@ -19,15 +19,12 @@ pub const MAX_LOG_LEVEL: LevelFilter = LevelFilter::Info;
pub const PROP_NATIVE_BRIDGE: &str = "ro.dalvik.vm.native.bridge"; pub const PROP_NATIVE_BRIDGE: &str = "ro.dalvik.vm.native.bridge";
pub const PROP_CTL_RESTART: &str = "ctl.restart"; pub const PROP_CTL_RESTART: &str = "ctl.restart";
pub const ZYGISK_LOADER: &str = "libzygisk_loader.so"; pub const ZYGISK_LOADER: &str = "libzygisk_loader.so";
pub const ZYGISK_MAGIC: &str = "/system/zygisk_magic";
pub const SOCKET_PLACEHOLDER: &str = "socket_placeholder";
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_ZYGISKD32: &str = "bin/zygiskd32"; pub const PATH_ZYGISKD32: &str = "bin/zygiskd32";
pub const PATH_ZYGISKD64: &str = "bin/zygiskd64"; pub const PATH_ZYGISKD64: &str = "bin/zygiskd64";
pub const PATH_TMP_DIR: &str = concatcp!("/dev/", SOCKET_PLACEHOLDER);
pub const PATH_TMP_PROP: &str = concatcp!("/dev/", SOCKET_PLACEHOLDER, "/module.prop");
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";

19
zygiskd/src/magic.rs Normal file
View File

@@ -0,0 +1,19 @@
use std::fs;
use anyhow::Result;
use crate::constants;
use crate::utils::LateInit;
pub static MAGIC: LateInit<String> = LateInit::new();
pub static PATH_TMP_DIR: LateInit<String> = LateInit::new();
pub static PATH_TMP_PROP: LateInit<String> = LateInit::new();
pub fn setup() -> Result<()> {
let name = fs::read_to_string(constants::ZYGISK_MAGIC)?;
let path_tmp_dir = format!("/dev/{}", name);
let path_tmp_prop = format!("{}/module.prop", path_tmp_dir);
MAGIC.init(name);
PATH_TMP_DIR.init(path_tmp_dir);
PATH_TMP_PROP.init(path_tmp_prop);
Ok(())
}

View File

@@ -3,6 +3,7 @@
mod companion; mod companion;
mod constants; mod constants;
mod dl; mod dl;
mod magic;
mod root_impl; mod root_impl;
mod utils; mod utils;
mod watchdog; mod watchdog;
@@ -39,6 +40,7 @@ fn init_android_logger(tag: &str) {
fn start() -> Result<()> { fn start() -> Result<()> {
root_impl::setup(); root_impl::setup();
magic::setup()?;
let cli = Args::parse(); let cli = Args::parse();
match cli.command { match cli.command {
Commands::Watchdog => watchdog::entry()?, Commands::Watchdog => watchdog::entry()?,

View File

@@ -5,6 +5,7 @@ use std::ffi::c_char;
use std::os::fd::FromRawFd; use std::os::fd::FromRawFd;
use std::os::unix::net::UnixListener; use std::os::unix::net::UnixListener;
use nix::sys::socket::{AddressFamily, SockFlag, SockType, UnixAddr}; use nix::sys::socket::{AddressFamily, SockFlag, SockType, UnixAddr};
use once_cell::sync::OnceCell;
use rand::distributions::{Alphanumeric, DistString}; use rand::distributions::{Alphanumeric, DistString};
#[cfg(target_pointer_width = "64")] #[cfg(target_pointer_width = "64")]
@@ -18,6 +19,27 @@ macro_rules! lp_select {
($lp32:expr, $lp64:expr) => { $lp32 }; ($lp32:expr, $lp64:expr) => { $lp32 };
} }
pub struct LateInit<T> {
cell: OnceCell<T>,
}
impl<T> LateInit<T> {
pub const fn new() -> Self {
LateInit { cell: OnceCell::new() }
}
pub fn init(&self, value: T) {
assert!(self.cell.set(value).is_ok())
}
}
impl<T> std::ops::Deref for LateInit<T> {
type Target = T;
fn deref(&self) -> &T {
self.cell.get().unwrap()
}
}
pub fn random_string() -> String { pub fn random_string() -> String {
Alphanumeric.sample_string(&mut rand::thread_rng(), 8) Alphanumeric.sample_string(&mut rand::thread_rng(), 8)
} }

View File

@@ -1,4 +1,4 @@
use crate::{constants, root_impl, utils}; use crate::{constants, magic, root_impl, utils};
use anyhow::{bail, Result}; use anyhow::{bail, Result};
use nix::unistd::{getgid, getuid, Pid}; use nix::unistd::{getgid, getuid, Pid};
use std::process::{Child, Command}; use std::process::{Child, Command};
@@ -12,10 +12,10 @@ use binder::IBinder;
use nix::errno::Errno; use nix::errno::Errno;
use nix::libc; use nix::libc;
use nix::sys::signal::{kill, Signal}; use nix::sys::signal::{kill, Signal};
use once_cell::sync::OnceCell; use crate::utils::LateInit;
static LOCK: OnceCell<UnixListener> = OnceCell::new(); static LOCK: LateInit<UnixListener> = LateInit::new();
static PROP_SECTIONS: OnceCell<[String; 2]> = OnceCell::new(); static PROP_SECTIONS: LateInit<[String; 2]> = LateInit::new();
pub fn entry() -> Result<()> { pub fn entry() -> Result<()> {
log::info!("Start zygisksu watchdog"); log::info!("Start zygisksu watchdog");
@@ -55,9 +55,9 @@ fn check_permission() -> Result<()> {
fn ensure_single_instance() -> Result<()> { fn ensure_single_instance() -> Result<()> {
log::info!("Ensure single instance"); log::info!("Ensure single instance");
let name = String::from("zygiskwd") + constants::SOCKET_PLACEHOLDER; let name = format!("zygiskwd{}", magic::MAGIC.as_str());
match utils::abstract_namespace_socket(&name) { match utils::abstract_namespace_socket(&name) {
Ok(socket) => { let _ = LOCK.set(socket); } Ok(socket) => LOCK.init(socket),
Err(e) => bail!("Failed to acquire lock: {e}. Maybe another instance is running?") Err(e) => bail!("Failed to acquire lock: {e}. Maybe another instance is running?")
} }
Ok(()) Ok(())
@@ -91,15 +91,15 @@ fn mount_prop() -> Result<()> {
sections[section].push('\n'); sections[section].push('\n');
} }
} }
let _ = PROP_SECTIONS.set(sections); PROP_SECTIONS.init(sections);
fs::create_dir(constants::PATH_TMP_DIR)?; fs::create_dir(magic::PATH_TMP_DIR.as_str())?;
fs::File::create(constants::PATH_TMP_PROP)?; fs::File::create(magic::PATH_TMP_PROP.as_str())?;
// FIXME: sys_mount cannot be compiled on 32 bit // FIXME: sys_mount cannot be compiled on 32 bit
unsafe { unsafe {
let r = libc::mount( let r = libc::mount(
CString::new(constants::PATH_TMP_PROP)?.as_ptr(), CString::new(magic::PATH_TMP_PROP.as_str())?.as_ptr(),
CString::new(module_prop)?.as_ptr(), CString::new(module_prop)?.as_ptr(),
std::ptr::null(), std::ptr::null(),
libc::MS_BIND, libc::MS_BIND,
@@ -112,13 +112,12 @@ fn mount_prop() -> Result<()> {
} }
fn set_prop_hint(hint: &str) -> Result<()> { fn set_prop_hint(hint: &str) -> Result<()> {
let mut file = fs::File::create(constants::PATH_TMP_PROP)?; let mut file = fs::File::create(magic::PATH_TMP_PROP.as_str())?;
let sections = PROP_SECTIONS.get().unwrap(); file.write_all(PROP_SECTIONS[0].as_bytes())?;
file.write_all(sections[0].as_bytes())?;
file.write_all(b"[")?; file.write_all(b"[")?;
file.write_all(hint.as_bytes())?; file.write_all(hint.as_bytes())?;
file.write_all(b"] ")?; file.write_all(b"] ")?;
file.write_all(sections[1].as_bytes())?; file.write_all(PROP_SECTIONS[1].as_bytes())?;
Ok(()) Ok(())
} }

View File

@@ -1,6 +1,6 @@
use crate::constants::DaemonSocketAction; use crate::constants::DaemonSocketAction;
use crate::utils::UnixStreamExt; use crate::utils::UnixStreamExt;
use crate::{constants, lp_select, root_impl, utils}; use crate::{constants, lp_select, magic, root_impl, utils};
use anyhow::{bail, Result}; use anyhow::{bail, Result};
use memfd::Memfd; use memfd::Memfd;
use nix::{ use nix::{
@@ -135,7 +135,7 @@ fn create_memfd(so_path: &PathBuf) -> Result<Memfd> {
fn create_daemon_socket() -> Result<UnixListener> { fn create_daemon_socket() -> Result<UnixListener> {
utils::set_socket_create_context("u:r:zygote:s0")?; utils::set_socket_create_context("u:r:zygote:s0")?;
let prefix = lp_select!("zygiskd32", "zygiskd64"); let prefix = lp_select!("zygiskd32", "zygiskd64");
let name = String::from(prefix) + constants::SOCKET_PLACEHOLDER; let name = format!("{}{}", prefix, magic::MAGIC.as_str());
let listener = utils::abstract_namespace_socket(&name)?; let listener = utils::abstract_namespace_socket(&name)?;
log::debug!("Daemon socket: {name}"); log::debug!("Daemon socket: {name}");
Ok(listener) Ok(listener)