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.
This commit is contained in:
topjohnwu
2025-12-06 20:01:43 -08:00
committed by John Wu
parent 9cc830c565
commit a510554b21
4 changed files with 159 additions and 64 deletions

View File

@@ -65,8 +65,8 @@ class JNIHook(Method):
def base_name(self): def base_name(self):
return '' return ''
def orig_method(self, name, i): def orig_method(self, field, i):
return f'reinterpret_cast<{self.ret.type.cpp}(*)(JNIEnv *env, jclass clazz, {self.cpp()})>(g_hook->{name}_methods[{i}].fnPtr)' return f'reinterpret_cast<{self.ret.type.cpp}(*)(JNIEnv *env, jclass clazz, {self.cpp()})>(g_hook->{field}[{i}].fnPtr)'
def ind(i): def ind(i):
return '\n' + ' ' * i return '\n' + ' ' * i
@@ -89,7 +89,7 @@ class ForkAndSpec(JNIHook):
def init_args(self): 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);' 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 = ''
decl += ind(3) + self.init_args() decl += ind(3) + self.init_args()
for a in self.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) + f'args.{a.name} = &{a.name};'
decl += ind(3) + 'ZygiskContext ctx(env, &args);' decl += ind(3) + 'ZygiskContext ctx(env, &args);'
decl += ind(3) + f'ctx.{self.base_name()}_pre();' 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(4) + f'env, clazz, {self.name_list()}'
decl += ind(3) + ');' decl += ind(3) + ');'
decl += ind(3) + f'ctx.{self.base_name()}_post();' 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, server_samsung_q = ForkServer('samsung_q', [uid, gid, gids, runtime_flags, Anon(jint), Anon(jint), rlimits,
permitted_capabilities, effective_capabilities]) permitted_capabilities, effective_capabilities])
def gen_jni_def(name, methods): def gen_jni_def(field, methods):
decl = '' decl = ''
decl += ind(0) + f'std::array<JNINativeMethod, {len(methods)}> {name}_methods = {{{{' decl += ind(0) + f'std::array<JNINativeMethod, {len(methods)}> {field} = {{{{'
for i, m in enumerate(methods): for i, m in enumerate(methods):
decl += ind(1) + f'// {m.name}'
decl += ind(1) + '{' decl += ind(1) + '{'
decl += ind(2) + f'"{m.base_name()}",' decl += ind(2) + f'"{m.base_name()}",'
decl += ind(2) + f'"{m.jni()}",' 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 += 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: if m.ret.value:
decl += ind(3) + f'return {m.ret.value};' decl += ind(3) + f'return {m.ret.value};'
decl += ind(2) + '}' decl += ind(2) + '}'
@@ -231,8 +232,11 @@ def gen_jni_def(name, methods):
with open('jni_hooks.hpp', 'w') as f: with open('jni_hooks.hpp', 'w') as f:
f.write('// Generated by gen_jni_hooks.py\n') f.write('// Generated by gen_jni_hooks.py\n')
f.write(gen_jni_def('zygote', [ 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_l, fas_o, fas_p, fas_q_alt, fas_r, fas_u, fas_samsung_m, fas_samsung_n, fas_samsung_o, fas_samsung_p]))
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('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') f.write('\n')

View File

@@ -8,7 +8,6 @@
#include <lsplt.hpp> #include <lsplt.hpp>
#include <base.hpp> #include <base.hpp>
#include <consts.hpp>
#include "zygisk.hpp" #include "zygisk.hpp"
#include "module.hpp" #include "module.hpp"
@@ -90,6 +89,9 @@ using namespace std;
constexpr const char *kZygoteInit = "com.android.internal.os.ZygoteInit"; constexpr const char *kZygoteInit = "com.android.internal.os.ZygoteInit";
constexpr const char *kZygote = "com/android/internal/os/Zygote"; 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: // Global contexts:
// //
@@ -104,11 +106,14 @@ struct HookContext;
static HookContext *g_hook; static HookContext *g_hook;
using JNIMethods = std::span<JNINativeMethod>; using JNIMethods = std::span<JNINativeMethod>;
using JNIMethodsDyn = std::pair<unique_ptr<JNINativeMethod[]>, size_t>;
struct HookContext { struct HookContext {
#include "jni_hooks.hpp" #include "jni_hooks.hpp"
// std::array<JNINativeMethod> zygote_methods // std::array<JNINativeMethod> fork_app_methods;
// std::array<JNINativeMethod> specialize_app_methods;
// std::array<JNINativeMethod> fork_server_methods;
vector<tuple<dev_t, ino_t, const char *, void **>> plt_backup; vector<tuple<dev_t, ino_t, const char *, void **>> plt_backup;
const NativeBridgeRuntimeCallbacks *runtime_callbacks = nullptr; const NativeBridgeRuntimeCallbacks *runtime_callbacks = nullptr;
void *self_handle = nullptr; void *self_handle = nullptr;
@@ -119,11 +124,13 @@ struct HookContext {
void restore_plt_hook(); void restore_plt_hook();
void hook_zygote_jni(); void hook_zygote_jni();
void restore_zygote_hook(JNIEnv *env); 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); void post_native_bridge_load(void *handle);
private: private:
void register_hook(dev_t dev, ino_t inode, const char *symbol, void *new_func, void **old_func); 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) { JNIMethodsDyn HookContext::get_jni_methods(JNIEnv *env, jclass clazz) const {
jclass clazz; size_t total = runtime_callbacks->getNativeMethodCount(env, clazz);
if (!runtime_callbacks || !env || !clz || !(clazz = env->FindClass(clz))) { auto methods = std::make_unique_for_overwrite<JNINativeMethod[]>(total);
for (auto &method : methods) { runtime_callbacks->getNativeMethods(env, clazz, methods.get(), total);
method.fnPtr = nullptr; return std::make_pair(std::move(methods), total);
} }
return;
}
// Backup existing methods static void register_jni_methods(JNIEnv *env, jclass clazz, JNIMethods methods) {
auto total = runtime_callbacks->getNativeMethodCount(env, clazz);
auto old_methods = std::make_unique_for_overwrite<JNINativeMethod[]>(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
for (auto &method : methods) { for (auto &method : methods) {
// It's useful to allow nullptr function pointer for restoring hook // It's useful to allow nullptr function pointer for restoring hook
if (!method.fnPtr) continue; if (!method.fnPtr) continue;
// It's normal that the method is not found // It's normal that the method is not found
if (env->RegisterNatives(clazz, &method, 1) == JNI_ERR || env->ExceptionCheck() == JNI_TRUE) { if (env->RegisterNatives(clazz, &method, 1) == JNI_ERR || env->ExceptionCheck() == JNI_TRUE) {
if (auto exception = env->ExceptionOccurred()) {
env->DeleteLocalRef(exception);
}
env->ExceptionClear(); env->ExceptionClear();
method.fnPtr = nullptr; 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 // Fetch the new set of native methods
auto new_methods = std::make_unique_for_overwrite<JNINativeMethod[]>(total); auto n = get_jni_methods(env, clazz);
runtime_callbacks->getNativeMethods(env, clazz, new_methods.get(), total); const auto new_methods = span(n.first.get(), n.second);
// Find the old function pointer and return to caller // Find the old function pointer and return to caller
int hook_count = 0;
for (auto &method : methods) { for (auto &method : methods) {
if (!method.fnPtr) continue; if (!method.fnPtr) continue;
for (auto i = 0; i < total; ++i) { for (const auto &new_method : new_methods) {
auto &new_method = new_methods[i];
if (new_method.fnPtr == method.fnPtr) { if (new_method.fnPtr == method.fnPtr) {
auto &old_method = old_methods[i]; for (const auto &old_method : old_methods) {
ZLOGV("replace %s#%s%s %p -> %p\n", clz, method.name, method.signature, old_method.fnPtr, method.fnPtr); if (strcmp(old_method.name, new_method.name) == 0 &&
method.fnPtr = old_method.fnPtr; strcmp(old_method.signature, new_method.signature) == 0) {
break; 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() { void HookContext::hook_zygote_jni() {
@@ -538,11 +563,54 @@ void HookContext::hook_zygote_jni() {
if (res != JNI_OK || env == nullptr) { if (res != JNI_OK || env == nullptr) {
ZLOGW("JNIEnv not found\n"); 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) { 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) { 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<size_t>(numMethods) });
} }

View File

@@ -1,6 +1,7 @@
// Generated by gen_jni_hooks.py // Generated by gen_jni_hooks.py
std::array<JNINativeMethod, 17> zygote_methods = {{ std::array<JNINativeMethod, 10> fork_app_methods = {{
// nativeForkAndSpecialize_l
{ {
"nativeForkAndSpecialize", "nativeForkAndSpecialize",
"(II[II[[IILjava/lang/String;Ljava/lang/String;[ILjava/lang/String;Ljava/lang/String;)I", "(II[II[[IILjava/lang/String;Ljava/lang/String;[ILjava/lang/String;Ljava/lang/String;)I",
@@ -8,13 +9,14 @@ std::array<JNINativeMethod, 17> zygote_methods = {{
AppSpecializeArgs_v5 args(uid, gid, gids, runtime_flags, rlimits, mount_external, se_info, nice_name, instruction_set, app_data_dir); AppSpecializeArgs_v5 args(uid, gid, gids, runtime_flags, rlimits, mount_external, se_info, nice_name, instruction_set, app_data_dir);
ZygiskContext ctx(env, &args); ZygiskContext ctx(env, &args);
ctx.nativeForkAndSpecialize_pre(); ctx.nativeForkAndSpecialize_pre();
reinterpret_cast<jint(*)(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)>(g_hook->zygote_methods[0].fnPtr)( reinterpret_cast<jint(*)(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)>(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 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(); ctx.nativeForkAndSpecialize_post();
return ctx.pid; return ctx.pid;
} }
}, },
// nativeForkAndSpecialize_o
{ {
"nativeForkAndSpecialize", "nativeForkAndSpecialize",
"(II[II[[IILjava/lang/String;Ljava/lang/String;[I[ILjava/lang/String;Ljava/lang/String;)I", "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[ILjava/lang/String;Ljava/lang/String;)I",
@@ -23,13 +25,14 @@ std::array<JNINativeMethod, 17> zygote_methods = {{
args.fds_to_ignore = &fds_to_ignore; args.fds_to_ignore = &fds_to_ignore;
ZygiskContext ctx(env, &args); ZygiskContext ctx(env, &args);
ctx.nativeForkAndSpecialize_pre(); ctx.nativeForkAndSpecialize_pre();
reinterpret_cast<jint(*)(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)>(g_hook->zygote_methods[1].fnPtr)( reinterpret_cast<jint(*)(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)>(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 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(); ctx.nativeForkAndSpecialize_post();
return ctx.pid; return ctx.pid;
} }
}, },
// nativeForkAndSpecialize_p
{ {
"nativeForkAndSpecialize", "nativeForkAndSpecialize",
"(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;)I", "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;)I",
@@ -39,13 +42,14 @@ std::array<JNINativeMethod, 17> zygote_methods = {{
args.is_child_zygote = &is_child_zygote; args.is_child_zygote = &is_child_zygote;
ZygiskContext ctx(env, &args); ZygiskContext ctx(env, &args);
ctx.nativeForkAndSpecialize_pre(); ctx.nativeForkAndSpecialize_pre();
reinterpret_cast<jint(*)(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)>(g_hook->zygote_methods[2].fnPtr)( reinterpret_cast<jint(*)(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)>(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 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(); ctx.nativeForkAndSpecialize_post();
return ctx.pid; return ctx.pid;
} }
}, },
// nativeForkAndSpecialize_q_alt
{ {
"nativeForkAndSpecialize", "nativeForkAndSpecialize",
"(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;Z)I", "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;Z)I",
@@ -56,13 +60,14 @@ std::array<JNINativeMethod, 17> zygote_methods = {{
args.is_top_app = &is_top_app; args.is_top_app = &is_top_app;
ZygiskContext ctx(env, &args); ZygiskContext ctx(env, &args);
ctx.nativeForkAndSpecialize_pre(); ctx.nativeForkAndSpecialize_pre();
reinterpret_cast<jint(*)(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)>(g_hook->zygote_methods[3].fnPtr)( reinterpret_cast<jint(*)(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)>(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 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(); ctx.nativeForkAndSpecialize_post();
return ctx.pid; return ctx.pid;
} }
}, },
// nativeForkAndSpecialize_r
{ {
"nativeForkAndSpecialize", "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", "(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<JNINativeMethod, 17> zygote_methods = {{
args.mount_storage_dirs = &mount_storage_dirs; args.mount_storage_dirs = &mount_storage_dirs;
ZygiskContext ctx(env, &args); ZygiskContext ctx(env, &args);
ctx.nativeForkAndSpecialize_pre(); ctx.nativeForkAndSpecialize_pre();
reinterpret_cast<jint(*)(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)>(g_hook->zygote_methods[4].fnPtr)( reinterpret_cast<jint(*)(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)>(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 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(); ctx.nativeForkAndSpecialize_post();
return ctx.pid; return ctx.pid;
} }
}, },
// nativeForkAndSpecialize_u
{ {
"nativeForkAndSpecialize", "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", "(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<JNINativeMethod, 17> zygote_methods = {{
args.mount_sysprop_overrides = &mount_sysprop_overrides; args.mount_sysprop_overrides = &mount_sysprop_overrides;
ZygiskContext ctx(env, &args); ZygiskContext ctx(env, &args);
ctx.nativeForkAndSpecialize_pre(); ctx.nativeForkAndSpecialize_pre();
reinterpret_cast<jint(*)(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, jboolean mount_sysprop_overrides)>(g_hook->zygote_methods[5].fnPtr)( reinterpret_cast<jint(*)(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, jboolean mount_sysprop_overrides)>(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 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(); ctx.nativeForkAndSpecialize_post();
return ctx.pid; return ctx.pid;
} }
}, },
// nativeForkAndSpecialize_samsung_m
{ {
"nativeForkAndSpecialize", "nativeForkAndSpecialize",
"(II[II[[IILjava/lang/String;IILjava/lang/String;[ILjava/lang/String;Ljava/lang/String;)I", "(II[II[[IILjava/lang/String;IILjava/lang/String;[ILjava/lang/String;Ljava/lang/String;)I",
@@ -113,13 +120,14 @@ std::array<JNINativeMethod, 17> zygote_methods = {{
AppSpecializeArgs_v5 args(uid, gid, gids, runtime_flags, rlimits, mount_external, se_info, nice_name, instruction_set, app_data_dir); AppSpecializeArgs_v5 args(uid, gid, gids, runtime_flags, rlimits, mount_external, se_info, nice_name, instruction_set, app_data_dir);
ZygiskContext ctx(env, &args); ZygiskContext ctx(env, &args);
ctx.nativeForkAndSpecialize_pre(); ctx.nativeForkAndSpecialize_pre();
reinterpret_cast<jint(*)(JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, jint mount_external, jstring se_info, jint _0, jint _1, jstring nice_name, jintArray fds_to_close, jstring instruction_set, jstring app_data_dir)>(g_hook->zygote_methods[6].fnPtr)( reinterpret_cast<jint(*)(JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, jint mount_external, jstring se_info, jint _0, jint _1, jstring nice_name, jintArray fds_to_close, jstring instruction_set, jstring app_data_dir)>(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 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(); ctx.nativeForkAndSpecialize_post();
return ctx.pid; return ctx.pid;
} }
}, },
// nativeForkAndSpecialize_samsung_n
{ {
"nativeForkAndSpecialize", "nativeForkAndSpecialize",
"(II[II[[IILjava/lang/String;IILjava/lang/String;[ILjava/lang/String;Ljava/lang/String;I)I", "(II[II[[IILjava/lang/String;IILjava/lang/String;[ILjava/lang/String;Ljava/lang/String;I)I",
@@ -127,13 +135,14 @@ std::array<JNINativeMethod, 17> zygote_methods = {{
AppSpecializeArgs_v5 args(uid, gid, gids, runtime_flags, rlimits, mount_external, se_info, nice_name, instruction_set, app_data_dir); AppSpecializeArgs_v5 args(uid, gid, gids, runtime_flags, rlimits, mount_external, se_info, nice_name, instruction_set, app_data_dir);
ZygiskContext ctx(env, &args); ZygiskContext ctx(env, &args);
ctx.nativeForkAndSpecialize_pre(); ctx.nativeForkAndSpecialize_pre();
reinterpret_cast<jint(*)(JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, jint mount_external, jstring se_info, jint _2, jint _3, jstring nice_name, jintArray fds_to_close, jstring instruction_set, jstring app_data_dir, jint _4)>(g_hook->zygote_methods[7].fnPtr)( reinterpret_cast<jint(*)(JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, jint mount_external, jstring se_info, jint _2, jint _3, jstring nice_name, jintArray fds_to_close, jstring instruction_set, jstring app_data_dir, jint _4)>(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 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(); ctx.nativeForkAndSpecialize_post();
return ctx.pid; return ctx.pid;
} }
}, },
// nativeForkAndSpecialize_samsung_o
{ {
"nativeForkAndSpecialize", "nativeForkAndSpecialize",
"(II[II[[IILjava/lang/String;IILjava/lang/String;[I[ILjava/lang/String;Ljava/lang/String;)I", "(II[II[[IILjava/lang/String;IILjava/lang/String;[I[ILjava/lang/String;Ljava/lang/String;)I",
@@ -142,13 +151,14 @@ std::array<JNINativeMethod, 17> zygote_methods = {{
args.fds_to_ignore = &fds_to_ignore; args.fds_to_ignore = &fds_to_ignore;
ZygiskContext ctx(env, &args); ZygiskContext ctx(env, &args);
ctx.nativeForkAndSpecialize_pre(); ctx.nativeForkAndSpecialize_pre();
reinterpret_cast<jint(*)(JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, jint mount_external, jstring se_info, jint _5, jint _6, jstring nice_name, jintArray fds_to_close, jintArray fds_to_ignore, jstring instruction_set, jstring app_data_dir)>(g_hook->zygote_methods[8].fnPtr)( reinterpret_cast<jint(*)(JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, jint mount_external, jstring se_info, jint _5, jint _6, jstring nice_name, jintArray fds_to_close, jintArray fds_to_ignore, jstring instruction_set, jstring app_data_dir)>(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 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(); ctx.nativeForkAndSpecialize_post();
return ctx.pid; return ctx.pid;
} }
}, },
// nativeForkAndSpecialize_samsung_p
{ {
"nativeForkAndSpecialize", "nativeForkAndSpecialize",
"(II[II[[IILjava/lang/String;IILjava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;)I", "(II[II[[IILjava/lang/String;IILjava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;)I",
@@ -158,13 +168,17 @@ std::array<JNINativeMethod, 17> zygote_methods = {{
args.is_child_zygote = &is_child_zygote; args.is_child_zygote = &is_child_zygote;
ZygiskContext ctx(env, &args); ZygiskContext ctx(env, &args);
ctx.nativeForkAndSpecialize_pre(); ctx.nativeForkAndSpecialize_pre();
reinterpret_cast<jint(*)(JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, jint mount_external, jstring se_info, jint _7, jint _8, jstring nice_name, jintArray fds_to_close, jintArray fds_to_ignore, jboolean is_child_zygote, jstring instruction_set, jstring app_data_dir)>(g_hook->zygote_methods[9].fnPtr)( reinterpret_cast<jint(*)(JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, jint mount_external, jstring se_info, jint _7, jint _8, jstring nice_name, jintArray fds_to_close, jintArray fds_to_ignore, jboolean is_child_zygote, jstring instruction_set, jstring app_data_dir)>(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 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(); ctx.nativeForkAndSpecialize_post();
return ctx.pid; return ctx.pid;
} }
}, },
}};
std::array<JNINativeMethod, 5> specialize_app_methods = {{
// nativeSpecializeAppProcess_q
{ {
"nativeSpecializeAppProcess", "nativeSpecializeAppProcess",
"(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;)V", "(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;)V",
@@ -173,12 +187,13 @@ std::array<JNINativeMethod, 17> zygote_methods = {{
args.is_child_zygote = &is_child_zygote; args.is_child_zygote = &is_child_zygote;
ZygiskContext ctx(env, &args); ZygiskContext ctx(env, &args);
ctx.nativeSpecializeAppProcess_pre(); ctx.nativeSpecializeAppProcess_pre();
reinterpret_cast<void(*)(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)>(g_hook->zygote_methods[10].fnPtr)( reinterpret_cast<void(*)(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)>(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 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(); ctx.nativeSpecializeAppProcess_post();
} }
}, },
// nativeSpecializeAppProcess_q_alt
{ {
"nativeSpecializeAppProcess", "nativeSpecializeAppProcess",
"(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;Z)V", "(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;Z)V",
@@ -188,12 +203,13 @@ std::array<JNINativeMethod, 17> zygote_methods = {{
args.is_top_app = &is_top_app; args.is_top_app = &is_top_app;
ZygiskContext ctx(env, &args); ZygiskContext ctx(env, &args);
ctx.nativeSpecializeAppProcess_pre(); ctx.nativeSpecializeAppProcess_pre();
reinterpret_cast<void(*)(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)>(g_hook->zygote_methods[11].fnPtr)( reinterpret_cast<void(*)(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)>(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 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(); ctx.nativeSpecializeAppProcess_post();
} }
}, },
// nativeSpecializeAppProcess_r
{ {
"nativeSpecializeAppProcess", "nativeSpecializeAppProcess",
"(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;Z[Ljava/lang/String;[Ljava/lang/String;ZZ)V", "(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<JNINativeMethod, 17> zygote_methods = {{
args.mount_storage_dirs = &mount_storage_dirs; args.mount_storage_dirs = &mount_storage_dirs;
ZygiskContext ctx(env, &args); ZygiskContext ctx(env, &args);
ctx.nativeSpecializeAppProcess_pre(); ctx.nativeSpecializeAppProcess_pre();
reinterpret_cast<void(*)(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)>(g_hook->zygote_methods[12].fnPtr)( reinterpret_cast<void(*)(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)>(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 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(); ctx.nativeSpecializeAppProcess_post();
} }
}, },
// nativeSpecializeAppProcess_u
{ {
"nativeSpecializeAppProcess", "nativeSpecializeAppProcess",
"(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;Z[Ljava/lang/String;[Ljava/lang/String;ZZZ)V", "(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<JNINativeMethod, 17> zygote_methods = {{
args.mount_sysprop_overrides = &mount_sysprop_overrides; args.mount_sysprop_overrides = &mount_sysprop_overrides;
ZygiskContext ctx(env, &args); ZygiskContext ctx(env, &args);
ctx.nativeSpecializeAppProcess_pre(); ctx.nativeSpecializeAppProcess_pre();
reinterpret_cast<void(*)(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, jboolean mount_sysprop_overrides)>(g_hook->zygote_methods[13].fnPtr)( reinterpret_cast<void(*)(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, jboolean mount_sysprop_overrides)>(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 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(); ctx.nativeSpecializeAppProcess_post();
} }
}, },
// nativeSpecializeAppProcess_samsung_q
{ {
"nativeSpecializeAppProcess", "nativeSpecializeAppProcess",
"(II[II[[IILjava/lang/String;IILjava/lang/String;ZLjava/lang/String;Ljava/lang/String;)V", "(II[II[[IILjava/lang/String;IILjava/lang/String;ZLjava/lang/String;Ljava/lang/String;)V",
@@ -241,12 +259,16 @@ std::array<JNINativeMethod, 17> zygote_methods = {{
args.is_child_zygote = &is_child_zygote; args.is_child_zygote = &is_child_zygote;
ZygiskContext ctx(env, &args); ZygiskContext ctx(env, &args);
ctx.nativeSpecializeAppProcess_pre(); ctx.nativeSpecializeAppProcess_pre();
reinterpret_cast<void(*)(JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, jint mount_external, jstring se_info, jint _9, jint _10, jstring nice_name, jboolean is_child_zygote, jstring instruction_set, jstring app_data_dir)>(g_hook->zygote_methods[14].fnPtr)( reinterpret_cast<void(*)(JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, jint mount_external, jstring se_info, jint _9, jint _10, jstring nice_name, jboolean is_child_zygote, jstring instruction_set, jstring app_data_dir)>(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 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(); ctx.nativeSpecializeAppProcess_post();
} }
}, },
}};
std::array<JNINativeMethod, 2> fork_server_methods = {{
// nativeForkSystemServer_l
{ {
"nativeForkSystemServer", "nativeForkSystemServer",
"(II[II[[IJJ)I", "(II[II[[IJJ)I",
@@ -254,13 +276,14 @@ std::array<JNINativeMethod, 17> zygote_methods = {{
ServerSpecializeArgs_v1 args(uid, gid, gids, runtime_flags, permitted_capabilities, effective_capabilities); ServerSpecializeArgs_v1 args(uid, gid, gids, runtime_flags, permitted_capabilities, effective_capabilities);
ZygiskContext ctx(env, &args); ZygiskContext ctx(env, &args);
ctx.nativeForkSystemServer_pre(); ctx.nativeForkSystemServer_pre();
reinterpret_cast<jint(*)(JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, jlong permitted_capabilities, jlong effective_capabilities)>(g_hook->zygote_methods[15].fnPtr)( reinterpret_cast<jint(*)(JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, jlong permitted_capabilities, jlong effective_capabilities)>(g_hook->fork_server_methods[0].fnPtr)(
env, clazz, uid, gid, gids, runtime_flags, rlimits, permitted_capabilities, effective_capabilities env, clazz, uid, gid, gids, runtime_flags, rlimits, permitted_capabilities, effective_capabilities
); );
ctx.nativeForkSystemServer_post(); ctx.nativeForkSystemServer_post();
return ctx.pid; return ctx.pid;
} }
}, },
// nativeForkSystemServer_samsung_q
{ {
"nativeForkSystemServer", "nativeForkSystemServer",
"(II[IIII[[IJJ)I", "(II[IIII[[IJJ)I",
@@ -268,7 +291,7 @@ std::array<JNINativeMethod, 17> zygote_methods = {{
ServerSpecializeArgs_v1 args(uid, gid, gids, runtime_flags, permitted_capabilities, effective_capabilities); ServerSpecializeArgs_v1 args(uid, gid, gids, runtime_flags, permitted_capabilities, effective_capabilities);
ZygiskContext ctx(env, &args); ZygiskContext ctx(env, &args);
ctx.nativeForkSystemServer_pre(); ctx.nativeForkSystemServer_pre();
reinterpret_cast<jint(*)(JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint runtime_flags, jint _11, jint _12, jobjectArray rlimits, jlong permitted_capabilities, jlong effective_capabilities)>(g_hook->zygote_methods[16].fnPtr)( reinterpret_cast<jint(*)(JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint runtime_flags, jint _11, jint _12, jobjectArray rlimits, jlong permitted_capabilities, jlong effective_capabilities)>(g_hook->fork_server_methods[1].fnPtr)(
env, clazz, uid, gid, gids, runtime_flags, _11, _12, rlimits, permitted_capabilities, effective_capabilities env, clazz, uid, gid, gids, runtime_flags, _11, _12, rlimits, permitted_capabilities, effective_capabilities
); );
ctx.nativeForkSystemServer_post(); ctx.nativeForkSystemServer_post();

View File

@@ -19,7 +19,7 @@
#endif #endif
// Extreme verbose logging // Extreme verbose logging
//#define ZLOGV(...) ZLOGD(__VA_ARGS__) // #define ZLOGV(...) ZLOGD(__VA_ARGS__)
#define ZLOGV(...) (void*)0 #define ZLOGV(...) (void*)0
void hook_entry(); void hook_entry();