C++/Rust 2 way binding for MagiskD

This commit is contained in:
topjohnwu 2023-11-17 13:35:50 -08:00
parent 6c0966b795
commit 8d5b9e5329
11 changed files with 234 additions and 176 deletions

View File

@ -325,3 +325,9 @@ void exec_command_async(Args &&...args) {
}; };
exec_command(exec); exec_command(exec);
} }
template <typename T>
constexpr auto operator+(T e) noexcept ->
std::enable_if_t<std::is_enum<T>::value, std::underlying_type_t<T>> {
return static_cast<std::underlying_type_t<T>>(e);
}

View File

@ -14,17 +14,6 @@
using namespace std; using namespace std;
// Boot stage state
enum : int {
FLAG_NONE = 0,
FLAG_POST_FS_DATA_DONE = (1 << 0),
FLAG_LATE_START_DONE = (1 << 1),
FLAG_BOOT_COMPLETE = (1 << 2),
FLAG_SAFE_MODE = (1 << 3),
};
static int boot_state = FLAG_NONE;
bool zygisk_enabled = false; bool zygisk_enabled = false;
/********* /*********
@ -243,31 +232,6 @@ static bool magisk_env() {
return true; return true;
} }
static bool check_data() {
bool mnt = false;
file_readline("/proc/mounts", [&](string_view s) {
if (str_contains(s, " /data ") && !str_contains(s, "tmpfs")) {
mnt = true;
return false;
}
return true;
});
if (!mnt)
return false;
auto crypto = get_prop("ro.crypto.state");
if (!crypto.empty()) {
if (crypto != "encrypted") {
// Unencrypted, we can directly access data
return true;
} else {
// Encrypted, check whether vold is started
return !get_prop("init.svc.vold").empty();
}
}
// ro.crypto.state is not set, assume it's unencrypted
return true;
}
void unlock_blocks() { void unlock_blocks() {
int fd, dev, OFF = 0; int fd, dev, OFF = 0;
@ -341,10 +305,7 @@ static bool check_key_combo() {
extern int disable_deny(); extern int disable_deny();
void MagiskD::post_fs_data() const { void MagiskD::post_fs_data() const {
if (!check_data()) as_rust().setup_logfile();
return;
setup_logfile();
LOGI("** post-fs-data mode running\n"); LOGI("** post-fs-data mode running\n");
@ -364,7 +325,7 @@ void MagiskD::post_fs_data() const {
if (get_prop("persist.sys.safemode", true) == "1" || if (get_prop("persist.sys.safemode", true) == "1" ||
get_prop("ro.sys.safemode") == "1" || check_key_combo()) { get_prop("ro.sys.safemode") == "1" || check_key_combo()) {
boot_state |= FLAG_SAFE_MODE; as_rust().enable_safe_mode();
// Disable all modules and denylist so next boot will be clean // Disable all modules and denylist so next boot will be clean
disable_modules(); disable_modules();
disable_deny(); disable_deny();
@ -380,23 +341,19 @@ void MagiskD::post_fs_data() const {
early_abort: early_abort:
// We still do magic mount because root itself might need it // We still do magic mount because root itself might need it
load_modules(); load_modules();
boot_state |= FLAG_POST_FS_DATA_DONE;
} }
void MagiskD::late_start() const { void MagiskD::late_start() const {
setup_logfile(); as_rust().setup_logfile();
LOGI("** late_start service mode running\n"); LOGI("** late_start service mode running\n");
exec_common_scripts("service"); exec_common_scripts("service");
exec_module_scripts("service"); exec_module_scripts("service");
boot_state |= FLAG_LATE_START_DONE;
} }
void MagiskD::boot_complete() const { void MagiskD::boot_complete() const {
boot_state |= FLAG_BOOT_COMPLETE; as_rust().setup_logfile();
setup_logfile();
LOGI("** boot-complete triggered\n"); LOGI("** boot-complete triggered\n");
@ -410,30 +367,3 @@ void MagiskD::boot_complete() const {
reset_zygisk(true); reset_zygisk(true);
} }
void boot_stage_handler(int client, int code) {
// Make sure boot stage execution is always serialized
static pthread_mutex_t stage_lock = PTHREAD_MUTEX_INITIALIZER;
mutex_guard lock(stage_lock);
MagiskD daemon;
switch (code) {
case MainRequest::POST_FS_DATA:
if ((boot_state & FLAG_POST_FS_DATA_DONE) == 0)
daemon.post_fs_data();
close(client);
break;
case MainRequest::LATE_START:
close(client);
if ((boot_state & FLAG_POST_FS_DATA_DONE) && (boot_state & FLAG_SAFE_MODE) == 0)
daemon.late_start();
break;
case MainRequest::BOOT_COMPLETE:
close(client);
if ((boot_state & FLAG_SAFE_MODE) == 0)
daemon.boot_complete();
break;
default:
__builtin_unreachable();
}
}

View File

@ -128,8 +128,20 @@ static void poll_ctrl_handler(pollfd *pfd) {
} }
} }
const MagiskD &MagiskD::get() {
return *reinterpret_cast<const MagiskD*>(&rust::get_magiskd());
}
const rust::MagiskD &MagiskD::as_rust() const {
return *reinterpret_cast<const rust::MagiskD*>(this);
}
void MagiskD::boot_stage_handler(int client, int code) const {
as_rust().boot_stage_handler(client, code);
}
void MagiskD::reboot() const { void MagiskD::reboot() const {
if (is_recovery()) if (as_rust().is_recovery())
exec_command_sync("/system/bin/reboot", "recovery"); exec_command_sync("/system/bin/reboot", "recovery");
else else
exec_command_sync("/system/bin/reboot"); exec_command_sync("/system/bin/reboot");
@ -137,34 +149,33 @@ void MagiskD::reboot() const {
static void handle_request_async(int client, int code, const sock_cred &cred) { static void handle_request_async(int client, int code, const sock_cred &cred) {
switch (code) { switch (code) {
case MainRequest::DENYLIST: case +RequestCode::DENYLIST:
denylist_handler(client, &cred); denylist_handler(client, &cred);
break; break;
case MainRequest::SUPERUSER: case +RequestCode::SUPERUSER:
su_daemon_handler(client, &cred); su_daemon_handler(client, &cred);
break; break;
case MainRequest::ZYGOTE_RESTART: case +RequestCode::ZYGOTE_RESTART:
LOGI("** zygote restarted\n"); LOGI("** zygote restarted\n");
pkg_xml_ino = 0; pkg_xml_ino = 0;
prune_su_access(); prune_su_access();
reset_zygisk(false); reset_zygisk(false);
close(client); close(client);
break; break;
case MainRequest::SQLITE_CMD: case +RequestCode::SQLITE_CMD:
exec_sql(client); exec_sql(client);
break; break;
case MainRequest::REMOVE_MODULES: { case +RequestCode::REMOVE_MODULES: {
int do_reboot = read_int(client); int do_reboot = read_int(client);
remove_modules(); remove_modules();
write_int(client, 0); write_int(client, 0);
close(client); close(client);
if (do_reboot) { if (do_reboot) {
MagiskD daemon; MagiskD::get().reboot();
daemon.reboot();
} }
break; break;
} }
case MainRequest::ZYGISK: case +RequestCode::ZYGISK:
zygisk_handler(client, &cred); zygisk_handler(client, &cred);
break; break;
default: default:
@ -174,20 +185,20 @@ static void handle_request_async(int client, int code, const sock_cred &cred) {
static void handle_request_sync(int client, int code) { static void handle_request_sync(int client, int code) {
switch (code) { switch (code) {
case MainRequest::CHECK_VERSION: case +RequestCode::CHECK_VERSION:
#if MAGISK_DEBUG #if MAGISK_DEBUG
write_string(client, MAGISK_VERSION ":MAGISK:D"); write_string(client, MAGISK_VERSION ":MAGISK:D");
#else #else
write_string(client, MAGISK_VERSION ":MAGISK:R"); write_string(client, MAGISK_VERSION ":MAGISK:R");
#endif #endif
break; break;
case MainRequest::CHECK_VERSION_CODE: case +RequestCode::CHECK_VERSION_CODE:
write_int(client, MAGISK_VER_CODE); write_int(client, MAGISK_VER_CODE);
break; break;
case MainRequest::START_DAEMON: case +RequestCode::START_DAEMON:
rust::get_magiskd().setup_logfile(); rust::get_magiskd().setup_logfile();
break; break;
case MainRequest::STOP_DAEMON: { case +RequestCode::STOP_DAEMON: {
// Unmount all overlays // Unmount all overlays
denylist_handler(-1, nullptr); denylist_handler(-1, nullptr);
@ -236,42 +247,42 @@ static void handle_request(pollfd *pfd) {
if (!is_root && !is_zygote && !is_client(cred.pid)) { if (!is_root && !is_zygote && !is_client(cred.pid)) {
// Unsupported client state // Unsupported client state
write_int(client, MainResponse::ACCESS_DENIED); write_int(client, +RespondCode::ACCESS_DENIED);
return; return;
} }
code = read_int(client); code = read_int(client);
if (code < 0 || code >= MainRequest::END || if (code < 0 || code >= +RequestCode::END ||
code == MainRequest::_SYNC_BARRIER_ || code == +RequestCode::_SYNC_BARRIER_ ||
code == MainRequest::_STAGE_BARRIER_) { code == +RequestCode::_STAGE_BARRIER_) {
// Unknown request code // Unknown request code
return; return;
} }
// Check client permissions // Check client permissions
switch (code) { switch (code) {
case MainRequest::POST_FS_DATA: case +RequestCode::POST_FS_DATA:
case MainRequest::LATE_START: case +RequestCode::LATE_START:
case MainRequest::BOOT_COMPLETE: case +RequestCode::BOOT_COMPLETE:
case MainRequest::ZYGOTE_RESTART: case +RequestCode::ZYGOTE_RESTART:
case MainRequest::SQLITE_CMD: case +RequestCode::SQLITE_CMD:
case MainRequest::DENYLIST: case +RequestCode::DENYLIST:
case MainRequest::STOP_DAEMON: case +RequestCode::STOP_DAEMON:
if (!is_root) { if (!is_root) {
write_int(client, MainResponse::ROOT_REQUIRED); write_int(client, +RespondCode::ROOT_REQUIRED);
return; return;
} }
break; break;
case MainRequest::REMOVE_MODULES: case +RequestCode::REMOVE_MODULES:
if (!is_root && cred.uid != AID_SHELL) { if (!is_root && cred.uid != AID_SHELL) {
write_int(client, MainResponse::ACCESS_DENIED); write_int(client, +RespondCode::ACCESS_DENIED);
return; return;
} }
break; break;
case MainRequest::ZYGISK: case +RequestCode::ZYGISK:
if (!is_zygote) { if (!is_zygote) {
// Invalid client context // Invalid client context
write_int(client, MainResponse::ACCESS_DENIED); write_int(client, +RespondCode::ACCESS_DENIED);
return; return;
} }
break; break;
@ -279,14 +290,16 @@ static void handle_request(pollfd *pfd) {
break; break;
} }
write_int(client, MainResponse::OK); write_int(client, +RespondCode::OK);
if (code < MainRequest::_SYNC_BARRIER_) { if (code < +RequestCode::_SYNC_BARRIER_) {
handle_request_sync(client, code); handle_request_sync(client, code);
} else if (code < MainRequest::_STAGE_BARRIER_) { } else if (code < +RequestCode::_STAGE_BARRIER_) {
exec_task([=, fd = client.release()] { handle_request_async(fd, code, cred); }); exec_task([=, fd = client.release()] { handle_request_async(fd, code, cred); });
} else { } else {
exec_task([=, fd = client.release()] { boot_stage_handler(fd, code); }); exec_task([=, fd = client.release()] {
MagiskD::get().boot_stage_handler(fd, code);
});
} }
} }
@ -460,20 +473,20 @@ int connect_daemon(int req, bool create) {
} }
write_int(fd, req); write_int(fd, req);
int res = read_int(fd); int res = read_int(fd);
if (res < MainResponse::ERROR || res >= MainResponse::END) if (res < +RespondCode::ERROR || res >= +RespondCode::END)
res = MainResponse::ERROR; res = +RespondCode::ERROR;
switch (res) { switch (res) {
case MainResponse::OK: case +RespondCode::OK:
break; break;
case MainResponse::ERROR: case +RespondCode::ERROR:
LOGE("Daemon error\n"); LOGE("Daemon error\n");
close(fd); close(fd);
return -1; return -1;
case MainResponse::ROOT_REQUIRED: case +RespondCode::ROOT_REQUIRED:
LOGE("Root is required for this operation\n"); LOGE("Root is required for this operation\n");
close(fd); close(fd);
return -1; return -1;
case MainResponse::ACCESS_DENIED: case +RespondCode::ACCESS_DENIED:
LOGE("Access denied\n"); LOGE("Access denied\n");
close(fd); close(fd);
return -1; return -1;

View File

@ -1,23 +1,51 @@
use std::fs::File; use std::fs::File;
use std::io;
use std::io::BufReader; use std::io::BufReader;
use std::sync::atomic::{AtomicU32, Ordering};
use std::sync::{Mutex, OnceLock}; use std::sync::{Mutex, OnceLock};
use std::{io, mem};
use base::libc::{O_CLOEXEC, O_RDONLY}; use base::libc::{O_CLOEXEC, O_RDONLY};
use base::{ use base::{
cstr, BufReadExt, Directory, FsPathBuf, ResultExt, Utf8CStr, Utf8CStrBuf, Utf8CStrBufArr, cstr, libc, open_fd, BufReadExt, Directory, FsPathBuf, ResultExt, Utf8CStr, Utf8CStrBuf,
Utf8CStrBufRef, WalkResult, Utf8CStrBufArr, Utf8CStrBufRef, WalkResult,
}; };
use crate::ffi::{CxxMagiskD, RequestCode};
use crate::logging::magisk_logging; use crate::logging::magisk_logging;
use crate::{get_prop, MAIN_CONFIG}; use crate::{get_prop, MAIN_CONFIG};
// Global magiskd singleton // Global magiskd singleton
pub static MAGISKD: OnceLock<MagiskD> = OnceLock::new(); pub static MAGISKD: OnceLock<MagiskD> = OnceLock::new();
#[repr(u32)]
enum BootState {
PostFsDataDone = (1 << 0),
LateStartDone = (1 << 1),
BootComplete = (1 << 2),
SafeMode = (1 << 3),
}
#[derive(Default)]
#[repr(transparent)]
struct BootStateFlags(AtomicU32);
impl BootStateFlags {
fn contains(&self, stage: BootState) -> bool {
let v = self.0.load(Ordering::Relaxed);
(v & stage as u32) != 0
}
fn set(&self, stage: BootState) {
let v = self.0.load(Ordering::Relaxed);
self.0.store(v | stage as u32, Ordering::Relaxed);
}
}
#[derive(Default)] #[derive(Default)]
pub struct MagiskD { pub struct MagiskD {
pub logd: Mutex<Option<File>>, pub logd: Mutex<Option<File>>,
boot_stage_lock: Mutex<()>,
boot_state_flags: BootStateFlags,
is_emulator: bool, is_emulator: bool,
is_recovery: bool, is_recovery: bool,
} }
@ -30,6 +58,50 @@ impl MagiskD {
pub fn is_recovery(&self) -> bool { pub fn is_recovery(&self) -> bool {
self.is_recovery self.is_recovery
} }
pub fn enable_safe_mode(&self) {
self.boot_state_flags.set(BootState::SafeMode)
}
pub fn boot_stage_handler(&self, client: i32, code: i32) {
// Make sure boot stage execution is always serialized
let _guard = self.boot_stage_lock.lock().unwrap();
let code = RequestCode { repr: code };
match code {
RequestCode::POST_FS_DATA => {
if check_data() && !self.boot_state_flags.contains(BootState::PostFsDataDone) {
self.as_cxx().post_fs_data();
self.boot_state_flags.set(BootState::PostFsDataDone);
}
unsafe { libc::close(client) };
}
RequestCode::LATE_START => {
unsafe { libc::close(client) };
if self.boot_state_flags.contains(BootState::PostFsDataDone)
&& !self.boot_state_flags.contains(BootState::SafeMode)
{
self.as_cxx().late_start();
self.boot_state_flags.set(BootState::LateStartDone);
}
}
RequestCode::BOOT_COMPLETE => {
unsafe { libc::close(client) };
if !self.boot_state_flags.contains(BootState::SafeMode) {
self.boot_state_flags.set(BootState::BootComplete);
self.as_cxx().boot_complete()
}
}
_ => {
unsafe { libc::close(client) };
}
}
}
#[inline(always)]
fn as_cxx(&self) -> &CxxMagiskD {
unsafe { mem::transmute(self) }
}
} }
mod cxx_extern { mod cxx_extern {
@ -69,15 +141,46 @@ pub fn daemon_entry() {
} }
let magiskd = MagiskD { let magiskd = MagiskD {
logd: Default::default(),
is_emulator, is_emulator,
is_recovery, is_recovery,
..Default::default()
}; };
magiskd.start_log_daemon(); magiskd.start_log_daemon();
MAGISKD.set(magiskd).ok(); MAGISKD.set(magiskd).ok();
magisk_logging(); magisk_logging();
} }
fn check_data() -> bool {
if let Ok(fd) = open_fd!(cstr!("/proc/mounts"), O_RDONLY | O_CLOEXEC) {
let file = File::from(fd);
let mut mnt = false;
BufReader::new(file).foreach_lines(|line| {
if line.contains(" /data ") && !line.contains("tmpfs") {
mnt = true;
return false;
}
true
});
if !mnt {
return false;
}
let crypto = get_prop(cstr!("ro.crypto.state"), false);
return if !crypto.is_empty() {
if crypto != "encrypted" {
// Unencrypted, we can directly access data
true
} else {
// Encrypted, check whether vold is started
!get_prop(cstr!("init.svc.vold"), false).is_empty()
}
} else {
// ro.crypto.state is not set, assume it's unencrypted
true
};
}
false
}
pub fn get_magiskd() -> &'static MagiskD { pub fn get_magiskd() -> &'static MagiskD {
unsafe { MAGISKD.get().unwrap_unchecked() } unsafe { MAGISKD.get().unwrap_unchecked() }
} }

View File

@ -92,7 +92,7 @@ int denylist_cli(int argc, char **argv) {
} }
// Send request // Send request
int fd = connect_daemon(MainRequest::DENYLIST); int fd = connect_daemon(+RequestCode::DENYLIST);
write_int(fd, req); write_int(fd, req);
if (req == DenyRequest::ADD || req == DenyRequest::REMOVE) { if (req == DenyRequest::ADD || req == DenyRequest::REMOVE) {
write_string(fd, argv[2]); write_string(fd, argv[2]);

View File

@ -8,7 +8,6 @@
#include <functional> #include <functional>
#include "socket.hpp" #include "socket.hpp"
#include "../core-rs.hpp"
#define AID_ROOT 0 #define AID_ROOT 0
#define AID_SHELL 2000 #define AID_SHELL 2000
@ -19,11 +18,17 @@
#define to_app_id(uid) (uid % AID_USER_OFFSET) #define to_app_id(uid) (uid % AID_USER_OFFSET)
#define to_user_id(uid) (uid / AID_USER_OFFSET) #define to_user_id(uid) (uid / AID_USER_OFFSET)
namespace rust {
struct MagiskD;
}
struct MagiskD { struct MagiskD {
// Make sure only references can exist
~MagiskD() = delete;
// Binding to Rust // Binding to Rust
void setup_logfile() const noexcept { impl.setup_logfile(); } static const MagiskD &get();
bool is_emulator() const noexcept { return impl.is_emulator(); } void boot_stage_handler(int client, int code) const;
bool is_recovery() const noexcept { return impl.is_recovery(); }
// C++ implementation // C++ implementation
void reboot() const; void reboot() const;
@ -32,46 +37,17 @@ struct MagiskD {
void boot_complete() const; void boot_complete() const;
private: private:
const rust::MagiskD &impl = rust::get_magiskd(); const rust::MagiskD &as_rust() const;
}; };
// Daemon command codes
namespace MainRequest {
enum : int {
START_DAEMON,
CHECK_VERSION,
CHECK_VERSION_CODE,
STOP_DAEMON,
_SYNC_BARRIER_,
SUPERUSER,
ZYGOTE_RESTART,
DENYLIST,
SQLITE_CMD,
REMOVE_MODULES,
ZYGISK,
_STAGE_BARRIER_,
POST_FS_DATA,
LATE_START,
BOOT_COMPLETE,
END,
};
}
// Return codes for daemon // Return codes for daemon
namespace MainResponse { enum class RespondCode : int {
enum : int {
ERROR = -1, ERROR = -1,
OK = 0, OK = 0,
ROOT_REQUIRED, ROOT_REQUIRED,
ACCESS_DENIED, ACCESS_DENIED,
END END
}; };
}
struct module_info { struct module_info {
std::string name; std::string name;
@ -139,3 +115,6 @@ int denylist_cli(int argc, char **argv);
void initialize_denylist(); void initialize_denylist();
bool is_deny_target(int uid, std::string_view process); bool is_deny_target(int uid, std::string_view process);
void revert_unmount(); void revert_unmount();
// Include last to prevent recursive include issues
#include "../core-rs.hpp"

View File

@ -18,6 +18,31 @@ mod resetprop;
#[cxx::bridge] #[cxx::bridge]
pub mod ffi { pub mod ffi {
#[repr(i32)]
enum RequestCode {
START_DAEMON,
CHECK_VERSION,
CHECK_VERSION_CODE,
STOP_DAEMON,
_SYNC_BARRIER_,
SUPERUSER,
ZYGOTE_RESTART,
DENYLIST,
SQLITE_CMD,
REMOVE_MODULES,
ZYGISK,
_STAGE_BARRIER_,
POST_FS_DATA,
LATE_START,
BOOT_COMPLETE,
END,
}
extern "C++" { extern "C++" {
include!("include/resetprop.hpp"); include!("include/resetprop.hpp");
@ -27,6 +52,16 @@ pub mod ffi {
unsafe fn prop_cb_exec(cb: Pin<&mut PropCb>, name: *const c_char, value: *const c_char); unsafe fn prop_cb_exec(cb: Pin<&mut PropCb>, name: *const c_char, value: *const c_char);
} }
unsafe extern "C++" {
include!("include/core.hpp");
#[cxx_name = "MagiskD"]
type CxxMagiskD;
fn post_fs_data(self: &CxxMagiskD);
fn late_start(self: &CxxMagiskD);
fn boot_complete(self: &CxxMagiskD);
}
extern "Rust" { extern "Rust" {
fn rust_test_entry(); fn rust_test_entry();
fn android_logging(); fn android_logging();
@ -48,11 +83,11 @@ pub mod ffi {
type MagiskD; type MagiskD;
fn get_magiskd() -> &'static MagiskD; fn get_magiskd() -> &'static MagiskD;
fn get_log_pipe(self: &MagiskD) -> i32;
fn close_log_pipe(self: &MagiskD);
fn setup_logfile(self: &MagiskD); fn setup_logfile(self: &MagiskD);
fn is_emulator(self: &MagiskD) -> bool; fn is_emulator(self: &MagiskD) -> bool;
fn is_recovery(self: &MagiskD) -> bool; fn is_recovery(self: &MagiskD) -> bool;
fn boot_stage_handler(self: &MagiskD, client: i32, code: i32);
fn enable_safe_mode(self: &MagiskD);
} }
} }

View File

@ -3,7 +3,7 @@ use std::ffi::{c_char, c_void};
use std::fmt::Write as FmtWrite; use std::fmt::Write as FmtWrite;
use std::fs::File; use std::fs::File;
use std::io::{IoSlice, Read, Write}; use std::io::{IoSlice, Read, Write};
use std::os::fd::{AsRawFd, FromRawFd, RawFd}; use std::os::fd::{FromRawFd, RawFd};
use std::ptr::null_mut; use std::ptr::null_mut;
use std::sync::atomic::{AtomicI32, Ordering}; use std::sync::atomic::{AtomicI32, Ordering};
use std::{fs, io}; use std::{fs, io};
@ -382,14 +382,6 @@ impl MagiskD {
} }
} }
pub fn get_log_pipe(&self) -> RawFd {
self.logd
.lock()
.unwrap()
.as_ref()
.map_or(-1, |s| s.as_raw_fd())
}
pub fn close_log_pipe(&self) { pub fn close_log_pipe(&self) {
*self.logd.lock().unwrap() = None; *self.logd.lock().unwrap() = None;
} }

View File

@ -58,12 +58,12 @@ int magisk_main(int argc, char *argv[]) {
#endif #endif
return 0; return 0;
} else if (argv[1] == "-v"sv) { } else if (argv[1] == "-v"sv) {
int fd = connect_daemon(MainRequest::CHECK_VERSION); int fd = connect_daemon(+RequestCode::CHECK_VERSION);
string v = read_string(fd); string v = read_string(fd);
printf("%s\n", v.data()); printf("%s\n", v.data());
return 0; return 0;
} else if (argv[1] == "-V"sv) { } else if (argv[1] == "-V"sv) {
int fd = connect_daemon(MainRequest::CHECK_VERSION_CODE); int fd = connect_daemon(+RequestCode::CHECK_VERSION_CODE);
printf("%d\n", read_int(fd)); printf("%d\n", read_int(fd));
return 0; return 0;
} else if (argv[1] == "--list"sv) { } else if (argv[1] == "--list"sv) {
@ -83,29 +83,29 @@ int magisk_main(int argc, char *argv[]) {
cp_afc(argv[2], argv[3]); cp_afc(argv[2], argv[3]);
return 0; return 0;
} else if (argv[1] == "--daemon"sv) { } else if (argv[1] == "--daemon"sv) {
close(connect_daemon(MainRequest::START_DAEMON, true)); close(connect_daemon(+RequestCode::START_DAEMON, true));
return 0; return 0;
} else if (argv[1] == "--stop"sv) { } else if (argv[1] == "--stop"sv) {
int fd = connect_daemon(MainRequest::STOP_DAEMON); int fd = connect_daemon(+RequestCode::STOP_DAEMON);
return read_int(fd); return read_int(fd);
} else if (argv[1] == "--post-fs-data"sv) { } else if (argv[1] == "--post-fs-data"sv) {
int fd = connect_daemon(MainRequest::POST_FS_DATA, true); int fd = connect_daemon(+RequestCode::POST_FS_DATA, true);
struct pollfd pfd = { fd, POLLIN, 0 }; struct pollfd pfd = { fd, POLLIN, 0 };
poll(&pfd, 1, 1000 * POST_FS_DATA_WAIT_TIME); poll(&pfd, 1, 1000 * POST_FS_DATA_WAIT_TIME);
return 0; return 0;
} else if (argv[1] == "--service"sv) { } else if (argv[1] == "--service"sv) {
close(connect_daemon(MainRequest::LATE_START, true)); close(connect_daemon(+RequestCode::LATE_START, true));
return 0; return 0;
} else if (argv[1] == "--boot-complete"sv) { } else if (argv[1] == "--boot-complete"sv) {
close(connect_daemon(MainRequest::BOOT_COMPLETE)); close(connect_daemon(+RequestCode::BOOT_COMPLETE));
return 0; return 0;
} else if (argv[1] == "--zygote-restart"sv) { } else if (argv[1] == "--zygote-restart"sv) {
close(connect_daemon(MainRequest::ZYGOTE_RESTART)); close(connect_daemon(+RequestCode::ZYGOTE_RESTART));
return 0; return 0;
} else if (argv[1] == "--denylist"sv) { } else if (argv[1] == "--denylist"sv) {
return denylist_cli(argc - 1, argv + 1); return denylist_cli(argc - 1, argv + 1);
} else if (argc >= 3 && argv[1] == "--sqlite"sv) { } else if (argc >= 3 && argv[1] == "--sqlite"sv) {
int fd = connect_daemon(MainRequest::SQLITE_CMD); int fd = connect_daemon(+RequestCode::SQLITE_CMD);
write_string(fd, argv[2]); write_string(fd, argv[2]);
string res; string res;
for (;;) { for (;;) {
@ -123,7 +123,7 @@ int magisk_main(int argc, char *argv[]) {
} else { } else {
usage(); usage();
} }
int fd = connect_daemon(MainRequest::REMOVE_MODULES); int fd = connect_daemon(+RequestCode::REMOVE_MODULES);
write_int(fd, do_reboot); write_int(fd, do_reboot);
return read_int(fd); return read_int(fd);
} else if (argv[1] == "--path"sv) { } else if (argv[1] == "--path"sv) {

View File

@ -189,7 +189,7 @@ int su_client_main(int argc, char *argv[]) {
int ptmx, fd; int ptmx, fd;
// Connect to client // Connect to client
fd = connect_daemon(MainRequest::SUPERUSER); fd = connect_daemon(+RequestCode::SUPERUSER);
// Send su_request // Send su_request
xwrite(fd, &su_req, sizeof(su_req_base)); xwrite(fd, &su_req, sizeof(su_req_base));

View File

@ -39,7 +39,7 @@ void hookJniNativeMethods(JNIEnv *env, const char *clz, JNINativeMethod *methods
int remote_get_info(int uid, const char *process, uint32_t *flags, std::vector<int> &fds); int remote_get_info(int uid, const char *process, uint32_t *flags, std::vector<int> &fds);
inline int zygisk_request(int req) { inline int zygisk_request(int req) {
int fd = connect_daemon(MainRequest::ZYGISK); int fd = connect_daemon(+RequestCode::ZYGISK);
if (fd < 0) return fd; if (fd < 0) return fd;
write_int(fd, req); write_int(fd, req);
return fd; return fd;