From a510554b21736ed14dd8d96ead95f0e3f29e3a2f Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Sat, 6 Dec 2025 20:01:43 -0800 Subject: [PATCH] Disable Zygisk upon incomplete JNI hook Do not enable Zygisk unless ALL replacements are hooked properly. This allow Zygisk tests to fail when new signature is introduced. --- native/src/core/zygisk/gen_jni_hooks.py | 24 +++-- native/src/core/zygisk/hook.cpp | 138 ++++++++++++++++++------ native/src/core/zygisk/jni_hooks.hpp | 59 ++++++---- native/src/core/zygisk/zygisk.hpp | 2 +- 4 files changed, 159 insertions(+), 64 deletions(-) diff --git a/native/src/core/zygisk/gen_jni_hooks.py b/native/src/core/zygisk/gen_jni_hooks.py index 04e06b1f8..19c070c3d 100755 --- a/native/src/core/zygisk/gen_jni_hooks.py +++ b/native/src/core/zygisk/gen_jni_hooks.py @@ -65,8 +65,8 @@ class JNIHook(Method): def base_name(self): return '' - def orig_method(self, name, i): - return f'reinterpret_cast<{self.ret.type.cpp}(*)(JNIEnv *env, jclass clazz, {self.cpp()})>(g_hook->{name}_methods[{i}].fnPtr)' + def orig_method(self, field, i): + return f'reinterpret_cast<{self.ret.type.cpp}(*)(JNIEnv *env, jclass clazz, {self.cpp()})>(g_hook->{field}[{i}].fnPtr)' def ind(i): return '\n' + ' ' * i @@ -89,7 +89,7 @@ class ForkAndSpec(JNIHook): def init_args(self): return 'AppSpecializeArgs_v5 args(uid, gid, gids, runtime_flags, rlimits, mount_external, se_info, nice_name, instruction_set, app_data_dir);' - def body(self, name, i): + def body(self, field, i): decl = '' decl += ind(3) + self.init_args() for a in self.args: @@ -97,7 +97,7 @@ class ForkAndSpec(JNIHook): decl += ind(3) + f'args.{a.name} = &{a.name};' decl += ind(3) + 'ZygiskContext ctx(env, &args);' decl += ind(3) + f'ctx.{self.base_name()}_pre();' - decl += ind(3) + self.orig_method(name, i) + '(' + decl += ind(3) + self.orig_method(field, i) + '(' decl += ind(4) + f'env, clazz, {self.name_list()}' decl += ind(3) + ');' decl += ind(3) + f'ctx.{self.base_name()}_post();' @@ -210,15 +210,16 @@ 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, methods): +def gen_jni_def(field, methods): decl = '' - decl += ind(0) + f'std::array {name}_methods = {{{{' + decl += ind(0) + f'std::array {field} = {{{{' for i, m in enumerate(methods): + decl += ind(1) + f'// {m.name}' decl += ind(1) + '{' decl += ind(2) + f'"{m.base_name()}",' decl += ind(2) + f'"{m.jni()}",' decl += ind(2) + f'(void *) +[] [[clang::no_stack_protector]] (JNIEnv *env, jclass clazz, {m.cpp()}) static -> {m.ret.type.cpp} {{' - decl += m.body(name, i) + decl += m.body(field, i) if m.ret.value: decl += ind(3) + f'return {m.ret.value};' decl += ind(2) + '}' @@ -231,8 +232,11 @@ def gen_jni_def(name, methods): with open('jni_hooks.hpp', 'w') as f: f.write('// Generated by gen_jni_hooks.py\n') - 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])) + f.write(gen_jni_def('fork_app_methods', [ + 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])) + + f.write(gen_jni_def('specialize_app_methods', [spec_q, spec_q_alt, spec_r, spec_u, spec_samsung_q])) + + f.write(gen_jni_def('fork_server_methods', [server_l, server_samsung_q])) f.write('\n') diff --git a/native/src/core/zygisk/hook.cpp b/native/src/core/zygisk/hook.cpp index 2ab3c3af5..b68f29730 100644 --- a/native/src/core/zygisk/hook.cpp +++ b/native/src/core/zygisk/hook.cpp @@ -8,7 +8,6 @@ #include #include -#include #include "zygisk.hpp" #include "module.hpp" @@ -90,6 +89,9 @@ using namespace std; constexpr const char *kZygoteInit = "com.android.internal.os.ZygoteInit"; constexpr const char *kZygote = "com/android/internal/os/Zygote"; +constexpr const char *kForkApp = "nativeForkAndSpecialize"; +constexpr const char *kSpecializeApp = "nativeSpecializeAppProcess"; +constexpr const char *kForkServer = "nativeForkSystemServer"; // Global contexts: // @@ -104,11 +106,14 @@ struct HookContext; static HookContext *g_hook; using JNIMethods = std::span; +using JNIMethodsDyn = std::pair, size_t>; struct HookContext { #include "jni_hooks.hpp" - // std::array zygote_methods + // std::array fork_app_methods; + // std::array specialize_app_methods; + // std::array fork_server_methods; vector> plt_backup; const NativeBridgeRuntimeCallbacks *runtime_callbacks = nullptr; void *self_handle = nullptr; @@ -119,11 +124,13 @@ struct HookContext { 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 hook_jni_methods(JNIEnv *env, const char *clz, JNIMethods methods) const; 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); + int hook_jni_methods(JNIEnv *env, jclass clazz, JNIMethods methods) const; + JNIMethodsDyn get_jni_methods(JNIEnv *env, jclass clazz) const; }; // ----------------------------------------------------------------- @@ -452,56 +459,74 @@ void HookContext::restore_plt_hook() { // ----------------------------------------------------------------- -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; - } +JNIMethodsDyn HookContext::get_jni_methods(JNIEnv *env, jclass clazz) const { + size_t total = runtime_callbacks->getNativeMethodCount(env, clazz); + auto methods = std::make_unique_for_overwrite(total); + runtime_callbacks->getNativeMethods(env, clazz, methods.get(), total); + return std::make_pair(std::move(methods), total); +} - // 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); - - // WARNING: the signature field returned from getNativeMethods is in a non-standard format. - // DO NOT TRY TO USE IT. This is the reason why we try to call RegisterNatives on every single - // provided JNI methods directly to be 100% sure about whether a signature matches or not. - - // Replace methods +static void register_jni_methods(JNIEnv *env, jclass clazz, JNIMethods methods) { 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; } } +} + +int HookContext::hook_jni_methods(JNIEnv *env, jclass clazz, JNIMethods methods) const { + // Backup existing methods + auto o = get_jni_methods(env, clazz); + const auto old_methods = span(o.first.get(), o.second); + + // WARNING: the signature field returned from getNativeMethods is in a non-standard format. + // DO NOT TRY TO USE IT. This is the reason why we try to call RegisterNatives on every single + // provided JNI methods directly to be 100% sure about whether a signature matches or not. + + // Replace methods + register_jni_methods(env, clazz, methods); // Fetch the new set of native methods - auto new_methods = std::make_unique_for_overwrite(total); - runtime_callbacks->getNativeMethods(env, clazz, new_methods.get(), total); + auto n = get_jni_methods(env, clazz); + const auto new_methods = span(n.first.get(), n.second); // Find the old function pointer and return to caller + int hook_count = 0; for (auto &method : methods) { if (!method.fnPtr) continue; - for (auto i = 0; i < total; ++i) { - auto &new_method = new_methods[i]; + for (const auto &new_method : new_methods) { if (new_method.fnPtr == method.fnPtr) { - auto &old_method = old_methods[i]; - ZLOGV("replace %s#%s%s %p -> %p\n", clz, method.name, method.signature, old_method.fnPtr, method.fnPtr); - method.fnPtr = old_method.fnPtr; - break; + for (const auto &old_method : old_methods) { + if (strcmp(old_method.name, new_method.name) == 0 && + strcmp(old_method.signature, new_method.signature) == 0) { + ZLOGV("replace %s %s %p -> %p\n", + method.name, method.signature, old_method.fnPtr, method.fnPtr); + method.fnPtr = old_method.fnPtr; + ++hook_count; + // Break 2 levels of for loop + goto next_method; + } + } } } + next_method: } + return hook_count; +} + + +void HookContext::hook_jni_methods(JNIEnv *env, const char *clz, JNIMethods methods) const { + jclass clazz; + if (!runtime_callbacks || !env || !clz || !((clazz = env->FindClass(clz)))) { + ranges::for_each(methods, [](auto &m) { m.fnPtr = nullptr; }); + return; + } + hook_jni_methods(env, clazz, methods); } void HookContext::hook_zygote_jni() { @@ -538,11 +563,54 @@ void HookContext::hook_zygote_jni() { if (res != JNI_OK || env == nullptr) { ZLOGW("JNIEnv not found\n"); } - hook_jni_methods(env, kZygote, zygote_methods); + + JNINativeMethod missing_method{}; + bool replaced_fork_app = false; + bool replaced_specialize_app = false; + bool replaced_fork_server = false; + + jclass clazz = env->FindClass(kZygote); + auto [ptr, count] = get_jni_methods(env, clazz); + for (const auto methods = span(ptr.get(), count); const auto &method : methods) { + if (strcmp(method.name, kForkApp) == 0) { + if (hook_jni_methods(env, clazz, fork_app_methods) == 0) { + missing_method = method; + break; + } + replaced_fork_app = true; + } else if (strcmp(method.name, kSpecializeApp) == 0) { + if (hook_jni_methods(env, clazz, specialize_app_methods) == 0) { + missing_method = method; + break; + } + replaced_specialize_app = true; + } else if (strcmp(method.name, kForkServer) == 0) { + if (hook_jni_methods(env, clazz, fork_server_methods) == 0) { + missing_method = method; + break; + } + replaced_fork_server = true; + } + } + + if (missing_method.name != nullptr) { + ZLOGE("Cannot hook method: %s %s\n", missing_method.name, missing_method.signature); + // Restore methods that were already replaced + if (replaced_fork_app) register_jni_methods(env, clazz, fork_app_methods); + if (replaced_specialize_app) register_jni_methods(env, clazz, specialize_app_methods); + if (replaced_fork_server) register_jni_methods(env, clazz, fork_server_methods); + // Clear the method lists just in case + ranges::for_each(fork_app_methods, [](auto &m) { m.fnPtr = nullptr; }); + ranges::for_each(specialize_app_methods, [](auto &m) { m.fnPtr = nullptr; }); + ranges::for_each(fork_server_methods, [](auto &m) { m.fnPtr = nullptr; }); + } } void HookContext::restore_zygote_hook(JNIEnv *env) { - hook_jni_methods(env, kZygote, zygote_methods); + jclass clazz = env->FindClass(kZygote); + register_jni_methods(env, clazz, fork_app_methods); + register_jni_methods(env, clazz, specialize_app_methods); + register_jni_methods(env, clazz, fork_server_methods); } // ----------------------------------------------------------------- @@ -553,5 +621,5 @@ void hook_entry() { } void hookJniNativeMethods(JNIEnv *env, const char *clz, JNINativeMethod *methods, int numMethods) { - g_hook->hook_jni_methods(env, clz, { methods, (size_t) numMethods }); + g_hook->hook_jni_methods(env, clz, { methods, static_cast(numMethods) }); } diff --git a/native/src/core/zygisk/jni_hooks.hpp b/native/src/core/zygisk/jni_hooks.hpp index d1be01474..801f79aae 100644 --- a/native/src/core/zygisk/jni_hooks.hpp +++ b/native/src/core/zygisk/jni_hooks.hpp @@ -1,6 +1,7 @@ // Generated by gen_jni_hooks.py -std::array zygote_methods = {{ +std::array fork_app_methods = {{ + // nativeForkAndSpecialize_l { "nativeForkAndSpecialize", "(II[II[[IILjava/lang/String;Ljava/lang/String;[ILjava/lang/String;Ljava/lang/String;)I", @@ -8,13 +9,14 @@ 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(g_hook->zygote_methods[0].fnPtr)( + reinterpret_cast(g_hook->fork_app_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(); return ctx.pid; } }, + // nativeForkAndSpecialize_o { "nativeForkAndSpecialize", "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[ILjava/lang/String;Ljava/lang/String;)I", @@ -23,13 +25,14 @@ std::array zygote_methods = {{ args.fds_to_ignore = &fds_to_ignore; ZygiskContext ctx(env, &args); ctx.nativeForkAndSpecialize_pre(); - reinterpret_cast(g_hook->zygote_methods[1].fnPtr)( + reinterpret_cast(g_hook->fork_app_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(); return ctx.pid; } }, + // nativeForkAndSpecialize_p { "nativeForkAndSpecialize", "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;)I", @@ -39,13 +42,14 @@ std::array zygote_methods = {{ args.is_child_zygote = &is_child_zygote; ZygiskContext ctx(env, &args); ctx.nativeForkAndSpecialize_pre(); - reinterpret_cast(g_hook->zygote_methods[2].fnPtr)( + reinterpret_cast(g_hook->fork_app_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(); return ctx.pid; } }, + // nativeForkAndSpecialize_q_alt { "nativeForkAndSpecialize", "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;Z)I", @@ -56,13 +60,14 @@ std::array zygote_methods = {{ args.is_top_app = &is_top_app; ZygiskContext ctx(env, &args); ctx.nativeForkAndSpecialize_pre(); - reinterpret_cast(g_hook->zygote_methods[3].fnPtr)( + reinterpret_cast(g_hook->fork_app_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(); return ctx.pid; } }, + // nativeForkAndSpecialize_r { "nativeForkAndSpecialize", "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;Z[Ljava/lang/String;[Ljava/lang/String;ZZ)I", @@ -77,13 +82,14 @@ std::array zygote_methods = {{ args.mount_storage_dirs = &mount_storage_dirs; ZygiskContext ctx(env, &args); ctx.nativeForkAndSpecialize_pre(); - reinterpret_cast(g_hook->zygote_methods[4].fnPtr)( + reinterpret_cast(g_hook->fork_app_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(); return ctx.pid; } }, + // nativeForkAndSpecialize_u { "nativeForkAndSpecialize", "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;Z[Ljava/lang/String;[Ljava/lang/String;ZZZ)I", @@ -99,13 +105,14 @@ std::array zygote_methods = {{ args.mount_sysprop_overrides = &mount_sysprop_overrides; ZygiskContext ctx(env, &args); ctx.nativeForkAndSpecialize_pre(); - reinterpret_cast(g_hook->zygote_methods[5].fnPtr)( + reinterpret_cast(g_hook->fork_app_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(); return ctx.pid; } }, + // nativeForkAndSpecialize_samsung_m { "nativeForkAndSpecialize", "(II[II[[IILjava/lang/String;IILjava/lang/String;[ILjava/lang/String;Ljava/lang/String;)I", @@ -113,13 +120,14 @@ 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(g_hook->zygote_methods[6].fnPtr)( + reinterpret_cast(g_hook->fork_app_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(); return ctx.pid; } }, + // nativeForkAndSpecialize_samsung_n { "nativeForkAndSpecialize", "(II[II[[IILjava/lang/String;IILjava/lang/String;[ILjava/lang/String;Ljava/lang/String;I)I", @@ -127,13 +135,14 @@ 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(g_hook->zygote_methods[7].fnPtr)( + reinterpret_cast(g_hook->fork_app_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(); return ctx.pid; } }, + // nativeForkAndSpecialize_samsung_o { "nativeForkAndSpecialize", "(II[II[[IILjava/lang/String;IILjava/lang/String;[I[ILjava/lang/String;Ljava/lang/String;)I", @@ -142,13 +151,14 @@ std::array zygote_methods = {{ args.fds_to_ignore = &fds_to_ignore; ZygiskContext ctx(env, &args); ctx.nativeForkAndSpecialize_pre(); - reinterpret_cast(g_hook->zygote_methods[8].fnPtr)( + reinterpret_cast(g_hook->fork_app_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(); return ctx.pid; } }, + // nativeForkAndSpecialize_samsung_p { "nativeForkAndSpecialize", "(II[II[[IILjava/lang/String;IILjava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;)I", @@ -158,13 +168,17 @@ std::array zygote_methods = {{ args.is_child_zygote = &is_child_zygote; ZygiskContext ctx(env, &args); ctx.nativeForkAndSpecialize_pre(); - reinterpret_cast(g_hook->zygote_methods[9].fnPtr)( + reinterpret_cast(g_hook->fork_app_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(); return ctx.pid; } }, +}}; + +std::array specialize_app_methods = {{ + // nativeSpecializeAppProcess_q { "nativeSpecializeAppProcess", "(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;)V", @@ -173,12 +187,13 @@ std::array zygote_methods = {{ args.is_child_zygote = &is_child_zygote; ZygiskContext ctx(env, &args); ctx.nativeSpecializeAppProcess_pre(); - reinterpret_cast(g_hook->zygote_methods[10].fnPtr)( + reinterpret_cast(g_hook->specialize_app_methods[0].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(); } }, + // nativeSpecializeAppProcess_q_alt { "nativeSpecializeAppProcess", "(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;Z)V", @@ -188,12 +203,13 @@ std::array zygote_methods = {{ args.is_top_app = &is_top_app; ZygiskContext ctx(env, &args); ctx.nativeSpecializeAppProcess_pre(); - reinterpret_cast(g_hook->zygote_methods[11].fnPtr)( + reinterpret_cast(g_hook->specialize_app_methods[1].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(); } }, + // nativeSpecializeAppProcess_r { "nativeSpecializeAppProcess", "(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;Z[Ljava/lang/String;[Ljava/lang/String;ZZ)V", @@ -207,12 +223,13 @@ std::array zygote_methods = {{ args.mount_storage_dirs = &mount_storage_dirs; ZygiskContext ctx(env, &args); ctx.nativeSpecializeAppProcess_pre(); - reinterpret_cast(g_hook->zygote_methods[12].fnPtr)( + reinterpret_cast(g_hook->specialize_app_methods[2].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(); } }, + // nativeSpecializeAppProcess_u { "nativeSpecializeAppProcess", "(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;Z[Ljava/lang/String;[Ljava/lang/String;ZZZ)V", @@ -227,12 +244,13 @@ std::array zygote_methods = {{ args.mount_sysprop_overrides = &mount_sysprop_overrides; ZygiskContext ctx(env, &args); ctx.nativeSpecializeAppProcess_pre(); - reinterpret_cast(g_hook->zygote_methods[13].fnPtr)( + reinterpret_cast(g_hook->specialize_app_methods[3].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(); } }, + // nativeSpecializeAppProcess_samsung_q { "nativeSpecializeAppProcess", "(II[II[[IILjava/lang/String;IILjava/lang/String;ZLjava/lang/String;Ljava/lang/String;)V", @@ -241,12 +259,16 @@ std::array zygote_methods = {{ args.is_child_zygote = &is_child_zygote; ZygiskContext ctx(env, &args); ctx.nativeSpecializeAppProcess_pre(); - reinterpret_cast(g_hook->zygote_methods[14].fnPtr)( + reinterpret_cast(g_hook->specialize_app_methods[4].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(); } }, +}}; + +std::array fork_server_methods = {{ + // nativeForkSystemServer_l { "nativeForkSystemServer", "(II[II[[IJJ)I", @@ -254,13 +276,14 @@ 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(g_hook->zygote_methods[15].fnPtr)( + reinterpret_cast(g_hook->fork_server_methods[0].fnPtr)( env, clazz, uid, gid, gids, runtime_flags, rlimits, permitted_capabilities, effective_capabilities ); ctx.nativeForkSystemServer_post(); return ctx.pid; } }, + // nativeForkSystemServer_samsung_q { "nativeForkSystemServer", "(II[IIII[[IJJ)I", @@ -268,7 +291,7 @@ 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(g_hook->zygote_methods[16].fnPtr)( + reinterpret_cast(g_hook->fork_server_methods[1].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 611ddff9a..9c1b8cfb1 100644 --- a/native/src/core/zygisk/zygisk.hpp +++ b/native/src/core/zygisk/zygisk.hpp @@ -19,7 +19,7 @@ #endif // Extreme verbose logging -//#define ZLOGV(...) ZLOGD(__VA_ARGS__) +// #define ZLOGV(...) ZLOGD(__VA_ARGS__) #define ZLOGV(...) (void*)0 void hook_entry();