mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-03-28 17:12:21 +00:00
Introduce zygisk loader
Use a separate library for 1st stage
This commit is contained in:
parent
6bfe34e5a8
commit
9806b38d8e
51
build.py
51
build.py
@ -203,16 +203,6 @@ def clean_elf():
|
|||||||
execv(args)
|
execv(args)
|
||||||
|
|
||||||
|
|
||||||
def binary_dump(src, var_name):
|
|
||||||
out_str = f'constexpr unsigned char {var_name}[] = {{'
|
|
||||||
for i, c in enumerate(xz(src.read())):
|
|
||||||
if i % 16 == 0:
|
|
||||||
out_str += '\n'
|
|
||||||
out_str += f'0x{c:02X},'
|
|
||||||
out_str += '\n};\n'
|
|
||||||
return out_str
|
|
||||||
|
|
||||||
|
|
||||||
def run_ndk_build(flags):
|
def run_ndk_build(flags):
|
||||||
os.chdir('native')
|
os.chdir('native')
|
||||||
flags = 'NDK_PROJECT_PATH=. NDK_APPLICATION_MK=src/Application.mk ' + flags
|
flags = 'NDK_PROJECT_PATH=. NDK_APPLICATION_MK=src/Application.mk ' + flags
|
||||||
@ -221,7 +211,7 @@ def run_ndk_build(flags):
|
|||||||
error('Build binary failed!')
|
error('Build binary failed!')
|
||||||
os.chdir('..')
|
os.chdir('..')
|
||||||
for arch in archs:
|
for arch in archs:
|
||||||
for tgt in support_targets + ['libpreload.so']:
|
for tgt in support_targets + ['libinit-ld.so', 'libzygisk-ld.so']:
|
||||||
source = op.join('native', 'libs', arch, tgt)
|
source = op.join('native', 'libs', arch, tgt)
|
||||||
target = op.join('native', 'out', arch, tgt)
|
target = op.join('native', 'out', arch, tgt)
|
||||||
mv(source, target)
|
mv(source, target)
|
||||||
@ -306,6 +296,16 @@ def write_if_diff(file_name, text):
|
|||||||
f.write(text)
|
f.write(text)
|
||||||
|
|
||||||
|
|
||||||
|
def binary_dump(src, var_name, compressor=xz):
|
||||||
|
out_str = f'constexpr unsigned char {var_name}[] = {{'
|
||||||
|
for i, c in enumerate(compressor(src.read())):
|
||||||
|
if i % 16 == 0:
|
||||||
|
out_str += '\n'
|
||||||
|
out_str += f'0x{c:02X},'
|
||||||
|
out_str += '\n};\n'
|
||||||
|
return out_str
|
||||||
|
|
||||||
|
|
||||||
def dump_bin_header(args):
|
def dump_bin_header(args):
|
||||||
stub = op.join(config['outdir'], f'stub-{"release" if args.release else "debug"}.apk')
|
stub = op.join(config['outdir'], f'stub-{"release" if args.release else "debug"}.apk')
|
||||||
if not op.exists(stub):
|
if not op.exists(stub):
|
||||||
@ -315,10 +315,13 @@ def dump_bin_header(args):
|
|||||||
text = binary_dump(src, 'manager_xz')
|
text = binary_dump(src, 'manager_xz')
|
||||||
write_if_diff(op.join(native_gen_path, 'binaries.h'), text)
|
write_if_diff(op.join(native_gen_path, 'binaries.h'), text)
|
||||||
for arch in archs:
|
for arch in archs:
|
||||||
preload = op.join('native', 'out', arch, 'libpreload.so')
|
preload = op.join('native', 'out', arch, 'libinit-ld.so')
|
||||||
with open(preload, 'rb') as src:
|
with open(preload, 'rb') as src:
|
||||||
text = binary_dump(src, 'preload_xz')
|
text = binary_dump(src, 'init_ld_xz')
|
||||||
write_if_diff(op.join(native_gen_path, f'{arch}_binaries.h'), text)
|
preload = op.join('native', 'out', arch, 'libzygisk-ld.so')
|
||||||
|
with open(preload, 'rb') as src:
|
||||||
|
text += binary_dump(src, 'zygisk_ld', compressor=lambda x: x)
|
||||||
|
write_if_diff(op.join(native_gen_path, f'{arch}_binaries.h'), text)
|
||||||
|
|
||||||
|
|
||||||
def dump_flag_header():
|
def dump_flag_header():
|
||||||
@ -363,8 +366,8 @@ def build_binary(args):
|
|||||||
|
|
||||||
flag = ''
|
flag = ''
|
||||||
|
|
||||||
if 'magisk' in args.target:
|
if 'magisk' in args.target or 'magiskinit' in args.target:
|
||||||
flag += ' B_MAGISK=1'
|
flag += ' B_PRELOAD=1'
|
||||||
|
|
||||||
if 'magiskpolicy' in args.target:
|
if 'magiskpolicy' in args.target:
|
||||||
flag += ' B_POLICY=1'
|
flag += ' B_POLICY=1'
|
||||||
@ -383,13 +386,23 @@ def build_binary(args):
|
|||||||
|
|
||||||
if flag:
|
if flag:
|
||||||
run_ndk_build(flag)
|
run_ndk_build(flag)
|
||||||
clean_elf()
|
|
||||||
|
|
||||||
# magiskinit and busybox has to be built separately
|
# magiskinit and magisk embeds preload.so
|
||||||
|
|
||||||
|
flag = ''
|
||||||
|
|
||||||
|
if 'magisk' in args.target:
|
||||||
|
flag += ' B_MAGISK=1'
|
||||||
|
|
||||||
if 'magiskinit' in args.target:
|
if 'magiskinit' in args.target:
|
||||||
|
flag += ' B_INIT=1'
|
||||||
|
|
||||||
|
if flag:
|
||||||
dump_bin_header(args)
|
dump_bin_header(args)
|
||||||
run_ndk_build('B_INIT=1')
|
run_ndk_build(flag)
|
||||||
|
clean_elf()
|
||||||
|
|
||||||
|
# BusyBox is built with different libc
|
||||||
|
|
||||||
if 'busybox' in args.target:
|
if 'busybox' in args.target:
|
||||||
run_ndk_build('B_BB=1')
|
run_ndk_build('B_BB=1')
|
||||||
|
@ -47,6 +47,7 @@ LOCAL_SRC_FILES := \
|
|||||||
zygisk/deny/revert.cpp
|
zygisk/deny/revert.cpp
|
||||||
|
|
||||||
LOCAL_LDLIBS := -llog
|
LOCAL_LDLIBS := -llog
|
||||||
|
LOCAL_LDFLAGS := -Wl,--dynamic-list=src/exported_sym.txt
|
||||||
|
|
||||||
include $(BUILD_EXECUTABLE)
|
include $(BUILD_EXECUTABLE)
|
||||||
|
|
||||||
@ -55,10 +56,15 @@ endif
|
|||||||
ifdef B_PRELOAD
|
ifdef B_PRELOAD
|
||||||
|
|
||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
LOCAL_MODULE := preload
|
LOCAL_MODULE := init-ld
|
||||||
LOCAL_SRC_FILES := init/preload.c
|
LOCAL_SRC_FILES := init/preload.c
|
||||||
include $(BUILD_SHARED_LIBRARY)
|
include $(BUILD_SHARED_LIBRARY)
|
||||||
|
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
LOCAL_MODULE := zygisk-ld
|
||||||
|
LOCAL_SRC_FILES := zygisk/loader.c
|
||||||
|
include $(BUILD_SHARED_LIBRARY)
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifdef B_INIT
|
ifdef B_INIT
|
||||||
|
@ -28,5 +28,5 @@ LOCAL_MODULE := libcompat
|
|||||||
LOCAL_SRC_FILES := compat/compat.cpp
|
LOCAL_SRC_FILES := compat/compat.cpp
|
||||||
# Fix static variables' ctor/dtor when using LTO
|
# Fix static variables' ctor/dtor when using LTO
|
||||||
# See: https://github.com/android/ndk/issues/1461
|
# See: https://github.com/android/ndk/issues/1461
|
||||||
LOCAL_EXPORT_LDLIBS := -static -T src/lto_fix.lds
|
LOCAL_EXPORT_LDFLAGS := -static -T src/lto_fix.lds
|
||||||
include $(BUILD_STATIC_LIBRARY)
|
include $(BUILD_STATIC_LIBRARY)
|
||||||
|
13
native/src/base/include/embed.hpp
Normal file
13
native/src/base/include/embed.hpp
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#include <binaries.h>
|
||||||
|
|
||||||
|
#if defined(__arm__)
|
||||||
|
#include <armeabi-v7a_binaries.h>
|
||||||
|
#elif defined(__aarch64__)
|
||||||
|
#include <arm64-v8a_binaries.h>
|
||||||
|
#elif defined(__i386__)
|
||||||
|
#include <x86_binaries.h>
|
||||||
|
#elif defined(__x86_64__)
|
||||||
|
#include <x86_64_binaries.h>
|
||||||
|
#else
|
||||||
|
#error Unsupported ABI
|
||||||
|
#endif
|
@ -567,19 +567,13 @@ int app_process_64 = -1;
|
|||||||
if (access("/system/bin/app_process" #bit, F_OK) == 0) { \
|
if (access("/system/bin/app_process" #bit, F_OK) == 0) { \
|
||||||
app_process_##bit = xopen("/system/bin/app_process" #bit, O_RDONLY | O_CLOEXEC); \
|
app_process_##bit = xopen("/system/bin/app_process" #bit, O_RDONLY | O_CLOEXEC); \
|
||||||
string zbin = zygisk_bin + "/app_process" #bit; \
|
string zbin = zygisk_bin + "/app_process" #bit; \
|
||||||
string dbin = zygisk_bin + "/magisk" #bit; \
|
|
||||||
string mbin = MAGISKTMP + "/magisk" #bit; \
|
string mbin = MAGISKTMP + "/magisk" #bit; \
|
||||||
int src = xopen(mbin.data(), O_RDONLY | O_CLOEXEC); \
|
int src = xopen(mbin.data(), O_RDONLY | O_CLOEXEC); \
|
||||||
int out = xopen(zbin.data(), O_CREAT | O_WRONLY | O_CLOEXEC, 0); \
|
int out = xopen(zbin.data(), O_CREAT | O_WRONLY | O_CLOEXEC, 0); \
|
||||||
xsendfile(out, src, nullptr, INT_MAX); \
|
xsendfile(out, src, nullptr, INT_MAX); \
|
||||||
close(out); \
|
close(out); \
|
||||||
out = xopen(dbin.data(), O_CREAT | O_WRONLY | O_CLOEXEC, 0); \
|
|
||||||
lseek(src, 0, SEEK_SET); \
|
|
||||||
xsendfile(out, src, nullptr, INT_MAX); \
|
|
||||||
close(out); \
|
|
||||||
close(src); \
|
close(src); \
|
||||||
clone_attr("/system/bin/app_process" #bit, zbin.data()); \
|
clone_attr("/system/bin/app_process" #bit, zbin.data()); \
|
||||||
clone_attr("/system/bin/app_process" #bit, dbin.data()); \
|
|
||||||
bind_mount(zbin.data(), "/system/bin/app_process" #bit); \
|
bind_mount(zbin.data(), "/system/bin/app_process" #bit); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
3
native/src/exported_sym.txt
Normal file
3
native/src/exported_sym.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
zygisk_inject_entry;
|
||||||
|
};
|
@ -6,19 +6,7 @@
|
|||||||
#include <xz.h>
|
#include <xz.h>
|
||||||
|
|
||||||
#include <base.hpp>
|
#include <base.hpp>
|
||||||
#include <binaries.h>
|
#include <embed.hpp>
|
||||||
|
|
||||||
#if defined(__arm__)
|
|
||||||
#include <armeabi-v7a_binaries.h>
|
|
||||||
#elif defined(__aarch64__)
|
|
||||||
#include <arm64-v8a_binaries.h>
|
|
||||||
#elif defined(__i386__)
|
|
||||||
#include <x86_binaries.h>
|
|
||||||
#elif defined(__x86_64__)
|
|
||||||
#include <x86_64_binaries.h>
|
|
||||||
#else
|
|
||||||
#error Unsupported ABI
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "init.hpp"
|
#include "init.hpp"
|
||||||
|
|
||||||
@ -78,7 +66,7 @@ int dump_manager(const char *path, mode_t mode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int dump_preload(const char *path, mode_t mode) {
|
int dump_preload(const char *path, mode_t mode) {
|
||||||
return dump_bin(preload_xz, sizeof(preload_xz), path, mode);
|
return dump_bin(init_ld_xz, sizeof(init_ld_xz), path, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
class RecoveryInit : public BaseInit {
|
class RecoveryInit : public BaseInit {
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <base.hpp>
|
#include <base.hpp>
|
||||||
#include <daemon.hpp>
|
#include <daemon.hpp>
|
||||||
#include <magisk.hpp>
|
#include <magisk.hpp>
|
||||||
|
#include <selinux.hpp>
|
||||||
|
|
||||||
#include "zygisk.hpp"
|
#include "zygisk.hpp"
|
||||||
#include "module.hpp"
|
#include "module.hpp"
|
||||||
@ -51,30 +52,9 @@ static void *unload_first_stage(void *) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__LP64__)
|
extern "C" void zygisk_inject_entry(void *handle) {
|
||||||
// Use symlink to workaround linker bug on old broken Android
|
|
||||||
// https://issuetracker.google.com/issues/36914295
|
|
||||||
#define SECOND_STAGE_PATH "/system/bin/app_process"
|
|
||||||
#else
|
|
||||||
#define SECOND_STAGE_PATH "/system/bin/app_process32"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void second_stage_entry() {
|
|
||||||
zygisk_logging();
|
zygisk_logging();
|
||||||
ZLOGD("inject 2nd stage\n");
|
ZLOGD("load success\n");
|
||||||
|
|
||||||
MAGISKTMP = getenv(MAGISKTMP_ENV);
|
|
||||||
self_handle = dlopen(SECOND_STAGE_PATH, RTLD_NOLOAD);
|
|
||||||
dlclose(self_handle);
|
|
||||||
|
|
||||||
unsetenv(MAGISKTMP_ENV);
|
|
||||||
sanitize_environ();
|
|
||||||
hook_functions();
|
|
||||||
new_daemon_thread(&unload_first_stage, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void first_stage_entry() {
|
|
||||||
ZLOGD("inject 1st stage\n");
|
|
||||||
|
|
||||||
char *ld = getenv("LD_PRELOAD");
|
char *ld = getenv("LD_PRELOAD");
|
||||||
if (char *c = strrchr(ld, ':')) {
|
if (char *c = strrchr(ld, ':')) {
|
||||||
@ -84,31 +64,13 @@ static void first_stage_entry() {
|
|||||||
unsetenv("LD_PRELOAD");
|
unsetenv("LD_PRELOAD");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load second stage
|
MAGISKTMP = getenv(MAGISKTMP_ENV);
|
||||||
android_dlextinfo info {
|
self_handle = handle;
|
||||||
.flags = ANDROID_DLEXT_FORCE_LOAD
|
|
||||||
};
|
|
||||||
setenv(INJECT_ENV_2, "1", 1);
|
|
||||||
if (android_dlopen_ext(SECOND_STAGE_PATH, RTLD_LAZY, &info) == nullptr) {
|
|
||||||
// Android 5.x doesn't support ANDROID_DLEXT_FORCE_LOAD
|
|
||||||
ZLOGI("ANDROID_DLEXT_FORCE_LOAD is not supported, fallback to dlopen\n");
|
|
||||||
if (dlopen(SECOND_STAGE_PATH, RTLD_LAZY) == nullptr) {
|
|
||||||
ZLOGE("Cannot load the second stage\n");
|
|
||||||
unsetenv(INJECT_ENV_2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[[gnu::constructor]] [[maybe_unused]]
|
unsetenv(MAGISKTMP_ENV);
|
||||||
static void zygisk_init() {
|
sanitize_environ();
|
||||||
android_logging();
|
hook_functions();
|
||||||
if (getenv(INJECT_ENV_1)) {
|
new_daemon_thread(&unload_first_stage, nullptr);
|
||||||
unsetenv(INJECT_ENV_1);
|
|
||||||
first_stage_entry();
|
|
||||||
} else if (getenv(INJECT_ENV_2)) {
|
|
||||||
unsetenv(INJECT_ENV_2);
|
|
||||||
second_stage_entry();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The following code runs in zygote/app process
|
// The following code runs in zygote/app process
|
||||||
@ -239,7 +201,7 @@ static int zygote_start_counts[] = { 0, 0 };
|
|||||||
static void setup_files(int client, const sock_cred *cred) {
|
static void setup_files(int client, const sock_cred *cred) {
|
||||||
LOGD("zygisk: setup files for pid=[%d]\n", cred->pid);
|
LOGD("zygisk: setup files for pid=[%d]\n", cred->pid);
|
||||||
|
|
||||||
char buf[256];
|
char buf[4096];
|
||||||
if (!get_exe(cred->pid, buf, sizeof(buf))) {
|
if (!get_exe(cred->pid, buf, sizeof(buf))) {
|
||||||
write_int(client, 1);
|
write_int(client, 1);
|
||||||
return;
|
return;
|
||||||
@ -278,22 +240,31 @@ static void setup_files(int client, const sock_cred *cred) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hijack some binary in /system/bin to host 1st stage
|
// Ack
|
||||||
|
write_int(client, 0);
|
||||||
|
|
||||||
|
// Hijack some binary in /system/bin to host loader
|
||||||
const char *hbin;
|
const char *hbin;
|
||||||
string mbin;
|
string mbin;
|
||||||
int app_fd;
|
int app_fd;
|
||||||
if (is_64_bit) {
|
if (is_64_bit) {
|
||||||
hbin = HIJACK_BIN64;
|
hbin = HIJACK_BIN64;
|
||||||
mbin = MAGISKTMP + "/" ZYGISKBIN "/magisk64";
|
mbin = MAGISKTMP + "/" ZYGISKBIN "/loader64.so";
|
||||||
app_fd = app_process_64;
|
app_fd = app_process_64;
|
||||||
} else {
|
} else {
|
||||||
hbin = HIJACK_BIN32;
|
hbin = HIJACK_BIN32;
|
||||||
mbin = MAGISKTMP + "/" ZYGISKBIN "/magisk32";
|
mbin = MAGISKTMP + "/" ZYGISKBIN "/loader32.so";
|
||||||
app_fd = app_process_32;
|
app_fd = app_process_32;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Receive and bind mount loader
|
||||||
|
int ld_fd = xopen(mbin.data(), O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, 0755);
|
||||||
|
string ld_data = read_string(client);
|
||||||
|
xwrite(ld_fd, ld_data.data(), ld_data.size());
|
||||||
|
close(ld_fd);
|
||||||
|
setfilecon(mbin.data(), "u:object_r:" SEPOL_FILE_TYPE ":s0");
|
||||||
xmount(mbin.data(), hbin, nullptr, MS_BIND, nullptr);
|
xmount(mbin.data(), hbin, nullptr, MS_BIND, nullptr);
|
||||||
|
|
||||||
write_int(client, 0);
|
|
||||||
send_fd(client, app_fd);
|
send_fd(client, app_fd);
|
||||||
write_string(client, MAGISKTMP);
|
write_string(client, MAGISKTMP);
|
||||||
}
|
}
|
||||||
|
27
native/src/zygisk/loader.c
Normal file
27
native/src/zygisk/loader.c
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#include <dlfcn.h>
|
||||||
|
#include <android/dlext.h>
|
||||||
|
|
||||||
|
#if defined(__LP64__)
|
||||||
|
// Use symlink to workaround linker bug on old broken Android
|
||||||
|
// https://issuetracker.google.com/issues/36914295
|
||||||
|
#define SECOND_STAGE_PATH "/system/bin/app_process"
|
||||||
|
#else
|
||||||
|
#define SECOND_STAGE_PATH "/system/bin/app_process32"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
__attribute__((constructor))
|
||||||
|
static void zygisk_loader() {
|
||||||
|
android_dlextinfo info = {
|
||||||
|
.flags = ANDROID_DLEXT_FORCE_LOAD
|
||||||
|
};
|
||||||
|
// Android 5.x doesn't support ANDROID_DLEXT_FORCE_LOAD
|
||||||
|
void *handle =
|
||||||
|
android_dlopen_ext(SECOND_STAGE_PATH, RTLD_LAZY, &info) ?:
|
||||||
|
dlopen(SECOND_STAGE_PATH, RTLD_LAZY);
|
||||||
|
if (handle) {
|
||||||
|
void(*entry)(void*) = dlsym(handle, "zygisk_inject_entry");
|
||||||
|
if (entry) {
|
||||||
|
entry(handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,6 +7,7 @@
|
|||||||
#include <socket.hpp>
|
#include <socket.hpp>
|
||||||
#include <daemon.hpp>
|
#include <daemon.hpp>
|
||||||
#include <selinux.hpp>
|
#include <selinux.hpp>
|
||||||
|
#include <embed.hpp>
|
||||||
|
|
||||||
#include "zygisk.hpp"
|
#include "zygisk.hpp"
|
||||||
|
|
||||||
@ -73,6 +74,10 @@ int app_process_main(int argc, char *argv[]) {
|
|||||||
if (read_int(socket) != 0)
|
if (read_int(socket) != 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// Send over zygisk loader
|
||||||
|
write_int(socket, sizeof(zygisk_ld));
|
||||||
|
xwrite(socket, zygisk_ld, sizeof(zygisk_ld));
|
||||||
|
|
||||||
int app_proc_fd = recv_fd(socket);
|
int app_proc_fd = recv_fd(socket);
|
||||||
if (app_proc_fd < 0)
|
if (app_proc_fd < 0)
|
||||||
break;
|
break;
|
||||||
@ -86,7 +91,6 @@ int app_process_main(int argc, char *argv[]) {
|
|||||||
} else {
|
} else {
|
||||||
setenv("LD_PRELOAD", HIJACK_BIN, 1);
|
setenv("LD_PRELOAD", HIJACK_BIN, 1);
|
||||||
}
|
}
|
||||||
setenv(INJECT_ENV_1, "1", 1);
|
|
||||||
setenv(MAGISKTMP_ENV, tmp.data(), 1);
|
setenv(MAGISKTMP_ENV, tmp.data(), 1);
|
||||||
|
|
||||||
close(socket);
|
close(socket);
|
||||||
|
@ -5,8 +5,6 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <daemon.hpp>
|
#include <daemon.hpp>
|
||||||
|
|
||||||
#define INJECT_ENV_1 "MAGISK_INJ_1"
|
|
||||||
#define INJECT_ENV_2 "MAGISK_INJ_2"
|
|
||||||
#define MAGISKTMP_ENV "MAGISKTMP"
|
#define MAGISKTMP_ENV "MAGISKTMP"
|
||||||
|
|
||||||
#define HIJACK_BIN64 "/system/bin/appwidget"
|
#define HIJACK_BIN64 "/system/bin/appwidget"
|
||||||
@ -55,7 +53,6 @@ extern void *self_handle;
|
|||||||
|
|
||||||
void hook_functions();
|
void hook_functions();
|
||||||
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);
|
||||||
int remote_request_unmount();
|
|
||||||
|
|
||||||
inline int zygisk_request(int req) {
|
inline int zygisk_request(int req) {
|
||||||
int fd = connect_daemon(MainRequest::ZYGISK);
|
int fd = connect_daemon(MainRequest::ZYGISK);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user