You've already forked ReZygisk
mirror of
https://github.com/PerformanC/ReZygisk.git
synced 2025-09-06 06:37:01 +00:00
several changes (#21)
* umount for ksu 10763 Signed-off-by: 5ec1cff <ewtqyqyewtqyqy@gmail.com> * Add crashdump sepolicy Signed-off-by: 5ec1cff <ewtqyqyewtqyqy@gmail.com> * Add more information about debug Signed-off-by: 5ec1cff <ewtqyqyewtqyqy@gmail.com> * daemonize zygiskd companion Signed-off-by: 5ec1cff <ewtqyqyewtqyqy@gmail.com> * create zygiskd if crash Signed-off-by: 5ec1cff <ewtqyqyewtqyqy@gmail.com> * injector: use ANDROID_DLEXT_USE_LIBRARY_FD to load module Signed-off-by: 5ec1cff <ewtqyqyewtqyqy@gmail.com> * zygiskd: use file as module fd instead of memfd on debug build Signed-off-by: 5ec1cff <ewtqyqyewtqyqy@gmail.com> * use OwnedFd Signed-off-by: 5ec1cff <ewtqyqyewtqyqy@gmail.com> * dlopen: no need to create ns Signed-off-by: 5ec1cff <ewtqyqyewtqyqy@gmail.com> --------- Signed-off-by: 5ec1cff <ewtqyqyewtqyqy@gmail.com>
This commit is contained in:
@@ -14,7 +14,7 @@ konst = "0.3.4"
|
||||
lazy_static = "1.4.0"
|
||||
log = "0.4.17"
|
||||
memfd = "0.6.2"
|
||||
nix = "0.26.2"
|
||||
nix = { version = "0.26.2", features = ["process","poll"] }
|
||||
num_enum = "0.5.9"
|
||||
once_cell = "1.17.1"
|
||||
passfd = "0.1.5"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use anyhow::Result;
|
||||
use anyhow::{bail, ensure, Result};
|
||||
use nix::unistd::gettid;
|
||||
use std::{fs, io::{Read, Write}, os::unix::net::UnixStream, process::Command};
|
||||
use std::ffi::c_char;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::constants::DaemonSocketAction;
|
||||
use crate::utils::UnixStreamExt;
|
||||
use crate::utils::{UnixStreamExt};
|
||||
use crate::{constants, debug_select, lp_select, magic, root_impl, utils};
|
||||
use anyhow::{bail, Result};
|
||||
use anyhow::{bail, ensure, Result};
|
||||
use memfd::Memfd;
|
||||
use nix::{
|
||||
fcntl::{fcntl, FcntlArg, FdFlag},
|
||||
@@ -11,6 +11,7 @@ use passfd::FdPassingExt;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::thread;
|
||||
use std::fs;
|
||||
use std::os::fd::{IntoRawFd, OwnedFd, RawFd};
|
||||
use std::os::unix::{
|
||||
net::{UnixListener, UnixStream},
|
||||
prelude::AsRawFd,
|
||||
@@ -18,10 +19,13 @@ use std::os::unix::{
|
||||
use std::os::unix::process::CommandExt;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
use nix::poll::{poll, PollFd, PollFlags};
|
||||
use nix::sys::wait::{waitpid, WaitStatus};
|
||||
use nix::unistd::{fork, ForkResult};
|
||||
|
||||
struct Module {
|
||||
name: String,
|
||||
memfd: Memfd,
|
||||
memfd: OwnedFd,
|
||||
companion: Mutex<Option<UnixStream>>,
|
||||
}
|
||||
|
||||
@@ -91,32 +95,30 @@ fn load_modules(arch: &str) -> Result<Vec<Module>> {
|
||||
continue;
|
||||
}
|
||||
log::info!(" Loading module `{name}`...");
|
||||
let memfd = match create_memfd(&so_path, &name) {
|
||||
Ok(memfd) => memfd,
|
||||
let fd = match create_library_fd(&so_path) {
|
||||
Ok(fd) => fd,
|
||||
Err(e) => {
|
||||
log::warn!(" Failed to create memfd for `{name}`: {e}");
|
||||
continue;
|
||||
}
|
||||
};
|
||||
let companion = match spawn_companion(&name, &memfd) {
|
||||
Ok(companion) => companion,
|
||||
Err(e) => {
|
||||
log::warn!(" Failed to spawn companion for `{name}`: {e}");
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
let companion = Mutex::new(companion);
|
||||
let module = Module { name, memfd, companion };
|
||||
let companion = Mutex::new(None);
|
||||
let module = Module { name, memfd: fd, companion };
|
||||
modules.push(module);
|
||||
}
|
||||
|
||||
Ok(modules)
|
||||
}
|
||||
|
||||
fn create_memfd(so_path: &PathBuf, debug_name: &str) -> Result<Memfd> {
|
||||
#[cfg(debug_assertions)]
|
||||
fn create_library_fd(so_path: &PathBuf) -> Result<OwnedFd> {
|
||||
Ok(OwnedFd::from(fs::File::open(so_path)?))
|
||||
}
|
||||
|
||||
#[cfg(not(debug_assertions))]
|
||||
fn create_library_fd(so_path: &PathBuf) -> Result<OwnedFd> {
|
||||
let opts = memfd::MemfdOptions::default().allow_sealing(true);
|
||||
let memfd = opts.create(debug_select!(debug_name, "jit-cache"))?;
|
||||
let memfd = opts.create("jit-cache")?;
|
||||
let file = fs::File::open(so_path)?;
|
||||
let mut reader = std::io::BufReader::new(file);
|
||||
let mut writer = memfd.as_file();
|
||||
@@ -129,7 +131,7 @@ fn create_memfd(so_path: &PathBuf, debug_name: &str) -> Result<Memfd> {
|
||||
seals.insert(memfd::FileSeal::SealSeal);
|
||||
memfd.add_seals(&seals)?;
|
||||
|
||||
Ok(memfd)
|
||||
Ok(OwnedFd::from(memfd.into_file()))
|
||||
}
|
||||
|
||||
fn create_daemon_socket() -> Result<UnixListener> {
|
||||
@@ -141,22 +143,36 @@ fn create_daemon_socket() -> Result<UnixListener> {
|
||||
Ok(listener)
|
||||
}
|
||||
|
||||
fn spawn_companion(name: &str, memfd: &Memfd) -> Result<Option<UnixStream>> {
|
||||
fn spawn_companion(name: &str, fd: &RawFd) -> Result<Option<UnixStream>> {
|
||||
let (mut daemon, companion) = UnixStream::pair()?;
|
||||
// Remove FD_CLOEXEC flag
|
||||
fcntl(companion.as_raw_fd(), FcntlArg::F_SETFD(FdFlag::empty()))?;
|
||||
|
||||
let process = std::env::args().next().unwrap();
|
||||
let nice_name = process.split('/').last().unwrap();
|
||||
Command::new(&process)
|
||||
.arg0(format!("{}-{}", nice_name, name))
|
||||
.arg("companion")
|
||||
.arg(format!("{}", companion.as_raw_fd()))
|
||||
.spawn()?;
|
||||
drop(companion);
|
||||
|
||||
match unsafe { fork()? } {
|
||||
ForkResult::Parent { child, ..} => {
|
||||
if let Ok(WaitStatus::Exited(.., code)) = waitpid(child, None) {
|
||||
ensure!(code == 0, format!("process exited with {code}"));
|
||||
} else {
|
||||
bail!("process exited abnormally");
|
||||
}
|
||||
}
|
||||
ForkResult::Child => {
|
||||
Command::new(&process)
|
||||
.arg0(format!("{}-{}", nice_name, name))
|
||||
.arg("companion")
|
||||
.arg(format!("{}", companion.as_raw_fd()))
|
||||
.spawn()?;
|
||||
drop(companion);
|
||||
|
||||
std::process::exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
daemon.write_string(name)?;
|
||||
daemon.send_fd(memfd.as_raw_fd())?;
|
||||
daemon.send_fd(*fd)?;
|
||||
match daemon.read_u8()? {
|
||||
0 => Ok(None),
|
||||
1 => Ok(Some(daemon)),
|
||||
@@ -213,12 +229,33 @@ fn handle_daemon_action(mut stream: UnixStream, context: &Context) -> Result<()>
|
||||
DaemonSocketAction::RequestCompanionSocket => {
|
||||
let index = stream.read_usize()?;
|
||||
let module = &context.modules[index];
|
||||
let name = &module.name;
|
||||
let fd = &module.memfd;
|
||||
let mut companion = module.companion.lock().unwrap();
|
||||
if let Some(sock) = companion.as_ref() {
|
||||
let mut pfds = [PollFd::new(sock.as_raw_fd(), PollFlags::empty())];
|
||||
poll(&mut pfds, 0)?;
|
||||
if !pfds[0].revents().unwrap().is_empty() {
|
||||
log::error!("poll companion for module `{}` crashed", name);
|
||||
companion.take();
|
||||
}
|
||||
}
|
||||
if companion.as_ref().is_none() {
|
||||
match spawn_companion(&name, &fd.as_raw_fd()) {
|
||||
Ok(c) => {
|
||||
log::trace!(" spawned companion for `{name}`");
|
||||
*companion = c;
|
||||
},
|
||||
Err(e) => {
|
||||
log::warn!(" Failed to spawn companion for `{name}`: {e}");
|
||||
}
|
||||
};
|
||||
}
|
||||
match companion.as_ref() {
|
||||
Some(sock) => {
|
||||
if let Err(_) = sock.send_fd(stream.as_raw_fd()) {
|
||||
log::error!("Companion of module `{}` crashed", module.name);
|
||||
companion.take();
|
||||
log::error!("Companion socket of module `{}` missing", module.name);
|
||||
|
||||
stream.write_u8(0)?;
|
||||
}
|
||||
// Ok: Send by companion
|
||||
|
||||
Reference in New Issue
Block a user