diff --git a/native/src/core/zygisk/entry.cpp b/native/src/core/zygisk/entry.cpp index 6affcd8e7..433308020 100644 --- a/native/src/core/zygisk/entry.cpp +++ b/native/src/core/zygisk/entry.cpp @@ -17,7 +17,7 @@ string native_bridge = "0"; static bool is_compatible_with(uint32_t) { zygisk_logging(); - hook_functions(); + hook_entry(); ZLOGD("load success\n"); return false; } @@ -55,12 +55,13 @@ static vector get_module_fds(bool is_64_bit) { // All fds passed to send_fds have to be valid file descriptors. // To workaround this issue, send over STDOUT_FILENO as an indicator of an // invalid fd as it will always be /dev/null in magiskd - if (is_64_bit) { #if defined(__LP64__) + if (is_64_bit) { std::transform(module_list->begin(), module_list->end(), std::back_inserter(fds), [](const module_info &info) { return info.z64 < 0 ? STDOUT_FILENO : info.z64; }); + } else #endif - } else { + { std::transform(module_list->begin(), module_list->end(), std::back_inserter(fds), [](const module_info &info) { return info.z32 < 0 ? STDOUT_FILENO : info.z32; }); } diff --git a/native/src/core/zygisk/gen_jni_hooks.py b/native/src/core/zygisk/gen_jni_hooks.py index d4eb5a82c..04e06b1f8 100755 --- a/native/src/core/zygisk/gen_jni_hooks.py +++ b/native/src/core/zygisk/gen_jni_hooks.py @@ -66,7 +66,7 @@ class JNIHook(Method): return '' def orig_method(self, name, i): - return f'reinterpret_cast<{self.ret.type.cpp}(*)(JNIEnv *env, jclass clazz, {self.cpp()})>({name}_methods[{i}].fnPtr)' + return f'reinterpret_cast<{self.ret.type.cpp}(*)(JNIEnv *env, jclass clazz, {self.cpp()})>(g_hook->{name}_methods[{i}].fnPtr)' def ind(i): return '\n' + ' ' * i @@ -210,10 +210,9 @@ server_l = ForkServer('l', [uid, gid, gids, runtime_flags, rlimits, server_samsung_q = ForkServer('samsung_q', [uid, gid, gids, runtime_flags, Anon(jint), Anon(jint), rlimits, permitted_capabilities, effective_capabilities]) -def gen_jni_def(name, clz, methods): +def gen_jni_def(name, methods): decl = '' - decl += ind(0) + f'static constexpr auto {name}_class = "{clz}";' - decl += ind(0) + f'static std::array {name}_methods = {{{{' + decl += ind(0) + f'std::array {name}_methods = {{{{' for i, m in enumerate(methods): decl += ind(1) + '{' decl += ind(2) + f'"{m.base_name()}",' @@ -232,9 +231,7 @@ def gen_jni_def(name, clz, methods): with open('jni_hooks.hpp', 'w') as f: f.write('// Generated by gen_jni_hooks.py\n') - zygote = 'com/android/internal/os/Zygote' - - f.write(gen_jni_def('zygote', zygote, [ + f.write(gen_jni_def('zygote', [ fas_l, fas_o, fas_p, fas_q_alt, fas_r, fas_u, fas_samsung_m, fas_samsung_n, fas_samsung_o, fas_samsung_p, spec_q, spec_q_alt, spec_r, spec_u, spec_samsung_q, server_l, server_samsung_q])) diff --git a/native/src/core/zygisk/hook.cpp b/native/src/core/zygisk/hook.cpp index d46d91806..63abef377 100644 --- a/native/src/core/zygisk/hook.cpp +++ b/native/src/core/zygisk/hook.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include @@ -9,7 +10,6 @@ #include "zygisk.hpp" #include "module.hpp" -#include "jni_hooks.hpp" using namespace std; @@ -51,12 +51,12 @@ using namespace std; // └──────────────────────┼────────────────►│post_native_bridge_load│ // │ └───────────────────────┘ // ▼ -// ┌──────────────────────────┐ -// │ strdup("ZygiskInit") │ -// └─────────────┬────┬───────┘ -// │ │ ┌───────────────────┐ -// │ └─────────────►│replace_jni_methods│ -// │ └───────────────────┘ ┌─────────┐ +// ┌──────────────────────┐ +// │ strdup("ZygoteInit") │ +// └───────────┬────┬─────┘ +// │ │ ┌───────────────┐ +// │ └───────────────►│hook_zygote_jni│ +// │ └───────────────┘ ┌─────────┐ // │ │ │ // └────────────────────────────────────────────►│ JVM │ // │ │ @@ -78,28 +78,16 @@ using namespace std; // // * NativeBridgeItf: this symbol is the entry point for android::LoadNativeBridge // * HookContext::hook_plt(): hook functions like |dlclose| and |strdup| -// * dlclose: the final step before android::LoadNativeBridge returns -// * strdup: called in AndroidRuntime::start before calling specializations routines -// * HookContext::replace_jni_methods: replace the function pointers registered in -// register_jni_procs, most importantly the process specialization routines, which are our -// main targets. This marks the final step of the code injection bootstrap process. +// * dlclose: the final step in android::LoadNativeBridge. In this function, we unwind the call +// stack to load the real native bridge if necessary, and fetch NativeBridgeRuntimeCallbacks. +// * strdup: called in AndroidRuntime::start before calling ZygoteInit#main(...) +// * HookContext::hook_zygote_jni(): replace the process specialization functions registered +// with register_jni_procs. This marks the final step of the code injection bootstrap process. // * pthread_attr_destroy: called whenever the JVM tries to setup threads for itself. We use // this method to cleanup and unload Zygisk from the process. -struct HookContext { - vector> plt_backup; - const NativeBridgeRuntimeCallbacks *runtime_callbacks = nullptr; - - void hook_plt(); - void hook_unloader(); - void restore_plt_hook(); - void replace_jni_methods(); - void restore_jni_hook(JNIEnv *env); - void post_native_bridge_load(); - -private: - void register_hook(dev_t dev, ino_t inode, const char *symbol, void *new_func, void **old_func); -}; +constexpr const char *kZygoteInit = "com.android.internal.os.ZygoteInit"; +constexpr const char *kZygote = "com/android/internal/os/Zygote"; // Global contexts: // @@ -110,11 +98,31 @@ private: // features, such as loading modules and customizing process fork/specialization. ZygiskContext *g_ctx; - +struct HookContext; static HookContext *g_hook; -static bool should_unmap_zygisk = false; -static void *self_handle = nullptr; -static constexpr const char *kZygiskInit = "com.android.internal.os.ZygoteInit"; + +using JNIMethods = std::span; + +struct HookContext { +#include "jni_hooks.hpp" + + // std::array zygote_methods + vector> plt_backup; + const NativeBridgeRuntimeCallbacks *runtime_callbacks = nullptr; + void *self_handle = nullptr; + bool should_unmap = false; + + void hook_plt(); + void hook_unloader(); + void restore_plt_hook(); + void hook_zygote_jni(); + void restore_zygote_hook(JNIEnv *env); + void hook_jni_methods(JNIEnv *env, const char *clz, JNIMethods methods); + void post_native_bridge_load(void *handle); + +private: + void register_hook(dev_t dev, ino_t inode, const char *symbol, void *new_func, void **old_func); +}; // ----------------------------------------------------------------- @@ -123,8 +131,8 @@ ret (*old_##func)(__VA_ARGS__); \ ret new_##func(__VA_ARGS__) DCL_HOOK_FUNC(static char *, strdup, const char * str) { - if (strcmp(kZygiskInit, str) == 0) { - g_hook->replace_jni_methods(); + if (strcmp(kZygoteInit, str) == 0) { + g_hook->hook_zygote_jni(); } return old_strdup(str); } @@ -167,10 +175,9 @@ DCL_HOOK_FUNC(static void, android_log_close) { // It should be safe to assume all dlclose's in libnativebridge are for zygisk_loader DCL_HOOK_FUNC(static int, dlclose, void *handle) { - if (!self_handle) { + if (!g_hook->self_handle) { ZLOGV("dlclose zygisk_loader\n"); - self_handle = handle; - g_hook->post_native_bridge_load(); + g_hook->post_native_bridge_load(handle); } return 0; } @@ -186,10 +193,11 @@ DCL_HOOK_FUNC(static int, pthread_attr_destroy, void *target) { return res; ZLOGV("pthread_attr_destroy\n"); - if (should_unmap_zygisk) { + if (g_hook->should_unmap) { g_hook->restore_plt_hook(); - if (should_unmap_zygisk) { + if (g_hook->should_unmap) { ZLOGV("dlclosing self\n"); + void *self_handle = g_hook->self_handle; delete g_hook; // Because both `pthread_attr_destroy` and `dlclose` have the same function signature, @@ -229,8 +237,8 @@ ZygiskContext::~ZygiskContext() { } // Cleanup - should_unmap_zygisk = true; - g_hook->restore_jni_hook(env); + g_hook->should_unmap = true; + g_hook->restore_zygote_hook(env); g_hook->hook_unloader(); } @@ -318,7 +326,8 @@ static const NativeBridgeRuntimeCallbacks* find_runtime_callbacks(struct _Unwind return nullptr; } -void HookContext::post_native_bridge_load() { +void HookContext::post_native_bridge_load(void *handle) { + self_handle = handle; using method_sig = const bool (*)(const char *, const NativeBridgeRuntimeCallbacks *); struct trace_arg { method_sig load_native_bridge; @@ -427,18 +436,63 @@ void HookContext::restore_plt_hook() { for (const auto &[dev, inode, sym, old_func] : plt_backup) { if (!lsplt::RegisterHook(dev, inode, sym, *old_func, nullptr)) { ZLOGE("Failed to register plt_hook [%s]\n", sym); - should_unmap_zygisk = false; + should_unmap = false; } } if (!lsplt::CommitHook()) { ZLOGE("Failed to restore plt_hook\n"); - should_unmap_zygisk = false; + should_unmap = false; } } // ----------------------------------------------------------------- -void HookContext::replace_jni_methods() { +void HookContext::hook_jni_methods(JNIEnv *env, const char *clz, JNIMethods methods) { + jclass clazz; + if (!runtime_callbacks || !env || !clz || !(clazz = env->FindClass(clz))) { + for (auto &method : methods) { + method.fnPtr = nullptr; + } + return; + } + + // Backup existing methods + auto total = runtime_callbacks->getNativeMethodCount(env, clazz); + auto old_methods = std::make_unique_for_overwrite(total); + runtime_callbacks->getNativeMethods(env, clazz, old_methods.get(), total); + auto new_methods = std::make_unique_for_overwrite(total); + + // Replace the method + for (auto &method : methods) { + // It's useful to allow nullptr function pointer for restoring hook + if (!method.fnPtr) continue; + // It's normal that the method is not found + if (env->RegisterNatives(clazz, &method, 1) == JNI_ERR || + env->ExceptionCheck() == JNI_TRUE) { + if (auto exception = env->ExceptionOccurred()) { + env->DeleteLocalRef(exception); + } + env->ExceptionClear(); + method.fnPtr = nullptr; + continue; + } + // Find the old function pointer and return to caller + runtime_callbacks->getNativeMethods(env, clazz, new_methods.get(), total); + for (auto i = 0; i < total; ++i) { + auto &new_method = new_methods[i]; + if (new_method.fnPtr == method.fnPtr && strcmp(new_method.name, method.name) == 0) { + auto &old_method = old_methods[i]; + ZLOGD("replace %s#%s%s %p -> %p\n", clz, + method.name, method.signature, old_method.fnPtr, method.fnPtr); + method.fnPtr = old_method.fnPtr; + break; + } + } + old_methods.swap(new_methods); + } +} + +void HookContext::hook_zygote_jni() { using method_sig = jint(*)(JavaVM **, jsize, jsize *); auto get_created_vms = reinterpret_cast( dlsym(RTLD_DEFAULT, "JNI_GetCreatedJavaVMs")); @@ -472,63 +526,20 @@ void HookContext::replace_jni_methods() { if (res != JNI_OK || env == nullptr) { ZLOGW("JNIEnv not found\n"); } - hookJniNativeMethods(env, zygote_class, zygote_methods.data(), zygote_methods.size()); + hook_jni_methods(env, kZygote, zygote_methods); } -void HookContext::restore_jni_hook(JNIEnv *env) { - hookJniNativeMethods(env, zygote_class, zygote_methods.data(), zygote_methods.size()); +void HookContext::restore_zygote_hook(JNIEnv *env) { + hook_jni_methods(env, kZygote, zygote_methods); } // ----------------------------------------------------------------- -void hook_functions() { +void hook_entry() { default_new(g_hook); g_hook->hook_plt(); } void hookJniNativeMethods(JNIEnv *env, const char *clz, JNINativeMethod *methods, int numMethods) { - jclass clazz; - if (!g_hook || !g_hook->runtime_callbacks || !env || !clz || !(clazz = env->FindClass(clz))) { - for (auto i = 0; i < numMethods; ++i) { - methods[i].fnPtr = nullptr; - } - return; - } - - // Backup existing methods - auto total = g_hook->runtime_callbacks->getNativeMethodCount(env, clazz); - auto old_methods = std::make_unique_for_overwrite(total); - g_hook->runtime_callbacks->getNativeMethods(env, clazz, old_methods.get(), total); - auto new_methods = std::make_unique_for_overwrite(total); - - // Replace the method - for (auto i = 0; i < numMethods; ++i) { - auto &method = methods[i]; - // It's useful to allow nullptr function pointer for restoring hook - if (!method.fnPtr) continue; - // It's normal that the method is not found - if (env->RegisterNatives(clazz, &method, 1) == JNI_ERR || - env->ExceptionCheck() == JNI_TRUE) { - if (auto *exception = env->ExceptionOccurred()) { - env->DeleteLocalRef(exception); - } - env->ExceptionClear(); - method.fnPtr = nullptr; - continue; - } - // Find the old function pointer and return to caller - g_hook->runtime_callbacks->getNativeMethods(env, clazz, new_methods.get(), total); - for (auto j = 0; j < total; ++j) { - auto &new_method = new_methods[j]; - auto &old_method = old_methods[j]; - if (new_method.fnPtr == method.fnPtr && old_method.fnPtr != new_method.fnPtr && - strcmp(new_method.name, method.name) == 0) { - ZLOGD("replace %s#%s%s %p -> %p\n", clz, - method.name, method.signature, old_method.fnPtr, method.fnPtr); - method.fnPtr = old_method.fnPtr; - break; - } - } - old_methods.swap(new_methods); - } + g_hook->hook_jni_methods(env, clz, { methods, (size_t) numMethods }); } diff --git a/native/src/core/zygisk/jni_hooks.hpp b/native/src/core/zygisk/jni_hooks.hpp index 4cf391255..d1be01474 100644 --- a/native/src/core/zygisk/jni_hooks.hpp +++ b/native/src/core/zygisk/jni_hooks.hpp @@ -1,7 +1,6 @@ // Generated by gen_jni_hooks.py -static constexpr auto zygote_class = "com/android/internal/os/Zygote"; -static std::array zygote_methods = {{ +std::array zygote_methods = {{ { "nativeForkAndSpecialize", "(II[II[[IILjava/lang/String;Ljava/lang/String;[ILjava/lang/String;Ljava/lang/String;)I", @@ -9,7 +8,7 @@ static std::array zygote_methods = {{ AppSpecializeArgs_v5 args(uid, gid, gids, runtime_flags, rlimits, mount_external, se_info, nice_name, instruction_set, app_data_dir); ZygiskContext ctx(env, &args); ctx.nativeForkAndSpecialize_pre(); - reinterpret_cast(zygote_methods[0].fnPtr)( + reinterpret_cast(g_hook->zygote_methods[0].fnPtr)( env, clazz, uid, gid, gids, runtime_flags, rlimits, mount_external, se_info, nice_name, fds_to_close, instruction_set, app_data_dir ); ctx.nativeForkAndSpecialize_post(); @@ -24,7 +23,7 @@ static std::array zygote_methods = {{ args.fds_to_ignore = &fds_to_ignore; ZygiskContext ctx(env, &args); ctx.nativeForkAndSpecialize_pre(); - reinterpret_cast(zygote_methods[1].fnPtr)( + reinterpret_cast(g_hook->zygote_methods[1].fnPtr)( 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 ); ctx.nativeForkAndSpecialize_post(); @@ -40,7 +39,7 @@ static std::array zygote_methods = {{ args.is_child_zygote = &is_child_zygote; ZygiskContext ctx(env, &args); ctx.nativeForkAndSpecialize_pre(); - reinterpret_cast(zygote_methods[2].fnPtr)( + reinterpret_cast(g_hook->zygote_methods[2].fnPtr)( 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 ); ctx.nativeForkAndSpecialize_post(); @@ -57,7 +56,7 @@ static std::array zygote_methods = {{ args.is_top_app = &is_top_app; ZygiskContext ctx(env, &args); ctx.nativeForkAndSpecialize_pre(); - reinterpret_cast(zygote_methods[3].fnPtr)( + reinterpret_cast(g_hook->zygote_methods[3].fnPtr)( 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 ); ctx.nativeForkAndSpecialize_post(); @@ -78,7 +77,7 @@ static std::array zygote_methods = {{ args.mount_storage_dirs = &mount_storage_dirs; ZygiskContext ctx(env, &args); ctx.nativeForkAndSpecialize_pre(); - reinterpret_cast(zygote_methods[4].fnPtr)( + reinterpret_cast(g_hook->zygote_methods[4].fnPtr)( 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 ); ctx.nativeForkAndSpecialize_post(); @@ -100,7 +99,7 @@ static std::array zygote_methods = {{ args.mount_sysprop_overrides = &mount_sysprop_overrides; ZygiskContext ctx(env, &args); ctx.nativeForkAndSpecialize_pre(); - reinterpret_cast(zygote_methods[5].fnPtr)( + reinterpret_cast(g_hook->zygote_methods[5].fnPtr)( 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, mount_sysprop_overrides ); ctx.nativeForkAndSpecialize_post(); @@ -114,7 +113,7 @@ static std::array zygote_methods = {{ AppSpecializeArgs_v5 args(uid, gid, gids, runtime_flags, rlimits, mount_external, se_info, nice_name, instruction_set, app_data_dir); ZygiskContext ctx(env, &args); ctx.nativeForkAndSpecialize_pre(); - reinterpret_cast(zygote_methods[6].fnPtr)( + reinterpret_cast(g_hook->zygote_methods[6].fnPtr)( env, clazz, uid, gid, gids, runtime_flags, rlimits, mount_external, se_info, _0, _1, nice_name, fds_to_close, instruction_set, app_data_dir ); ctx.nativeForkAndSpecialize_post(); @@ -128,7 +127,7 @@ static std::array zygote_methods = {{ AppSpecializeArgs_v5 args(uid, gid, gids, runtime_flags, rlimits, mount_external, se_info, nice_name, instruction_set, app_data_dir); ZygiskContext ctx(env, &args); ctx.nativeForkAndSpecialize_pre(); - reinterpret_cast(zygote_methods[7].fnPtr)( + reinterpret_cast(g_hook->zygote_methods[7].fnPtr)( env, clazz, uid, gid, gids, runtime_flags, rlimits, mount_external, se_info, _2, _3, nice_name, fds_to_close, instruction_set, app_data_dir, _4 ); ctx.nativeForkAndSpecialize_post(); @@ -143,7 +142,7 @@ static std::array zygote_methods = {{ args.fds_to_ignore = &fds_to_ignore; ZygiskContext ctx(env, &args); ctx.nativeForkAndSpecialize_pre(); - reinterpret_cast(zygote_methods[8].fnPtr)( + reinterpret_cast(g_hook->zygote_methods[8].fnPtr)( env, clazz, uid, gid, gids, runtime_flags, rlimits, mount_external, se_info, _5, _6, nice_name, fds_to_close, fds_to_ignore, instruction_set, app_data_dir ); ctx.nativeForkAndSpecialize_post(); @@ -159,7 +158,7 @@ static std::array zygote_methods = {{ args.is_child_zygote = &is_child_zygote; ZygiskContext ctx(env, &args); ctx.nativeForkAndSpecialize_pre(); - reinterpret_cast(zygote_methods[9].fnPtr)( + reinterpret_cast(g_hook->zygote_methods[9].fnPtr)( env, clazz, uid, gid, gids, runtime_flags, rlimits, mount_external, se_info, _7, _8, nice_name, fds_to_close, fds_to_ignore, is_child_zygote, instruction_set, app_data_dir ); ctx.nativeForkAndSpecialize_post(); @@ -174,7 +173,7 @@ static std::array zygote_methods = {{ args.is_child_zygote = &is_child_zygote; ZygiskContext ctx(env, &args); ctx.nativeSpecializeAppProcess_pre(); - reinterpret_cast(zygote_methods[10].fnPtr)( + reinterpret_cast(g_hook->zygote_methods[10].fnPtr)( env, clazz, uid, gid, gids, runtime_flags, rlimits, mount_external, se_info, nice_name, is_child_zygote, instruction_set, app_data_dir ); ctx.nativeSpecializeAppProcess_post(); @@ -189,7 +188,7 @@ static std::array zygote_methods = {{ args.is_top_app = &is_top_app; ZygiskContext ctx(env, &args); ctx.nativeSpecializeAppProcess_pre(); - reinterpret_cast(zygote_methods[11].fnPtr)( + reinterpret_cast(g_hook->zygote_methods[11].fnPtr)( 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 ); ctx.nativeSpecializeAppProcess_post(); @@ -208,7 +207,7 @@ static std::array zygote_methods = {{ args.mount_storage_dirs = &mount_storage_dirs; ZygiskContext ctx(env, &args); ctx.nativeSpecializeAppProcess_pre(); - reinterpret_cast(zygote_methods[12].fnPtr)( + reinterpret_cast(g_hook->zygote_methods[12].fnPtr)( 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 ); ctx.nativeSpecializeAppProcess_post(); @@ -228,7 +227,7 @@ static std::array zygote_methods = {{ args.mount_sysprop_overrides = &mount_sysprop_overrides; ZygiskContext ctx(env, &args); ctx.nativeSpecializeAppProcess_pre(); - reinterpret_cast(zygote_methods[13].fnPtr)( + reinterpret_cast(g_hook->zygote_methods[13].fnPtr)( 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, mount_sysprop_overrides ); ctx.nativeSpecializeAppProcess_post(); @@ -242,7 +241,7 @@ static std::array zygote_methods = {{ args.is_child_zygote = &is_child_zygote; ZygiskContext ctx(env, &args); ctx.nativeSpecializeAppProcess_pre(); - reinterpret_cast(zygote_methods[14].fnPtr)( + reinterpret_cast(g_hook->zygote_methods[14].fnPtr)( env, clazz, uid, gid, gids, runtime_flags, rlimits, mount_external, se_info, _9, _10, nice_name, is_child_zygote, instruction_set, app_data_dir ); ctx.nativeSpecializeAppProcess_post(); @@ -255,7 +254,7 @@ static std::array zygote_methods = {{ ServerSpecializeArgs_v1 args(uid, gid, gids, runtime_flags, permitted_capabilities, effective_capabilities); ZygiskContext ctx(env, &args); ctx.nativeForkSystemServer_pre(); - reinterpret_cast(zygote_methods[15].fnPtr)( + reinterpret_cast(g_hook->zygote_methods[15].fnPtr)( env, clazz, uid, gid, gids, runtime_flags, rlimits, permitted_capabilities, effective_capabilities ); ctx.nativeForkSystemServer_post(); @@ -269,7 +268,7 @@ static std::array zygote_methods = {{ ServerSpecializeArgs_v1 args(uid, gid, gids, runtime_flags, permitted_capabilities, effective_capabilities); ZygiskContext ctx(env, &args); ctx.nativeForkSystemServer_pre(); - reinterpret_cast(zygote_methods[16].fnPtr)( + reinterpret_cast(g_hook->zygote_methods[16].fnPtr)( env, clazz, uid, gid, gids, runtime_flags, _11, _12, rlimits, permitted_capabilities, effective_capabilities ); ctx.nativeForkSystemServer_post(); diff --git a/native/src/core/zygisk/zygisk.hpp b/native/src/core/zygisk/zygisk.hpp index 46c794dd8..939a05fe2 100644 --- a/native/src/core/zygisk/zygisk.hpp +++ b/native/src/core/zygisk/zygisk.hpp @@ -31,7 +31,7 @@ enum : int { #define ZLOGV(...) ZLOGD(__VA_ARGS__) //#define ZLOGV(...) (void*)0 -void hook_functions(); +void hook_entry(); void hookJniNativeMethods(JNIEnv *env, const char *clz, JNINativeMethod *methods, int numMethods); int remote_get_info(int uid, const char *process, uint32_t *flags, std::vector &fds);