diff --git a/native/src/zygisk/hook.cpp b/native/src/zygisk/hook.cpp index 50302f6ec..8fd1ec283 100644 --- a/native/src/zygisk/hook.cpp +++ b/native/src/zygisk/hook.cpp @@ -28,6 +28,7 @@ using xstring = jni_hook::string; static void hook_unloader(); static void unhook_functions(); static void hook_jni_env(); +static bool unhook_jni(JNIEnv *env); namespace { @@ -94,7 +95,11 @@ struct HookContext { HookContext(JNIEnv *env, void *args) : env(env), args{args}, process(nullptr), pid(-1), info_flags(0), - hook_info_lock(PTHREAD_MUTEX_INITIALIZER) { g_ctx = this; } + hook_info_lock(PTHREAD_MUTEX_INITIALIZER) { + static bool unloaded = unhook_jni(env); + should_unmap_zygisk = unloaded; + g_ctx = this; + } ~HookContext(); @@ -405,6 +410,7 @@ void HookContext::fork_pre() { // First block SIGCHLD, unblock after original fork is done sigmask(SIG_BLOCK, SIGCHLD); pid = old_fork(); + if (pid != 0 || flags[SKIP_FD_SANITIZATION]) return; @@ -601,28 +607,6 @@ HookContext::~HookContext() { if (!is_child()) return; - should_unmap_zygisk = true; - - // Restore JNIEnv - env->functions = old_functions; - delete new_functions; - - // Unhook JNI methods - for (const auto &[clz, methods] : *jni_hook_list) { - if (!methods.empty() && env->RegisterNatives( - env->FindClass(clz.data()), methods.data(), - static_cast(methods.size())) != 0) { - ZLOGE("Failed to restore JNI hook of class [%s]\n", clz.data()); - should_unmap_zygisk = false; - } - } - delete jni_hook_list; - - // Do NOT call the destructor - operator delete(jni_method_map); - // Directly unmap the whole memory block - jni_hook::memory_block::release(); - // Strip out all API function pointers for (auto &m : modules) { m.clearApi(); @@ -786,6 +770,31 @@ static void unhook_functions() { } } +static bool unhook_jni(JNIEnv *env) { + // Restore JNIEnv + env->functions = old_functions; + delete new_functions; + + bool success = true; + + // Unhook JNI methods + for (const auto &[clz, methods] : *jni_hook_list) { + if (!methods.empty() && env->RegisterNatives( + env->FindClass(clz.data()), methods.data(), + static_cast(methods.size())) != 0) { + ZLOGE("Failed to restore JNI hook of class [%s]\n", clz.data()); + success = false; + } + } + delete jni_hook_list; + + // Do NOT call the destructor + operator delete(jni_method_map); + // Directly unmap the whole memory block + jni_hook::memory_block::release(); + return success; +} + // ----------------------------------------------------------------- static JNINativeMethod *hookAndSaveJNIMethods(const char *, const JNINativeMethod *, int);