Refactor to better support Magisk

This commit is contained in:
Nullptr
2023-02-28 17:29:26 +08:00
parent 09b6673ab0
commit f465cbf810
11 changed files with 58 additions and 46 deletions

View File

@@ -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)
}

View File

@@ -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<String> {
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<UnixListener> {
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;
}

View File

@@ -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(),

View File

@@ -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;
}