mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-02-19 19:48:30 +00:00
Use magiskd to setup files
This commit is contained in:
parent
003fea52b1
commit
9b3efffba9
@ -68,6 +68,9 @@ static void handle_request_async(int client, int code, ucred cred) {
|
||||
close(client);
|
||||
reboot();
|
||||
break;
|
||||
case ZYGISK_REQUEST:
|
||||
zygisk_handler(client, &cred);
|
||||
break;
|
||||
default:
|
||||
close(client);
|
||||
break;
|
||||
@ -116,6 +119,7 @@ static void handle_request(int client) {
|
||||
case BOOT_COMPLETE:
|
||||
case SQLITE_CMD:
|
||||
case GET_PATH:
|
||||
case MAGISKHIDE:
|
||||
if (!is_root) {
|
||||
write_int(client, ROOT_REQUIRED);
|
||||
goto done;
|
||||
@ -127,9 +131,9 @@ static void handle_request(int client) {
|
||||
goto done;
|
||||
}
|
||||
break;
|
||||
case MAGISKHIDE: // accept hide request from zygote
|
||||
if (!is_root && !is_zygote) {
|
||||
write_int(client, ROOT_REQUIRED);
|
||||
case ZYGISK_REQUEST:
|
||||
if (!is_zygote) {
|
||||
write_int(client, DAEMON_ERROR);
|
||||
goto done;
|
||||
}
|
||||
break;
|
||||
@ -260,7 +264,7 @@ int connect_daemon(bool create) {
|
||||
if (connect(fd, (sockaddr*) &sun, len)) {
|
||||
if (!create || getuid() != UID_ROOT) {
|
||||
LOGE("No daemon is currently running!\n");
|
||||
exit(1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (fork_dont_care() == 0) {
|
||||
|
@ -158,6 +158,16 @@ void magisk_logging() {
|
||||
log_cb.ex = nop_ex;
|
||||
}
|
||||
|
||||
#define alog(prio) [](auto fmt, auto ap){ \
|
||||
return __android_log_vprint(ANDROID_LOG_##prio, "Magisk", fmt, ap); }
|
||||
void android_logging() {
|
||||
log_cb.d = alog(DEBUG);
|
||||
log_cb.i = alog(INFO);
|
||||
log_cb.w = alog(WARN);
|
||||
log_cb.e = alog(ERROR);
|
||||
log_cb.ex = nop_ex;
|
||||
}
|
||||
|
||||
void start_log_daemon() {
|
||||
int fds[2];
|
||||
if (pipe2(fds, O_CLOEXEC) == 0) {
|
||||
|
@ -25,6 +25,7 @@ enum : int {
|
||||
MAGISKHIDE,
|
||||
SQLITE_CMD,
|
||||
REMOVE_MODULES,
|
||||
ZYGISK_REQUEST,
|
||||
DAEMON_CODE_END,
|
||||
};
|
||||
|
||||
@ -47,12 +48,15 @@ enum : int {
|
||||
|
||||
int connect_daemon(bool create = false);
|
||||
|
||||
void android_logging();
|
||||
|
||||
// Daemon handlers
|
||||
void post_fs_data(int client);
|
||||
void late_start(int client);
|
||||
void boot_complete(int client);
|
||||
void magiskhide_handler(int client, ucred *cred);
|
||||
void su_daemon_handler(int client, ucred *credential);
|
||||
void zygisk_handler(int client, ucred *cred);
|
||||
|
||||
// MagiskHide
|
||||
void check_enable_hide();
|
||||
|
@ -3,9 +3,10 @@
|
||||
#include <sys/mount.h>
|
||||
#include <sys/sendfile.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <android/log.h>
|
||||
|
||||
#include <utils.hpp>
|
||||
#include <daemon.hpp>
|
||||
#include <magisk.hpp>
|
||||
|
||||
#include "inject.hpp"
|
||||
|
||||
@ -14,16 +15,6 @@ using namespace std;
|
||||
static void *self_handle = nullptr;
|
||||
static atomic<int> active_threads = -1;
|
||||
|
||||
#define alog(prio) [](auto fmt, auto ap){ \
|
||||
return __android_log_vprint(ANDROID_LOG_##prio, "Magisk", fmt, ap); }
|
||||
static void inject_logging() {
|
||||
log_cb.d = alog(DEBUG);
|
||||
log_cb.i = alog(INFO);
|
||||
log_cb.w = alog(WARN);
|
||||
log_cb.e = alog(ERROR);
|
||||
log_cb.ex = nop_ex;
|
||||
}
|
||||
|
||||
void self_unload() {
|
||||
LOGD("hook: Request to self unload\n");
|
||||
// If unhook failed, do not unload or else it will cause SIGSEGV
|
||||
@ -33,7 +24,7 @@ void self_unload() {
|
||||
active_threads--;
|
||||
}
|
||||
|
||||
static void *unload_first_stage(void *) {
|
||||
static void *unload_first_stage(void *v) {
|
||||
// Setup 1ms
|
||||
timespec ts = { .tv_sec = 0, .tv_nsec = 1000000L };
|
||||
|
||||
@ -43,7 +34,8 @@ static void *unload_first_stage(void *) {
|
||||
// Wait another 1ms to make sure all threads left our code
|
||||
nanosleep(&ts, nullptr);
|
||||
|
||||
unmap_all(INJECT_LIB_1);
|
||||
char *path = static_cast<char *>(v);
|
||||
unmap_all(path);
|
||||
active_threads--;
|
||||
return nullptr;
|
||||
}
|
||||
@ -87,66 +79,108 @@ static void inject_cleanup_wait() {
|
||||
|
||||
__attribute__((constructor))
|
||||
static void inject_init() {
|
||||
if (getenv(INJECT_ENV_2)) {
|
||||
inject_logging();
|
||||
if (char *env = getenv(INJECT_ENV_2)) {
|
||||
android_logging();
|
||||
LOGD("zygote: inject 2nd stage\n");
|
||||
active_threads = 1;
|
||||
unsetenv(INJECT_ENV_2);
|
||||
|
||||
// Get our own handle
|
||||
self_handle = dlopen(INJECT_LIB_2, RTLD_LAZY);
|
||||
self_handle = dlopen(env, RTLD_LAZY);
|
||||
dlclose(self_handle);
|
||||
unlink(INJECT_LIB_2);
|
||||
|
||||
hook_functions();
|
||||
|
||||
// Update path to 1st stage lib
|
||||
*(strrchr(env, '.') - 1) = '1';
|
||||
|
||||
// Some cleanup
|
||||
sanitize_environ();
|
||||
active_threads++;
|
||||
new_daemon_thread(&unload_first_stage);
|
||||
} else if (char *env = getenv(INJECT_ENV_1)) {
|
||||
inject_logging();
|
||||
new_daemon_thread(&unload_first_stage, env);
|
||||
} else if (getenv(INJECT_ENV_1)) {
|
||||
android_logging();
|
||||
LOGD("zygote: inject 1st stage\n");
|
||||
|
||||
if (env[0] == '1')
|
||||
char *ld = getenv("LD_PRELOAD");
|
||||
char *path;
|
||||
if (char *c = strrchr(ld, ':')) {
|
||||
*c = '\0';
|
||||
setenv("LD_PRELOAD", ld, 1); // Restore original LD_PRELOAD
|
||||
path = c + 1;
|
||||
} else {
|
||||
unsetenv("LD_PRELOAD");
|
||||
else
|
||||
setenv("LD_PRELOAD", env, 1); // Restore original LD_PRELOAD
|
||||
path = ld;
|
||||
}
|
||||
|
||||
// Update path to 2nd stage lib
|
||||
*(strrchr(path, '.') - 1) = '2';
|
||||
|
||||
// Setup second stage
|
||||
setenv(INJECT_ENV_2, "1", 1);
|
||||
cp_afc(INJECT_LIB_1, INJECT_LIB_2);
|
||||
dlopen(INJECT_LIB_2, RTLD_LAZY);
|
||||
setenv(INJECT_ENV_2, path, 1);
|
||||
dlopen(path, RTLD_LAZY);
|
||||
|
||||
unlink(INJECT_LIB_1);
|
||||
unsetenv(INJECT_ENV_1);
|
||||
}
|
||||
}
|
||||
|
||||
int app_process_main(int argc, char *argv[]) {
|
||||
inject_logging();
|
||||
char buf[4096];
|
||||
if (realpath("/proc/self/exe", buf) == nullptr)
|
||||
return 1;
|
||||
android_logging();
|
||||
|
||||
int in = xopen(buf, O_RDONLY);
|
||||
int out = xopen(INJECT_LIB_1, O_WRONLY | O_CREAT, 0644);
|
||||
sendfile(out, in, nullptr, INT_MAX);
|
||||
close(in);
|
||||
close(out);
|
||||
if (int fd = connect_daemon(); fd >= 0) {
|
||||
write_int(fd, ZYGISK_REQUEST);
|
||||
write_int(fd, ZYGISK_SETUP);
|
||||
|
||||
if (char *ld = getenv("LD_PRELOAD")) {
|
||||
char env[128];
|
||||
sprintf(env, "%s:" INJECT_LIB_1, ld);
|
||||
setenv("LD_PRELOAD", env, 1);
|
||||
setenv(INJECT_ENV_1, ld, 1); // Backup original LD_PRELOAD
|
||||
} else {
|
||||
setenv("LD_PRELOAD", INJECT_LIB_1, 1);
|
||||
setenv(INJECT_ENV_1, "1", 1);
|
||||
if (read_int(fd) == 0) {
|
||||
string path = read_string(fd);
|
||||
string lib = path + ".1.so";
|
||||
if (char *ld = getenv("LD_PRELOAD")) {
|
||||
char env[256];
|
||||
sprintf(env, "%s:%s", ld, lib.data());
|
||||
setenv("LD_PRELOAD", env, 1);
|
||||
} else {
|
||||
setenv("LD_PRELOAD", lib.data(), 1);
|
||||
}
|
||||
setenv(INJECT_ENV_1, "1", 1);
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
|
||||
// Execute real app_process
|
||||
xumount2(buf, MNT_DETACH);
|
||||
char buf[256];
|
||||
xreadlink("/proc/self/exe", buf, sizeof(buf));
|
||||
xumount2("/proc/self/exe", MNT_DETACH);
|
||||
execve(buf, argv, environ);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// The following code runs in magiskd
|
||||
|
||||
static void setup_files(int client, ucred *cred) {
|
||||
LOGD("zygisk: setup files\n");
|
||||
|
||||
char buf[PATH_MAX];
|
||||
sprintf(buf, "/proc/%d/exe", cred->pid);
|
||||
if (realpath(buf, buf) == nullptr) {
|
||||
write_int(client, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
write_int(client, 0);
|
||||
|
||||
string path = MAGISKTMP + "/zygisk." + basename(buf);
|
||||
cp_afc(buf, (path + ".1.so").data());
|
||||
cp_afc(buf, (path + ".2.so").data());
|
||||
|
||||
write_string(client, path);
|
||||
}
|
||||
|
||||
void zygisk_handler(int client, ucred *cred) {
|
||||
int code = read_int(client);
|
||||
switch (code) {
|
||||
case ZYGISK_SETUP:
|
||||
setup_files(client, cred);
|
||||
break;
|
||||
}
|
||||
close(client);
|
||||
}
|
||||
|
@ -3,11 +3,13 @@
|
||||
#include <stdint.h>
|
||||
#include <jni.h>
|
||||
|
||||
#define INJECT_LIB_1 "/dev/tmp/magisk.1.so"
|
||||
#define INJECT_LIB_2 "/dev/tmp/magisk.2.so"
|
||||
#define INJECT_ENV_1 "MAGISK_INJ_1"
|
||||
#define INJECT_ENV_2 "MAGISK_INJ_2"
|
||||
|
||||
enum : int {
|
||||
ZYGISK_SETUP,
|
||||
};
|
||||
|
||||
// Unmap all pages matching the name
|
||||
void unmap_all(const char *name);
|
||||
|
||||
|
@ -23,7 +23,7 @@ abort() {
|
||||
|
||||
mount_sbin() {
|
||||
mount -t tmpfs -o 'mode=0755' tmpfs /sbin
|
||||
$SELINUX && chcon u:object_r:rootfs:s0 /sbin
|
||||
chcon u:object_r:rootfs:s0 /sbin
|
||||
}
|
||||
|
||||
if [ ! -f /system/build.prop ]; then
|
||||
@ -56,14 +56,14 @@ fi
|
||||
pgrep magiskd >/dev/null && pkill -9 magiskd
|
||||
[ -f /sbin/magisk ] && umount -l /sbin
|
||||
[ -f /system/bin/magisk ] && umount -l /system/bin
|
||||
if [ -d /dev/magisk ]; then
|
||||
umount -l /dev/magisk 2>/dev/null
|
||||
rm -rf /dev/magisk
|
||||
fi
|
||||
|
||||
# SELinux stuffs
|
||||
SELINUX=false
|
||||
[ -e /sys/fs/selinux ] && SELINUX=true
|
||||
if $SELINUX; then
|
||||
ln -sf ./magiskinit magiskpolicy
|
||||
./magiskpolicy --live --magisk
|
||||
fi
|
||||
ln -sf ./magiskinit magiskpolicy
|
||||
./magiskpolicy --live --magisk
|
||||
|
||||
BINDIR=/sbin
|
||||
|
||||
@ -99,12 +99,14 @@ elif [ -e /sbin ]; then
|
||||
done
|
||||
else
|
||||
# Android Q+ without sbin, use overlayfs
|
||||
BINDIR=/system/bin
|
||||
rm -rf /dev/magisk
|
||||
mkdir -p /dev/magisk/upper
|
||||
BINDIR=/dev/magisk/upper
|
||||
mkdir /dev/magisk
|
||||
mount -t tmpfs -o 'mode=0755' tmpfs /dev/magisk
|
||||
chcon u:object_r:system_file:s0 /dev/magisk
|
||||
mkdir /dev/magisk/upper
|
||||
mkdir /dev/magisk/work
|
||||
./magisk --clone-attr /system/bin /dev/magisk/upper
|
||||
mount -t overlay overlay -olowerdir=/system/bin,upperdir=/dev/magisk/upper,workdir=/dev/magisk/work /system/bin
|
||||
mount -t overlay overlay -o lowerdir=/system/bin,upperdir=/dev/magisk/upper,workdir=/dev/magisk/work /system/bin
|
||||
fi
|
||||
|
||||
# Magisk stuffs
|
||||
|
Loading…
x
Reference in New Issue
Block a user