From 6f9c3c4ff30c37e0344fb13b36adb66d84447906 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Thu, 19 Aug 2021 01:54:12 -0700 Subject: [PATCH] Refactor hook.cpp --- native/jni/utils/misc.hpp | 4 +- native/jni/zygisk/entry.cpp | 8 +- native/jni/zygisk/gen_jni_hooks.py | 14 +- native/jni/zygisk/hook.cpp | 207 ++++++++++++++++------------- native/jni/zygisk/jni_hooks.hpp | 154 ++++++++++++--------- 5 files changed, 219 insertions(+), 168 deletions(-) diff --git a/native/jni/utils/misc.hpp b/native/jni/utils/misc.hpp index da78bbe06..3604d85fd 100644 --- a/native/jni/utils/misc.hpp +++ b/native/jni/utils/misc.hpp @@ -33,10 +33,10 @@ template class run_finally { DISALLOW_COPY_AND_MOVE(run_finally) public: - explicit run_finally(const Func &fn) : fn(fn) {} + explicit run_finally(Func &&fn) : fn(std::move(fn)) {} ~run_finally() { fn(); } private: - const Func &fn; + Func fn; }; template diff --git a/native/jni/zygisk/entry.cpp b/native/jni/zygisk/entry.cpp index db72f8a59..16d1a7d03 100644 --- a/native/jni/zygisk/entry.cpp +++ b/native/jni/zygisk/entry.cpp @@ -16,8 +16,8 @@ static void *self_handle = nullptr; static atomic active_threads = -1; void self_unload() { - LOGD("hook: Request to self unload\n"); - // If unhook failed, do not unload or else it will cause SIGSEGV + LOGD("zygisk: Request to self unload\n"); + // If deny failed, do not unload or else it will cause SIGSEGV if (!unhook_functions()) return; new_daemon_thread(reinterpret_cast(&dlclose), self_handle); @@ -81,7 +81,7 @@ __attribute__((constructor)) static void inject_init() { if (char *env = getenv(INJECT_ENV_2)) { android_logging(); - LOGD("zygote: inject 2nd stage\n"); + LOGD("zygisk: inject 2nd stage\n"); active_threads = 1; unsetenv(INJECT_ENV_2); @@ -100,7 +100,7 @@ static void inject_init() { new_daemon_thread(&unload_first_stage, env); } else if (getenv(INJECT_ENV_1)) { android_logging(); - LOGD("zygote: inject 1st stage\n"); + LOGD("zygisk: inject 1st stage\n"); char *ld = getenv("LD_PRELOAD"); char *path; diff --git a/native/jni/zygisk/gen_jni_hooks.py b/native/jni/zygisk/gen_jni_hooks.py index 637a174ce..c68d80860 100755 --- a/native/jni/zygisk/gen_jni_hooks.py +++ b/native/jni/zygisk/gen_jni_hooks.py @@ -128,7 +128,7 @@ spec_r = Method('r', [uid, gid, gids, runtime_flags, rlimits, mount_external, se spec_samsung_q = Method('samsung_q', [uid, gid, gids, runtime_flags, rlimits, mount_external, se_info, i1, i2, nice_name, is_child_zygote, instruction_set, app_data_dir]) -server_m = Method('m', [uid, gid, gids, runtime_flags, rlimits, +server_l = Method('l', [uid, gid, gids, runtime_flags, rlimits, permitted_capabilities, effective_capabilities]) server_samsung_q = Method('samsung_q', [uid, gid, gids, runtime_flags, i1, i2, rlimits, @@ -151,7 +151,6 @@ def gen_definitions(methods, base_name): for m in methods: func_name = f'{base_name}_{m.name}' decl += ind(0) + f'{cpp_ret} {func_name}(JNIEnv *env, jclass clazz, {m.cpp()}) {{' - decl += ind(1) + 'HookContext ctx{};' if base_name == 'nativeForkSystemServer': decl += ind(1) + 'ForkSystemServerArgs args(uid, gid, gids, runtime_flags, permitted_capabilities, effective_capabilities);' else: @@ -159,12 +158,15 @@ def gen_definitions(methods, base_name): for a in m.args: if a.set_arg: decl += ind(1) + f'args.{a.name} = &{a.name};' + decl += ind(1) + 'HookContext ctx;' + decl += ind(1) + 'ctx.env = env;' + decl += ind(1) + 'ctx.clazz = clazz;' decl += ind(1) + 'ctx.raw_args = &args;' - decl += ind(1) + f'{base_name}_pre(&ctx, env, clazz);' - decl += ind(1) + f'reinterpret_cast({base_name}_orig)(' + decl += ind(1) + f'ctx.{base_name}_pre();' + decl += ind(1) + f'reinterpret_cast(HookContext::{base_name}_orig)(' decl += ind(2) + f'env, clazz, {m.name_list()}' decl += ind(1) + ');' - decl += ind(1) + f'{base_name}_post(&ctx, env, clazz);' + decl += ind(1) + f'ctx.{base_name}_post();' decl += ret_stat decl += ind(0) + '}' @@ -189,7 +191,7 @@ def gen_spec(): return gen_definitions(methods, 'nativeSpecializeAppProcess') def gen_server(): - methods = [server_m, server_samsung_q] + methods = [server_l, server_samsung_q] return gen_definitions(methods, 'nativeForkSystemServer') with open('jni_hooks.hpp', 'w') as f: diff --git a/native/jni/zygisk/hook.cpp b/native/jni/zygisk/hook.cpp index 1c9f6657b..fff415f7b 100644 --- a/native/jni/zygisk/hook.cpp +++ b/native/jni/zygisk/hook.cpp @@ -1,5 +1,7 @@ #include #include +#include + #include #include #include @@ -15,50 +17,68 @@ using xstring = jni_hook::string; namespace { +#define DCL_JNI_FUNC(name) \ +static void *name##_orig; \ +void name##_pre(); \ +void name##_post(); + +#define DEF_STATIC(name) \ +void *HookContext::name##_orig = nullptr; + +enum { + DENY_FLAG, + APP_FORK, + FLAG_MAX +}; + struct HookContext { - int pid; - bool do_hide; + JNIEnv *env; + jclass clazz; union { SpecializeAppProcessArgs *args; ForkSystemServerArgs *server_args; void *raw_args; }; + const char *process; + int pid; + bitset flags; + + HookContext() : process(nullptr), pid(0) {} + + // JNI method declarations + DCL_JNI_FUNC(nativeForkAndSpecialize) + DCL_JNI_FUNC(nativeSpecializeAppProcess) + DCL_JNI_FUNC(nativeForkSystemServer) }; +DEF_STATIC(nativeForkAndSpecialize) +DEF_STATIC(nativeSpecializeAppProcess) +DEF_STATIC(nativeForkSystemServer) + +#undef DCL_JNI_FUNC +#undef DEF_STATIC // Global variables vector> *xhook_list; vector *jni_hook_list; hash_map>> *jni_method_map; -HookContext *current_ctx; -JavaVM *g_jvm; +// Current context +HookContext *g_ctx; const JNINativeInterface *old_functions; JNINativeInterface *new_functions; -#define DCL_JNI_FUNC(name) \ -void *name##_orig; \ -void name##_pre(HookContext *ctx, JNIEnv *env, jclass clazz); \ -void name##_post(HookContext *ctx, JNIEnv *env, jclass clazz); - -// JNI method declarations -DCL_JNI_FUNC(nativeForkAndSpecialize) -DCL_JNI_FUNC(nativeSpecializeAppProcess) -DCL_JNI_FUNC(nativeForkSystemServer) - -#undef DCL_JNI_FUNC - // JNI method definitions -// Includes all method signatures of all supported Android versions +// Includes method signatures of all supported Android versions #include "jni_hooks.hpp" #define HOOK_JNI(method) \ if (methods[i].name == #method##sv) { \ jni_hook_list->push_back(methods[i]); \ - method##_orig = methods[i].fnPtr; \ + HookContext::method##_orig = methods[i].fnPtr; \ for (int j = 0; j < method##_methods_num; ++j) { \ if (strcmp(methods[i].signature, method##_methods[j].signature) == 0) { \ newMethods[i] = method##_methods[j]; \ - LOGI("hook: replaced #" #method "\n"); \ + LOGI("zygisk: replaced #" #method "\n"); \ ++hooked; \ break; \ } \ @@ -66,13 +86,8 @@ if (methods[i].name == #method##sv) { \ continue; \ } -unique_ptr hookAndSaveJNIMethods( - JNIEnv *env, const char *className, const JNINativeMethod *methods, int numMethods) { - if (g_jvm == nullptr) { - // Save for later unhooking - env->GetJavaVM(&g_jvm); - } - +unique_ptrhookAndSaveJNIMethods( + const char *className, const JNINativeMethod *methods, int numMethods) { unique_ptr newMethods; int hooked = numeric_limits::max(); if (className == "com/android/internal/os/Zygote"sv) { @@ -85,9 +100,9 @@ unique_ptr hookAndSaveJNIMethods( for (int i = 0; i < numMethods; ++i) { class_map[methods[i].name][methods[i].signature] = methods[i].fnPtr; if (hooked < 3) { - HOOK_JNI(nativeForkAndSpecialize); - HOOK_JNI(nativeSpecializeAppProcess); - HOOK_JNI(nativeForkSystemServer); + HOOK_JNI(nativeForkAndSpecialize) + HOOK_JNI(nativeSpecializeAppProcess) + HOOK_JNI(nativeForkSystemServer) } } return newMethods; @@ -114,9 +129,9 @@ string get_class_name(JNIEnv *env, jclass clazz) { // ----------------------------------------------------------------- -// TODOs -int remote_check_hide(int uid, const char *process) { return 0; } -void remote_request_hide() {} +// TODO +int remote_check_denylist(int uid, const char *process) { return 0; } +void remote_request_unmount() {} // ----------------------------------------------------------------- @@ -127,29 +142,29 @@ ret new_##func(__VA_ARGS__) jint jniRegisterNatives( JNIEnv *env, jclass clazz, const JNINativeMethod *methods, jint numMethods) { auto className = get_class_name(env, clazz); - LOGD("hook: JNIEnv->RegisterNatives %s\n", className.data()); - auto newMethods = hookAndSaveJNIMethods(env, className.data(), methods, numMethods); + LOGD("zygisk: JNIEnv->RegisterNatives [%s]\n", className.data()); + auto newMethods = hookAndSaveJNIMethods(className.data(), methods, numMethods); return old_functions->RegisterNatives(env, clazz, newMethods.get() ?: methods, numMethods); } DCL_HOOK_FUNC(int, jniRegisterNativeMethods, JNIEnv *env, const char *className, const JNINativeMethod *methods, int numMethods) { - LOGD("hook: jniRegisterNativeMethods %s\n", className); - auto newMethods = hookAndSaveJNIMethods(env, className, methods, numMethods); + LOGD("zygisk: jniRegisterNativeMethods [%s]\n", className); + auto newMethods = hookAndSaveJNIMethods(className, methods, numMethods); return old_jniRegisterNativeMethods(env, className, newMethods.get() ?: methods, numMethods); } DCL_HOOK_FUNC(int, fork) { - return current_ctx ? current_ctx->pid : old_fork(); + return g_ctx ? g_ctx->pid : old_fork(); } DCL_HOOK_FUNC(int, selinux_android_setcontext, uid_t uid, int isSystemServer, const char *seinfo, const char *pkgname) { - if (current_ctx && current_ctx->do_hide) { - // Ask magiskd to hide ourselves before switching context - // because magiskd socket is not accessible on Android 8.0+ - remote_request_hide(); - LOGD("hook: process successfully hidden\n"); + if (g_ctx && g_ctx->flags[DENY_FLAG]) { + // Ask magiskd to cleanup the mount namespace before switching context + // This is the latest point where we can still connect to the magiskd main socket + remote_request_unmount(); + LOGD("zygisk: process successfully hidden\n"); } return old_selinux_android_setcontext(uid, isSystemServer, seinfo, pkgname); } @@ -161,7 +176,7 @@ void **gAppRuntimeVTable; // This method is a trampoline for hooking JNIEnv->RegisterNatives void onVmCreated(void *self, JNIEnv* env) { - LOGD("hook: AppRuntime::onVmCreated\n"); + LOGD("zygisk: AppRuntime::onVmCreated\n"); // Restore virtual table auto new_table = *reinterpret_cast(self); @@ -193,7 +208,7 @@ DCL_HOOK_FUNC(void, setArgv0, void *self, const char *argv0, bool setProcName) { return; } - LOGD("hook: AndroidRuntime::setArgv0\n"); + LOGD("zygisk: AndroidRuntime::setArgv0\n"); // We don't know which entry is onVmCreated, so overwrite every one // We also don't know the size of the vtable, but 8 is more than enough @@ -219,26 +234,33 @@ DCL_HOOK_FUNC(void, setArgv0, void *self, const char *argv0, bool setProcName) { // ----------------------------------------------------------------- -void nativeSpecializeAppProcess_pre(HookContext *ctx, JNIEnv *env, jclass clazz) { - current_ctx = ctx; - const char *process = env->GetStringUTFChars(ctx->args->nice_name, nullptr); - LOGD("hook: %s %s\n", __FUNCTION__, process); - - if (ctx->args->mount_external != 0 /* TODO: Handle MOUNT_EXTERNAL_NONE cases */ - && remote_check_hide(ctx->args->uid, process)) { - ctx->do_hide = true; - LOGI("hook: [%s] should be hidden\n", process); +void HookContext::nativeSpecializeAppProcess_pre() { + g_ctx = this; + process = env->GetStringUTFChars(args->nice_name, nullptr); + if (flags[APP_FORK]) { + LOGD("zygisk: pre app fork [%s]\n", process); + } else { + LOGD("zygisk: pre specialize [%s]\n", process); } - env->ReleaseStringUTFChars(ctx->args->nice_name, process); + /* TODO: Handle MOUNT_EXTERNAL_NONE */ + if (args->mount_external != 0 && remote_check_denylist(args->uid, process)) { + flags[DENY_FLAG] = true; + LOGI("zygisk: [%s] is on the denylist\n", process); + } } -void nativeSpecializeAppProcess_post(HookContext *ctx, JNIEnv *env, jclass clazz) { - current_ctx = nullptr; - LOGD("hook: %s\n", __FUNCTION__); +void HookContext::nativeSpecializeAppProcess_post() { + if (flags[APP_FORK]) { + LOGD("zygisk: post app fork [%s]\n", process); + } else { + LOGD("zygisk: post specialize [%s]\n", process); + } - if (ctx->do_hide) + env->ReleaseStringUTFChars(args->nice_name, process); + if (flags[DENY_FLAG]) self_unload(); + g_ctx = nullptr; } // ----------------------------------------------------------------- @@ -253,49 +275,40 @@ int sigmask(int how, int signum) { // Do our own fork before loading any 3rd party code // First block SIGCHLD, unblock after original fork is done #define PRE_FORK() \ - current_ctx = ctx; \ + g_ctx = this; \ sigmask(SIG_BLOCK, SIGCHLD); \ - ctx->pid = old_fork(); \ - if (ctx->pid != 0) \ + pid = old_fork(); \ + if (pid != 0) \ return; // Unblock SIGCHLD in case the original method didn't #define POST_FORK() \ - current_ctx = nullptr; \ - sigmask(SIG_UNBLOCK, SIGCHLD); \ - if (ctx->pid != 0)\ + run_finally f([]{g_ctx = nullptr;}); \ + sigmask(SIG_UNBLOCK, SIGCHLD); \ + if (pid != 0) \ return; -void nativeForkAndSpecialize_pre(HookContext *ctx, JNIEnv *env, jclass clazz) { - PRE_FORK(); - nativeSpecializeAppProcess_pre(ctx, env, clazz); +void HookContext::nativeForkAndSpecialize_pre() { + PRE_FORK() + flags[APP_FORK] = true; + nativeSpecializeAppProcess_pre(); } -void nativeForkAndSpecialize_post(HookContext *ctx, JNIEnv *env, jclass clazz) { - POST_FORK(); - nativeSpecializeAppProcess_post(ctx, env, clazz); +void HookContext::nativeForkAndSpecialize_post() { + POST_FORK() + nativeSpecializeAppProcess_post(); } // ----------------------------------------------------------------- -void nativeForkSystemServer_pre(HookContext *ctx, JNIEnv *env, jclass clazz) { - if (env->functions == new_functions) { - // Restore JNIEnv - env->functions = old_functions; - if (gClassRef) { - env->DeleteGlobalRef(gClassRef); - gClassRef = nullptr; - class_getName = nullptr; - } - } - - PRE_FORK(); - LOGD("hook: %s\n", __FUNCTION__); +void HookContext::nativeForkSystemServer_pre() { + PRE_FORK() + LOGD("zygisk: pre server fork\n"); } -void nativeForkSystemServer_post(HookContext *ctx, JNIEnv *env, jclass clazz) { - POST_FORK(); - LOGD("hook: %s\n", __FUNCTION__); +void HookContext::nativeForkSystemServer_post() { + POST_FORK() + LOGD("zygisk: post server fork\n"); } #undef PRE_FORK @@ -306,10 +319,10 @@ void nativeForkSystemServer_post(HookContext *ctx, JNIEnv *env, jclass clazz) { bool hook_refresh() { if (xhook_refresh(0) == 0) { xhook_clear(); - LOGI("hook: xhook success\n"); + LOGI("zygisk: xhook success\n"); return true; } else { - LOGE("hook: xhook failed\n"); + LOGE("zygisk: xhook failed\n"); return false; } } @@ -356,7 +369,7 @@ void hook_functions() { xhook_list->end()); if (old_jniRegisterNativeMethods == nullptr) { - LOGD("hook: jniRegisterNativeMethods not used\n"); + LOGD("zygisk: jniRegisterNativeMethods not hooked, using fallback\n"); // android::AndroidRuntime::setArgv0(const char *, bool) XHOOK_REGISTER_SYM(APP_PROCESS, "_ZN7android14AndroidRuntime8setArgv0EPKcb", setArgv0); @@ -370,17 +383,23 @@ void hook_functions() { } bool unhook_functions() { - JNIEnv* env; - if (g_jvm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6) != JNI_OK) - return false; + // Restore JNIEnv + if (g_ctx->env->functions == new_functions) { + g_ctx->env->functions = old_functions; + if (gClassRef) { + g_ctx->env->DeleteGlobalRef(gClassRef); + gClassRef = nullptr; + class_getName = nullptr; + } + } - // Do NOT call any destructors + // Do NOT call the destructor operator delete(jni_method_map); // Directly unmap the whole memory block jni_hook::memory_block::release(); // Unhook JNI methods - if (!jni_hook_list->empty() && old_jniRegisterNativeMethods(env, + if (!jni_hook_list->empty() && old_jniRegisterNativeMethods(g_ctx->env, "com/android/internal/os/Zygote", jni_hook_list->data(), jni_hook_list->size()) != 0) { LOGE("hook: Failed to register JNI hook\n"); diff --git a/native/jni/zygisk/jni_hooks.hpp b/native/jni/zygisk/jni_hooks.hpp index 82bb862aa..0fe01fdb0 100644 --- a/native/jni/zygisk/jni_hooks.hpp +++ b/native/jni/zygisk/jni_hooks.hpp @@ -1,54 +1,61 @@ // Generated by gen_jni_hooks.py jint nativeForkAndSpecialize_l(JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, jint mount_external, jstring se_info, jstring nice_name, jintArray fds_to_close, jstring instruction_set, jstring app_data_dir) { - HookContext ctx{}; SpecializeAppProcessArgs args(uid, gid, gids, runtime_flags, mount_external, se_info, nice_name, instruction_set, app_data_dir); + HookContext ctx; + ctx.env = env; + ctx.clazz = clazz; ctx.raw_args = &args; - nativeForkAndSpecialize_pre(&ctx, env, clazz); - reinterpret_cast(nativeForkAndSpecialize_orig)( + ctx.nativeForkAndSpecialize_pre(); + reinterpret_cast(HookContext::nativeForkAndSpecialize_orig)( env, clazz, uid, gid, gids, runtime_flags, rlimits, mount_external, se_info, nice_name, fds_to_close, instruction_set, app_data_dir ); - nativeForkAndSpecialize_post(&ctx, env, clazz); + ctx.nativeForkAndSpecialize_post(); return ctx.pid; } jint nativeForkAndSpecialize_o(JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, jint mount_external, jstring se_info, jstring nice_name, jintArray fds_to_close, jintArray fds_to_ignore, jstring instruction_set, jstring app_data_dir) { - HookContext ctx{}; SpecializeAppProcessArgs args(uid, gid, gids, runtime_flags, mount_external, se_info, nice_name, instruction_set, app_data_dir); + HookContext ctx; + ctx.env = env; + ctx.clazz = clazz; ctx.raw_args = &args; - nativeForkAndSpecialize_pre(&ctx, env, clazz); - reinterpret_cast(nativeForkAndSpecialize_orig)( + ctx.nativeForkAndSpecialize_pre(); + reinterpret_cast(HookContext::nativeForkAndSpecialize_orig)( env, clazz, uid, gid, gids, runtime_flags, rlimits, mount_external, se_info, nice_name, fds_to_close, fds_to_ignore, instruction_set, app_data_dir ); - nativeForkAndSpecialize_post(&ctx, env, clazz); + ctx.nativeForkAndSpecialize_post(); return ctx.pid; } jint nativeForkAndSpecialize_p(JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, jint mount_external, jstring se_info, jstring nice_name, jintArray fds_to_close, jintArray fds_to_ignore, jboolean is_child_zygote, jstring instruction_set, jstring app_data_dir) { - HookContext ctx{}; SpecializeAppProcessArgs args(uid, gid, gids, runtime_flags, mount_external, se_info, nice_name, instruction_set, app_data_dir); args.is_child_zygote = &is_child_zygote; + HookContext ctx; + ctx.env = env; + ctx.clazz = clazz; ctx.raw_args = &args; - nativeForkAndSpecialize_pre(&ctx, env, clazz); - reinterpret_cast(nativeForkAndSpecialize_orig)( + ctx.nativeForkAndSpecialize_pre(); + reinterpret_cast(HookContext::nativeForkAndSpecialize_orig)( env, clazz, uid, gid, gids, runtime_flags, rlimits, mount_external, se_info, nice_name, fds_to_close, fds_to_ignore, is_child_zygote, instruction_set, app_data_dir ); - nativeForkAndSpecialize_post(&ctx, env, clazz); + ctx.nativeForkAndSpecialize_post(); return ctx.pid; } jint nativeForkAndSpecialize_q_alt(JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, jint mount_external, jstring se_info, jstring nice_name, jintArray fds_to_close, jintArray fds_to_ignore, jboolean is_child_zygote, jstring instruction_set, jstring app_data_dir, jboolean is_top_app) { - HookContext ctx{}; SpecializeAppProcessArgs args(uid, gid, gids, runtime_flags, mount_external, se_info, nice_name, instruction_set, app_data_dir); args.is_child_zygote = &is_child_zygote; args.is_top_app = &is_top_app; + HookContext ctx; + ctx.env = env; + ctx.clazz = clazz; ctx.raw_args = &args; - nativeForkAndSpecialize_pre(&ctx, env, clazz); - reinterpret_cast(nativeForkAndSpecialize_orig)( + ctx.nativeForkAndSpecialize_pre(); + reinterpret_cast(HookContext::nativeForkAndSpecialize_orig)( env, clazz, uid, gid, gids, runtime_flags, rlimits, mount_external, se_info, nice_name, fds_to_close, fds_to_ignore, is_child_zygote, instruction_set, app_data_dir, is_top_app ); - nativeForkAndSpecialize_post(&ctx, env, clazz); + ctx.nativeForkAndSpecialize_post(); return ctx.pid; } jint nativeForkAndSpecialize_r(JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, jint mount_external, jstring se_info, jstring nice_name, jintArray fds_to_close, jintArray fds_to_ignore, jboolean is_child_zygote, jstring instruction_set, jstring app_data_dir, jboolean is_top_app, jobjectArray pkg_data_info_list, jobjectArray whitelisted_data_info_list, jboolean mount_data_dirs, jboolean mount_storage_dirs) { - HookContext ctx{}; SpecializeAppProcessArgs args(uid, gid, gids, runtime_flags, mount_external, se_info, nice_name, instruction_set, app_data_dir); args.is_child_zygote = &is_child_zygote; args.is_top_app = &is_top_app; @@ -56,57 +63,68 @@ jint nativeForkAndSpecialize_r(JNIEnv *env, jclass clazz, jint uid, jint gid, ji args.whitelisted_data_info_list = &whitelisted_data_info_list; args.mount_data_dirs = &mount_data_dirs; args.mount_storage_dirs = &mount_storage_dirs; + HookContext ctx; + ctx.env = env; + ctx.clazz = clazz; ctx.raw_args = &args; - nativeForkAndSpecialize_pre(&ctx, env, clazz); - reinterpret_cast(nativeForkAndSpecialize_orig)( + ctx.nativeForkAndSpecialize_pre(); + reinterpret_cast(HookContext::nativeForkAndSpecialize_orig)( env, clazz, uid, gid, gids, runtime_flags, rlimits, mount_external, se_info, nice_name, fds_to_close, fds_to_ignore, is_child_zygote, instruction_set, app_data_dir, is_top_app, pkg_data_info_list, whitelisted_data_info_list, mount_data_dirs, mount_storage_dirs ); - nativeForkAndSpecialize_post(&ctx, env, clazz); + ctx.nativeForkAndSpecialize_post(); return ctx.pid; } jint nativeForkAndSpecialize_samsung_m(JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, jint mount_external, jstring se_info, jint i1, jint i2, jstring nice_name, jintArray fds_to_close, jstring instruction_set, jstring app_data_dir) { - HookContext ctx{}; SpecializeAppProcessArgs args(uid, gid, gids, runtime_flags, mount_external, se_info, nice_name, instruction_set, app_data_dir); + HookContext ctx; + ctx.env = env; + ctx.clazz = clazz; ctx.raw_args = &args; - nativeForkAndSpecialize_pre(&ctx, env, clazz); - reinterpret_cast(nativeForkAndSpecialize_orig)( + ctx.nativeForkAndSpecialize_pre(); + reinterpret_cast(HookContext::nativeForkAndSpecialize_orig)( env, clazz, uid, gid, gids, runtime_flags, rlimits, mount_external, se_info, i1, i2, nice_name, fds_to_close, instruction_set, app_data_dir ); - nativeForkAndSpecialize_post(&ctx, env, clazz); + ctx.nativeForkAndSpecialize_post(); return ctx.pid; } jint nativeForkAndSpecialize_samsung_n(JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, jint mount_external, jstring se_info, jint i1, jint i2, jstring nice_name, jintArray fds_to_close, jstring instruction_set, jstring app_data_dir, jint i3) { - HookContext ctx{}; SpecializeAppProcessArgs args(uid, gid, gids, runtime_flags, mount_external, se_info, nice_name, instruction_set, app_data_dir); + HookContext ctx; + ctx.env = env; + ctx.clazz = clazz; ctx.raw_args = &args; - nativeForkAndSpecialize_pre(&ctx, env, clazz); - reinterpret_cast(nativeForkAndSpecialize_orig)( + ctx.nativeForkAndSpecialize_pre(); + reinterpret_cast(HookContext::nativeForkAndSpecialize_orig)( env, clazz, uid, gid, gids, runtime_flags, rlimits, mount_external, se_info, i1, i2, nice_name, fds_to_close, instruction_set, app_data_dir, i3 ); - nativeForkAndSpecialize_post(&ctx, env, clazz); + ctx.nativeForkAndSpecialize_post(); return ctx.pid; } jint nativeForkAndSpecialize_samsung_o(JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, jint mount_external, jstring se_info, jint i1, jint i2, jstring nice_name, jintArray fds_to_close, jintArray fds_to_ignore, jstring instruction_set, jstring app_data_dir) { - HookContext ctx{}; SpecializeAppProcessArgs args(uid, gid, gids, runtime_flags, mount_external, se_info, nice_name, instruction_set, app_data_dir); + HookContext ctx; + ctx.env = env; + ctx.clazz = clazz; ctx.raw_args = &args; - nativeForkAndSpecialize_pre(&ctx, env, clazz); - reinterpret_cast(nativeForkAndSpecialize_orig)( + ctx.nativeForkAndSpecialize_pre(); + reinterpret_cast(HookContext::nativeForkAndSpecialize_orig)( env, clazz, uid, gid, gids, runtime_flags, rlimits, mount_external, se_info, i1, i2, nice_name, fds_to_close, fds_to_ignore, instruction_set, app_data_dir ); - nativeForkAndSpecialize_post(&ctx, env, clazz); + ctx.nativeForkAndSpecialize_post(); return ctx.pid; } jint nativeForkAndSpecialize_samsung_p(JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, jint mount_external, jstring se_info, jint i1, jint i2, jstring nice_name, jintArray fds_to_close, jintArray fds_to_ignore, jboolean is_child_zygote, jstring instruction_set, jstring app_data_dir) { - HookContext ctx{}; SpecializeAppProcessArgs args(uid, gid, gids, runtime_flags, mount_external, se_info, nice_name, instruction_set, app_data_dir); args.is_child_zygote = &is_child_zygote; + HookContext ctx; + ctx.env = env; + ctx.clazz = clazz; ctx.raw_args = &args; - nativeForkAndSpecialize_pre(&ctx, env, clazz); - reinterpret_cast(nativeForkAndSpecialize_orig)( + ctx.nativeForkAndSpecialize_pre(); + reinterpret_cast(HookContext::nativeForkAndSpecialize_orig)( env, clazz, uid, gid, gids, runtime_flags, rlimits, mount_external, se_info, i1, i2, nice_name, fds_to_close, fds_to_ignore, is_child_zygote, instruction_set, app_data_dir ); - nativeForkAndSpecialize_post(&ctx, env, clazz); + ctx.nativeForkAndSpecialize_post(); return ctx.pid; } const JNINativeMethod nativeForkAndSpecialize_methods[] = { @@ -159,30 +177,33 @@ const JNINativeMethod nativeForkAndSpecialize_methods[] = { constexpr int nativeForkAndSpecialize_methods_num = std::size(nativeForkAndSpecialize_methods); void nativeSpecializeAppProcess_q(JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, jint mount_external, jstring se_info, jstring nice_name, jboolean is_child_zygote, jstring instruction_set, jstring app_data_dir) { - HookContext ctx{}; SpecializeAppProcessArgs args(uid, gid, gids, runtime_flags, mount_external, se_info, nice_name, instruction_set, app_data_dir); args.is_child_zygote = &is_child_zygote; + HookContext ctx; + ctx.env = env; + ctx.clazz = clazz; ctx.raw_args = &args; - nativeSpecializeAppProcess_pre(&ctx, env, clazz); - reinterpret_cast(nativeSpecializeAppProcess_orig)( + ctx.nativeSpecializeAppProcess_pre(); + reinterpret_cast(HookContext::nativeSpecializeAppProcess_orig)( env, clazz, uid, gid, gids, runtime_flags, rlimits, mount_external, se_info, nice_name, is_child_zygote, instruction_set, app_data_dir ); - nativeSpecializeAppProcess_post(&ctx, env, clazz); + ctx.nativeSpecializeAppProcess_post(); } void nativeSpecializeAppProcess_q_alt(JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, jint mount_external, jstring se_info, jstring nice_name, jboolean is_child_zygote, jstring instruction_set, jstring app_data_dir, jboolean is_top_app) { - HookContext ctx{}; SpecializeAppProcessArgs args(uid, gid, gids, runtime_flags, mount_external, se_info, nice_name, instruction_set, app_data_dir); args.is_child_zygote = &is_child_zygote; args.is_top_app = &is_top_app; + HookContext ctx; + ctx.env = env; + ctx.clazz = clazz; ctx.raw_args = &args; - nativeSpecializeAppProcess_pre(&ctx, env, clazz); - reinterpret_cast(nativeSpecializeAppProcess_orig)( + ctx.nativeSpecializeAppProcess_pre(); + reinterpret_cast(HookContext::nativeSpecializeAppProcess_orig)( env, clazz, uid, gid, gids, runtime_flags, rlimits, mount_external, se_info, nice_name, is_child_zygote, instruction_set, app_data_dir, is_top_app ); - nativeSpecializeAppProcess_post(&ctx, env, clazz); + ctx.nativeSpecializeAppProcess_post(); } void nativeSpecializeAppProcess_r(JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, jint mount_external, jstring se_info, jstring nice_name, jboolean is_child_zygote, jstring instruction_set, jstring app_data_dir, jboolean is_top_app, jobjectArray pkg_data_info_list, jobjectArray whitelisted_data_info_list, jboolean mount_data_dirs, jboolean mount_storage_dirs) { - HookContext ctx{}; SpecializeAppProcessArgs args(uid, gid, gids, runtime_flags, mount_external, se_info, nice_name, instruction_set, app_data_dir); args.is_child_zygote = &is_child_zygote; args.is_top_app = &is_top_app; @@ -190,23 +211,28 @@ void nativeSpecializeAppProcess_r(JNIEnv *env, jclass clazz, jint uid, jint gid, args.whitelisted_data_info_list = &whitelisted_data_info_list; args.mount_data_dirs = &mount_data_dirs; args.mount_storage_dirs = &mount_storage_dirs; + HookContext ctx; + ctx.env = env; + ctx.clazz = clazz; ctx.raw_args = &args; - nativeSpecializeAppProcess_pre(&ctx, env, clazz); - reinterpret_cast(nativeSpecializeAppProcess_orig)( + ctx.nativeSpecializeAppProcess_pre(); + reinterpret_cast(HookContext::nativeSpecializeAppProcess_orig)( env, clazz, uid, gid, gids, runtime_flags, rlimits, mount_external, se_info, nice_name, is_child_zygote, instruction_set, app_data_dir, is_top_app, pkg_data_info_list, whitelisted_data_info_list, mount_data_dirs, mount_storage_dirs ); - nativeSpecializeAppProcess_post(&ctx, env, clazz); + ctx.nativeSpecializeAppProcess_post(); } void nativeSpecializeAppProcess_samsung_q(JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, jint mount_external, jstring se_info, jint i1, jint i2, jstring nice_name, jboolean is_child_zygote, jstring instruction_set, jstring app_data_dir) { - HookContext ctx{}; SpecializeAppProcessArgs args(uid, gid, gids, runtime_flags, mount_external, se_info, nice_name, instruction_set, app_data_dir); args.is_child_zygote = &is_child_zygote; + HookContext ctx; + ctx.env = env; + ctx.clazz = clazz; ctx.raw_args = &args; - nativeSpecializeAppProcess_pre(&ctx, env, clazz); - reinterpret_cast(nativeSpecializeAppProcess_orig)( + ctx.nativeSpecializeAppProcess_pre(); + reinterpret_cast(HookContext::nativeSpecializeAppProcess_orig)( env, clazz, uid, gid, gids, runtime_flags, rlimits, mount_external, se_info, i1, i2, nice_name, is_child_zygote, instruction_set, app_data_dir ); - nativeSpecializeAppProcess_post(&ctx, env, clazz); + ctx.nativeSpecializeAppProcess_post(); } const JNINativeMethod nativeSpecializeAppProcess_methods[] = { { @@ -232,33 +258,37 @@ const JNINativeMethod nativeSpecializeAppProcess_methods[] = { }; constexpr int nativeSpecializeAppProcess_methods_num = std::size(nativeSpecializeAppProcess_methods); -jint nativeForkSystemServer_m(JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, jlong permitted_capabilities, jlong effective_capabilities) { - HookContext ctx{}; +jint nativeForkSystemServer_l(JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, jlong permitted_capabilities, jlong effective_capabilities) { ForkSystemServerArgs args(uid, gid, gids, runtime_flags, permitted_capabilities, effective_capabilities); + HookContext ctx; + ctx.env = env; + ctx.clazz = clazz; ctx.raw_args = &args; - nativeForkSystemServer_pre(&ctx, env, clazz); - reinterpret_cast(nativeForkSystemServer_orig)( + ctx.nativeForkSystemServer_pre(); + reinterpret_cast(HookContext::nativeForkSystemServer_orig)( env, clazz, uid, gid, gids, runtime_flags, rlimits, permitted_capabilities, effective_capabilities ); - nativeForkSystemServer_post(&ctx, env, clazz); + ctx.nativeForkSystemServer_post(); return ctx.pid; } jint nativeForkSystemServer_samsung_q(JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint runtime_flags, jint i1, jint i2, jobjectArray rlimits, jlong permitted_capabilities, jlong effective_capabilities) { - HookContext ctx{}; ForkSystemServerArgs args(uid, gid, gids, runtime_flags, permitted_capabilities, effective_capabilities); + HookContext ctx; + ctx.env = env; + ctx.clazz = clazz; ctx.raw_args = &args; - nativeForkSystemServer_pre(&ctx, env, clazz); - reinterpret_cast(nativeForkSystemServer_orig)( + ctx.nativeForkSystemServer_pre(); + reinterpret_cast(HookContext::nativeForkSystemServer_orig)( env, clazz, uid, gid, gids, runtime_flags, i1, i2, rlimits, permitted_capabilities, effective_capabilities ); - nativeForkSystemServer_post(&ctx, env, clazz); + ctx.nativeForkSystemServer_post(); return ctx.pid; } const JNINativeMethod nativeForkSystemServer_methods[] = { { "nativeForkSystemServer", "(II[II[[IJJ)I", - (void *) &nativeForkSystemServer_m + (void *) &nativeForkSystemServer_l }, { "nativeForkSystemServer",