Use native methods instead of parameters passing

This commit is contained in:
solohsu 2019-02-28 20:08:03 +08:00
parent 2ac5eb19c9
commit 37bf64a1ee
5 changed files with 48 additions and 45 deletions

View File

@ -34,36 +34,32 @@ public class Main implements KeepAll {
int[][] rlimits, int mountExternal, String seInfo, int[][] rlimits, int mountExternal, String seInfo,
String niceName, int[] fdsToClose, int[] fdsToIgnore, String niceName, int[] fdsToClose, int[] fdsToIgnore,
boolean startChildZygote, String instructionSet, boolean startChildZygote, String instructionSet,
String appDataDir, boolean isBlackWhiteListMode, String appDataDir) {
boolean isDynamicModulesMode) {
if (BuildConfig.DEBUG) { if (BuildConfig.DEBUG) {
forkAndSpecializePramsStr = String.format( forkAndSpecializePramsStr = String.format(
"Zygote#forkAndSpecialize(%d, %d, %s, %d, %s, %d, %s, %s, %s, %s, %s, %s, %s)", "Zygote#forkAndSpecialize(%d, %d, %s, %d, %s, %d, %s, %s, %s, %s, %s, %s, %s)",
uid, gid, Arrays.toString(gids), debugFlags, Arrays.toString(rlimits), uid, gid, Arrays.toString(gids), debugFlags, Arrays.toString(rlimits),
mountExternal, seInfo, niceName, Arrays.toString(fdsToClose), mountExternal, seInfo, niceName, Arrays.toString(fdsToClose),
Arrays.toString(fdsToIgnore), startChildZygote, instructionSet, appDataDir, Arrays.toString(fdsToIgnore), startChildZygote, instructionSet, appDataDir);
isDynamicModulesMode);
} }
if (isBlackWhiteListMode) { if (isBlackWhiteListEnabled()) {
BlackWhiteListProxy.forkAndSpecializePre(uid, gid, gids, debugFlags, rlimits, BlackWhiteListProxy.forkAndSpecializePre(uid, gid, gids, debugFlags, rlimits,
mountExternal, seInfo, niceName, fdsToClose, fdsToIgnore, startChildZygote, mountExternal, seInfo, niceName, fdsToClose, fdsToIgnore, startChildZygote,
instructionSet, appDataDir, isDynamicModulesMode); instructionSet, appDataDir);
} else { } else {
NormalProxy.forkAndSpecializePre(uid, gid, gids, debugFlags, rlimits, mountExternal, NormalProxy.forkAndSpecializePre(uid, gid, gids, debugFlags, rlimits, mountExternal,
seInfo, niceName, fdsToClose, fdsToIgnore, startChildZygote, instructionSet, seInfo, niceName, fdsToClose, fdsToIgnore, startChildZygote, instructionSet,
appDataDir, isDynamicModulesMode); appDataDir);
} }
} }
public static void forkAndSpecializePost(int pid, String appDataDir, public static void forkAndSpecializePost(int pid, String appDataDir) {
boolean isBlackWhiteListMode,
boolean isDynamicModulesMode) {
if (pid == 0) { if (pid == 0) {
Utils.logD(forkAndSpecializePramsStr + " = " + Process.myPid()); Utils.logD(forkAndSpecializePramsStr + " = " + Process.myPid());
if (isBlackWhiteListMode) { if (isBlackWhiteListEnabled()) {
BlackWhiteListProxy.forkAndSpecializePost(pid, appDataDir, isDynamicModulesMode); BlackWhiteListProxy.forkAndSpecializePost(pid, appDataDir);
} else { } else {
NormalProxy.forkAndSpecializePost(pid, appDataDir, isDynamicModulesMode); NormalProxy.forkAndSpecializePost(pid, appDataDir);
} }
} else { } else {
// in zygote process, res is child zygote pid // in zygote process, res is child zygote pid
@ -72,30 +68,28 @@ public class Main implements KeepAll {
} }
public static void forkSystemServerPre(int uid, int gid, int[] gids, int debugFlags, int[][] rlimits, public static void forkSystemServerPre(int uid, int gid, int[] gids, int debugFlags, int[][] rlimits,
long permittedCapabilities, long effectiveCapabilities, long permittedCapabilities, long effectiveCapabilities) {
boolean isBlackWhiteListMode, boolean isDynamicModulesMode) {
if (BuildConfig.DEBUG) { if (BuildConfig.DEBUG) {
forkSystemServerPramsStr = String.format("Zygote#forkSystemServer(%d, %d, %s, %d, %s, %d, %d)", forkSystemServerPramsStr = String.format("Zygote#forkSystemServer(%d, %d, %s, %d, %s, %d, %d)",
uid, gid, Arrays.toString(gids), debugFlags, Arrays.toString(rlimits), uid, gid, Arrays.toString(gids), debugFlags, Arrays.toString(rlimits),
permittedCapabilities, effectiveCapabilities); permittedCapabilities, effectiveCapabilities);
} }
if (isBlackWhiteListMode) { if (isBlackWhiteListEnabled()) {
BlackWhiteListProxy.forkSystemServerPre(uid, gid, gids, debugFlags, rlimits, BlackWhiteListProxy.forkSystemServerPre(uid, gid, gids, debugFlags, rlimits,
permittedCapabilities, effectiveCapabilities, isDynamicModulesMode); permittedCapabilities, effectiveCapabilities);
} else { } else {
NormalProxy.forkSystemServerPre(uid, gid, gids, debugFlags, rlimits, NormalProxy.forkSystemServerPre(uid, gid, gids, debugFlags, rlimits,
permittedCapabilities, effectiveCapabilities, isDynamicModulesMode); permittedCapabilities, effectiveCapabilities);
} }
} }
public static void forkSystemServerPost(int pid, boolean isBlackWhiteListMode, public static void forkSystemServerPost(int pid) {
boolean isDynamicModulesMode) {
if (pid == 0) { if (pid == 0) {
Utils.logD(forkSystemServerPramsStr + " = " + Process.myPid()); Utils.logD(forkSystemServerPramsStr + " = " + Process.myPid());
if (isBlackWhiteListMode) { if (isBlackWhiteListEnabled()) {
BlackWhiteListProxy.forkSystemServerPost(pid, isDynamicModulesMode); BlackWhiteListProxy.forkSystemServerPost(pid);
} else { } else {
NormalProxy.forkSystemServerPost(pid, isDynamicModulesMode); NormalProxy.forkSystemServerPost(pid);
} }
} else { } else {
// in zygote process, res is child zygote pid // in zygote process, res is child zygote pid
@ -118,6 +112,10 @@ public class Main implements KeepAll {
public static native String getInstallerPkgName(); public static native String getInstallerPkgName();
public static native boolean isBlackWhiteListEnabled();
public static native boolean isDynamicModulesEnabled();
// prevent from fatal error caused by holding not whitelisted file descriptors when forking zygote // prevent from fatal error caused by holding not whitelisted file descriptors when forking zygote
// https://github.com/rovo89/Xposed/commit/b3ba245ad04cd485699fb1d2ebde7117e58214ff // https://github.com/rovo89/Xposed/commit/b3ba245ad04cd485699fb1d2ebde7117e58214ff
public static native void closeFilesBeforeForkNative(); public static native void closeFilesBeforeForkNative();

View File

@ -12,7 +12,8 @@ public class BlackWhiteListProxy {
int[][] rlimits, int mountExternal, String seInfo, int[][] rlimits, int mountExternal, String seInfo,
String niceName, int[] fdsToClose, int[] fdsToIgnore, String niceName, int[] fdsToClose, int[] fdsToIgnore,
boolean startChildZygote, String instructionSet, boolean startChildZygote, String instructionSet,
String appDataDir, boolean isDynamicModulesMode) { String appDataDir) {
final boolean isDynamicModulesMode = Main.isDynamicModulesEnabled();
ConfigManager.setDynamicModulesMode(isDynamicModulesMode); ConfigManager.setDynamicModulesMode(isDynamicModulesMode);
if (!isDynamicModulesMode) { if (!isDynamicModulesMode) {
Router.loadModulesSafely(); Router.loadModulesSafely();
@ -20,8 +21,8 @@ public class BlackWhiteListProxy {
} }
} }
public static void forkAndSpecializePost(int pid, String appDataDir, public static void forkAndSpecializePost(int pid, String appDataDir) {
boolean isDynamicModulesMode) { final boolean isDynamicModulesMode = Main.isDynamicModulesEnabled();
if (!isDynamicModulesMode) { if (!isDynamicModulesMode) {
Main.reopenFilesAfterForkNative(); Main.reopenFilesAfterForkNative();
} }
@ -34,8 +35,8 @@ public class BlackWhiteListProxy {
public static void forkSystemServerPre(int uid, int gid, int[] gids, int debugFlags, public static void forkSystemServerPre(int uid, int gid, int[] gids, int debugFlags,
int[][] rlimits, long permittedCapabilities, int[][] rlimits, long permittedCapabilities,
long effectiveCapabilities, long effectiveCapabilities) {
boolean isDynamicModulesMode) { final boolean isDynamicModulesMode = Main.isDynamicModulesEnabled();
ConfigManager.setDynamicModulesMode(isDynamicModulesMode); ConfigManager.setDynamicModulesMode(isDynamicModulesMode);
if (!isDynamicModulesMode) { if (!isDynamicModulesMode) {
Router.loadModulesSafely(); Router.loadModulesSafely();
@ -43,7 +44,8 @@ public class BlackWhiteListProxy {
} }
} }
public static void forkSystemServerPost(int pid, boolean isDynamicModulesMode) { public static void forkSystemServerPost(int pid) {
final boolean isDynamicModulesMode = Main.isDynamicModulesEnabled();
if (!isDynamicModulesMode) { if (!isDynamicModulesMode) {
Main.reopenFilesAfterForkNative(); Main.reopenFilesAfterForkNative();
} }

View File

@ -13,7 +13,8 @@ public class NormalProxy {
int[][] rlimits, int mountExternal, String seInfo, int[][] rlimits, int mountExternal, String seInfo,
String niceName, int[] fdsToClose, int[] fdsToIgnore, String niceName, int[] fdsToClose, int[] fdsToIgnore,
boolean startChildZygote, String instructionSet, boolean startChildZygote, String instructionSet,
String appDataDir, boolean isDynamicModulesMode) { String appDataDir) {
final boolean isDynamicModulesMode = Main.isDynamicModulesEnabled();
Main.appDataDir = appDataDir; Main.appDataDir = appDataDir;
ConfigManager.setDynamicModulesMode(isDynamicModulesMode); ConfigManager.setDynamicModulesMode(isDynamicModulesMode);
Router.prepare(false); Router.prepare(false);
@ -24,7 +25,7 @@ public class NormalProxy {
Main.closeFilesBeforeForkNative(); Main.closeFilesBeforeForkNative();
} }
public static void forkAndSpecializePost(int pid, String appDataDir, boolean isDynamicModulesMode) { public static void forkAndSpecializePost(int pid, String appDataDir) {
// TODO consider processes without forkAndSpecializePost called // TODO consider processes without forkAndSpecializePost called
Main.reopenFilesAfterForkNative(); Main.reopenFilesAfterForkNative();
Router.onEnterChildProcess(); Router.onEnterChildProcess();
@ -34,8 +35,8 @@ public class NormalProxy {
} }
public static void forkSystemServerPre(int uid, int gid, int[] gids, int debugFlags, int[][] rlimits, public static void forkSystemServerPre(int uid, int gid, int[] gids, int debugFlags, int[][] rlimits,
long permittedCapabilities, long effectiveCapabilities, long permittedCapabilities, long effectiveCapabilities) {
boolean isDynamicModulesMode) { final boolean isDynamicModulesMode = Main.isDynamicModulesEnabled();
Main.appDataDir = getDataPathPrefix() + "android"; Main.appDataDir = getDataPathPrefix() + "android";
ConfigManager.setDynamicModulesMode(isDynamicModulesMode); ConfigManager.setDynamicModulesMode(isDynamicModulesMode);
Router.prepare(true); Router.prepare(true);
@ -50,7 +51,7 @@ public class NormalProxy {
Main.closeFilesBeforeForkNative(); Main.closeFilesBeforeForkNative();
} }
public static void forkSystemServerPost(int pid, boolean isDynamicModulesMode) { public static void forkSystemServerPost(int pid) {
// in system_server process // in system_server process
Main.reopenFilesAfterForkNative(); Main.reopenFilesAfterForkNative();
Router.onEnterChildProcess(); Router.onEnterChildProcess();

View File

@ -50,9 +50,8 @@ void onNativeForkSystemServerPre(JNIEnv *env, jclass clazz, uid_t uid, gid_t gid
} }
prepareJavaEnv(env); prepareJavaEnv(env);
// jump to java code // jump to java code
findAndCall(env, "forkSystemServerPre", "(II[II[[IJJZZ)V", uid, gid, gids, runtime_flags, findAndCall(env, "forkSystemServerPre", "(II[II[[IJJ)V", uid, gid, gids, runtime_flags,
rlimits, permittedCapabilities, effectiveCapabilities, rlimits, permittedCapabilities, effectiveCapabilities);
is_black_white_list_mode, is_dynamic_modules_mode);
} }
@ -63,8 +62,7 @@ int onNativeForkSystemServerPost(JNIEnv *env, jclass clazz, jint res) {
} }
prepareJavaEnv(env); prepareJavaEnv(env);
// only do work in child since findAndCall would print log // only do work in child since findAndCall would print log
findAndCall(env, "forkSystemServerPost", "(IZZ)V", res, findAndCall(env, "forkSystemServerPost", "(I)V", res);
is_black_white_list_enabled(), is_dynamic_modules_enabled());
} else { } else {
// in zygote process, res is child zygote pid // in zygote process, res is child zygote pid
// don't print log here, see https://github.com/RikkaApps/Riru/blob/77adfd6a4a6a81bfd20569c910bc4854f2f84f5e/riru-core/jni/main/jni_native_method.cpp#L55-L66 // don't print log here, see https://github.com/RikkaApps/Riru/blob/77adfd6a4a6a81bfd20569c910bc4854f2f84f5e/riru-core/jni/main/jni_native_method.cpp#L55-L66
@ -94,11 +92,10 @@ void onNativeForkAndSpecializePre(JNIEnv *env, jclass clazz,
} }
prepareJavaEnv(env); prepareJavaEnv(env);
findAndCall(env, "forkAndSpecializePre", findAndCall(env, "forkAndSpecializePre",
"(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;ZZ)V", "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;)V",
uid, gid, gids, runtime_flags, rlimits, uid, gid, gids, runtime_flags, rlimits,
_mount_external, se_info, se_name, fdsToClose, fdsToIgnore, _mount_external, se_info, se_name, fdsToClose, fdsToIgnore,
is_child_zygote, instructionSet, appDataDir, is_child_zygote, instructionSet, appDataDir);
is_black_white_list_mode, is_dynamic_modules_mode);
} }
int onNativeForkAndSpecializePost(JNIEnv *env, jclass clazz, jint res) { int onNativeForkAndSpecializePost(JNIEnv *env, jclass clazz, jint res) {
@ -107,8 +104,7 @@ int onNativeForkAndSpecializePost(JNIEnv *env, jclass clazz, jint res) {
return 0; return 0;
} }
prepareJavaEnv(env); prepareJavaEnv(env);
findAndCall(env, "forkAndSpecializePost", "(ILjava/lang/String;ZZ)V", res, sAppDataDir, findAndCall(env, "forkAndSpecializePost", "(ILjava/lang/String;)V", res, sAppDataDir);
is_black_white_list_enabled(), is_dynamic_modules_enabled());
} else { } else {
// in zygote process, res is child zygote pid // in zygote process, res is child zygote pid
// don't print log here, see https://github.com/RikkaApps/Riru/blob/77adfd6a4a6a81bfd20569c910bc4854f2f84f5e/riru-core/jni/main/jni_native_method.cpp#L55-L66 // don't print log here, see https://github.com/RikkaApps/Riru/blob/77adfd6a4a6a81bfd20569c910bc4854f2f84f5e/riru-core/jni/main/jni_native_method.cpp#L55-L66

View File

@ -73,6 +73,12 @@ static JNINativeMethod hookMethods[] = {
"(Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;)V", "(Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;)V",
(void *) Java_lab_galaxy_yahfa_HookMain_ensureMethodCached (void *) Java_lab_galaxy_yahfa_HookMain_ensureMethodCached
}, },
{
"isBlackWhiteListEnabled", "()Z", (void *) is_black_white_list_enabled
},
{
"isDynamicModulesEnabled", "()Z", (void *) is_dynamic_modules_enabled
},
{ {
"getInstallerPkgName", "()Ljava/lang/String;", (void *) get_installer_pkg_name "getInstallerPkgName", "()Ljava/lang/String;", (void *) get_installer_pkg_name
}, },
@ -128,7 +134,7 @@ void loadDexAndInit(JNIEnv *env, const char *dexPath) {
jclass entry_class = findClassFromLoader(env, myClassLoader, ENTRY_CLASS_NAME); jclass entry_class = findClassFromLoader(env, myClassLoader, ENTRY_CLASS_NAME);
if (NULL != entry_class) { if (NULL != entry_class) {
LOGD("HookEntry Class %p", entry_class); LOGD("HookEntry Class %p", entry_class);
env->RegisterNatives(entry_class, hookMethods, 10); env->RegisterNatives(entry_class, hookMethods, 12);
isInited = true; isInited = true;
LOGD("RegisterNatives succeed for HookEntry."); LOGD("RegisterNatives succeed for HookEntry.");
} else { } else {