Move config manager to Java world
This commit is contained in:
parent
e8b18bcf6a
commit
3fb6a478df
|
|
@ -5,6 +5,7 @@ import android.os.Build;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
|
|
||||||
import com.elderdrivers.riru.common.KeepAll;
|
import com.elderdrivers.riru.common.KeepAll;
|
||||||
|
import com.elderdrivers.riru.xposed.config.ConfigManager;
|
||||||
import com.elderdrivers.riru.xposed.core.HookMethodResolver;
|
import com.elderdrivers.riru.xposed.core.HookMethodResolver;
|
||||||
import com.elderdrivers.riru.xposed.dexmaker.DynamicBridge;
|
import com.elderdrivers.riru.xposed.dexmaker.DynamicBridge;
|
||||||
import com.elderdrivers.riru.xposed.entry.Router;
|
import com.elderdrivers.riru.xposed.entry.Router;
|
||||||
|
|
@ -20,13 +21,6 @@ public class Main implements KeepAll {
|
||||||
|
|
||||||
public static String appDataDir = "";
|
public static String appDataDir = "";
|
||||||
public static String appProcessName = "";
|
public static String appProcessName = "";
|
||||||
/**
|
|
||||||
* When set to true, install bootstrap hooks and loadModules
|
|
||||||
* for each process when it starts.
|
|
||||||
* This means you can deactivate or activate every module
|
|
||||||
* for the process you restart without rebooting.
|
|
||||||
*/
|
|
||||||
public static boolean isDynamicModules = false;
|
|
||||||
private static String forkAndSpecializePramsStr = "";
|
private static String forkAndSpecializePramsStr = "";
|
||||||
private static String forkSystemServerPramsStr = "";
|
private static String forkSystemServerPramsStr = "";
|
||||||
|
|
||||||
|
|
@ -43,7 +37,7 @@ 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 isDynamicModules) {
|
String appDataDir) {
|
||||||
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)",
|
||||||
|
|
@ -52,7 +46,6 @@ public class Main implements KeepAll {
|
||||||
Arrays.toString(fdsToIgnore), startChildZygote, instructionSet, appDataDir);
|
Arrays.toString(fdsToIgnore), startChildZygote, instructionSet, appDataDir);
|
||||||
}
|
}
|
||||||
Main.appDataDir = appDataDir;
|
Main.appDataDir = appDataDir;
|
||||||
Main.isDynamicModules = isDynamicModules;
|
|
||||||
Router.prepare(false);
|
Router.prepare(false);
|
||||||
// install bootstrap hooks for secondary zygote
|
// install bootstrap hooks for secondary zygote
|
||||||
Router.installBootstrapHooks(false);
|
Router.installBootstrapHooks(false);
|
||||||
|
|
@ -63,9 +56,10 @@ public class Main implements KeepAll {
|
||||||
public static void forkAndSpecializePost(int pid, String appDataDir) {
|
public static void forkAndSpecializePost(int pid, String appDataDir) {
|
||||||
if (pid == 0) {
|
if (pid == 0) {
|
||||||
Utils.logD(forkAndSpecializePramsStr + " = " + Process.myPid());
|
Utils.logD(forkAndSpecializePramsStr + " = " + Process.myPid());
|
||||||
|
// TODO consider processes without forkAndSpecializePost called
|
||||||
Router.onEnterChildProcess();
|
Router.onEnterChildProcess();
|
||||||
DynamicBridge.onForkPost();
|
DynamicBridge.onForkPost();
|
||||||
if (isDynamicModules) {
|
if (ConfigManager.isDynamicModulesMode()) {
|
||||||
// load modules for each app process on its forked
|
// load modules for each app process on its forked
|
||||||
Router.loadModulesSafely();
|
Router.loadModulesSafely();
|
||||||
}
|
}
|
||||||
|
|
@ -76,15 +70,13 @@ 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 isDynamicModules) {
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
Main.appDataDir = getDataPathPrefix() + "android";
|
Main.appDataDir = getDataPathPrefix() + "android";
|
||||||
Main.isDynamicModules = isDynamicModules;
|
|
||||||
Router.prepare(true);
|
Router.prepare(true);
|
||||||
// install bootstrap hooks for main zygote as early as possible
|
// install bootstrap hooks for main zygote as early as possible
|
||||||
// in case we miss some processes not forked via forkAndSpecialize
|
// in case we miss some processes not forked via forkAndSpecialize
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
package com.elderdrivers.riru.xposed.config;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import de.robv.android.xposed.SELinuxHelper;
|
||||||
|
import de.robv.android.xposed.XposedInit;
|
||||||
|
|
||||||
|
import static de.robv.android.xposed.XposedInit.INSTALLER_PACKAGE_NAME;
|
||||||
|
|
||||||
|
public class ConfigManager {
|
||||||
|
|
||||||
|
private static final String BLACK_LIST_PATH = XposedInit.INSTALLER_DATA_BASE_DIR + "conf/blacklist/";
|
||||||
|
private static final String WHITE_LIST_PATH = XposedInit.INSTALLER_DATA_BASE_DIR + "conf/whitelist/";
|
||||||
|
private static final String COMPAT_LIST_PATH = XposedInit.INSTALLER_DATA_BASE_DIR + "conf/compatlist/";
|
||||||
|
private static final String USE_WHITE_LIST = XposedInit.INSTALLER_DATA_BASE_DIR + "conf/usewhitelist";
|
||||||
|
private static final String DYNAMIC_MODULES = XposedInit.INSTALLER_DATA_BASE_DIR + "conf/dynamicmodules";
|
||||||
|
private static final Set<String> WHITE_LIST = Collections.singleton(INSTALLER_PACKAGE_NAME);
|
||||||
|
private static final boolean IS_DYNAMIC_MODULES;
|
||||||
|
|
||||||
|
static {
|
||||||
|
IS_DYNAMIC_MODULES = isFileExists(DYNAMIC_MODULES);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isDynamicModulesMode() {
|
||||||
|
return IS_DYNAMIC_MODULES;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean shouldUseWhitelist() {
|
||||||
|
return isFileExists(USE_WHITE_LIST);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean shouldUseCompatMode(String packageName) {
|
||||||
|
return isFileExists(COMPAT_LIST_PATH + packageName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean shouldHook(String packageName) {
|
||||||
|
if (WHITE_LIST.contains(packageName)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (shouldUseWhitelist()) {
|
||||||
|
return isFileExists(WHITE_LIST_PATH + packageName);
|
||||||
|
} else {
|
||||||
|
return !isFileExists(BLACK_LIST_PATH + packageName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isFileExists(String path) {
|
||||||
|
return SELinuxHelper.getAppDataFileService().checkFileExists(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,6 +5,7 @@ import android.os.Build;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import com.elderdrivers.riru.xposed.Main;
|
import com.elderdrivers.riru.xposed.Main;
|
||||||
|
import com.elderdrivers.riru.xposed.config.ConfigManager;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
@ -17,7 +18,6 @@ import external.com.android.dx.TypeId;
|
||||||
public class DexMakerUtils {
|
public class DexMakerUtils {
|
||||||
|
|
||||||
private static final boolean IN_MEMORY_DEX_ELIGIBLE = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
|
private static final boolean IN_MEMORY_DEX_ELIGIBLE = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
|
||||||
private static final String COMPAT_LIST_PATH = "/data/misc/riru/modules/edxposed/compatlist/";
|
|
||||||
|
|
||||||
public static boolean shouldUseInMemoryHook() {
|
public static boolean shouldUseInMemoryHook() {
|
||||||
if (!IN_MEMORY_DEX_ELIGIBLE) {
|
if (!IN_MEMORY_DEX_ELIGIBLE) {
|
||||||
|
|
@ -29,7 +29,7 @@ public class DexMakerUtils {
|
||||||
+ ", appDataDir=" + Main.appDataDir);
|
+ ", appDataDir=" + Main.appDataDir);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return !SELinuxHelper.getAppDataFileService().checkFileExists(COMPAT_LIST_PATH + packageName);
|
return !ConfigManager.shouldUseCompatMode(packageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void autoBoxIfNecessary(Code code, Local<Object> target, Local source) {
|
public static void autoBoxIfNecessary(Code code, Local<Object> target, Local source) {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
package com.elderdrivers.riru.xposed.entry;
|
package com.elderdrivers.riru.xposed.entry;
|
||||||
|
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import com.elderdrivers.riru.xposed.Main;
|
||||||
|
import com.elderdrivers.riru.xposed.config.ConfigManager;
|
||||||
import com.elderdrivers.riru.xposed.core.HookMain;
|
import com.elderdrivers.riru.xposed.core.HookMain;
|
||||||
import com.elderdrivers.riru.xposed.entry.bootstrap.AppBootstrapHookInfo;
|
import com.elderdrivers.riru.xposed.entry.bootstrap.AppBootstrapHookInfo;
|
||||||
import com.elderdrivers.riru.xposed.entry.bootstrap.SysBootstrapHookInfo;
|
import com.elderdrivers.riru.xposed.entry.bootstrap.SysBootstrapHookInfo;
|
||||||
|
|
@ -19,6 +23,22 @@ public class Router {
|
||||||
XposedInit.startsSystemServer = isSystem;
|
XposedInit.startsSystemServer = isSystem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void checkHookState(String appDataDir) {
|
||||||
|
// determine whether allow xposed or not
|
||||||
|
// XposedBridge.disableHooks = ConfigManager.shouldHook(parsePackageName(appDataDir));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String parsePackageName(String appDataDir) {
|
||||||
|
if (TextUtils.isEmpty(appDataDir)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
int lastIndex = appDataDir.lastIndexOf("/");
|
||||||
|
if (lastIndex < 1) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return appDataDir.substring(lastIndex + 1);
|
||||||
|
}
|
||||||
|
|
||||||
public static void installBootstrapHooks(boolean isSystem) {
|
public static void installBootstrapHooks(boolean isSystem) {
|
||||||
// Initialize the Xposed framework
|
// Initialize the Xposed framework
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import android.util.Log;
|
||||||
|
|
||||||
import com.android.internal.os.ZygoteInit;
|
import com.android.internal.os.ZygoteInit;
|
||||||
import com.elderdrivers.riru.xposed.BuildConfig;
|
import com.elderdrivers.riru.xposed.BuildConfig;
|
||||||
import com.elderdrivers.riru.xposed.Main;
|
import com.elderdrivers.riru.xposed.config.ConfigManager;
|
||||||
import com.elderdrivers.riru.xposed.entry.Router;
|
import com.elderdrivers.riru.xposed.entry.Router;
|
||||||
import com.elderdrivers.riru.xposed.util.Utils;
|
import com.elderdrivers.riru.xposed.util.Utils;
|
||||||
|
|
||||||
|
|
@ -94,7 +94,8 @@ public final class XposedInit {
|
||||||
private static volatile AtomicBoolean modulesLoaded = new AtomicBoolean(false);
|
private static volatile AtomicBoolean modulesLoaded = new AtomicBoolean(false);
|
||||||
|
|
||||||
public static void loadModules() throws IOException {
|
public static void loadModules() throws IOException {
|
||||||
if (!modulesLoaded.compareAndSet(false, true) && !Main.isDynamicModules) {
|
if (!modulesLoaded.compareAndSet(false, true)
|
||||||
|
&& !ConfigManager.isDynamicModulesMode()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
XposedBridge.clearLoadedPackages();
|
XposedBridge.clearLoadedPackages();
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ LOCAL_SRC_FILES:= \
|
||||||
yahfa/HookMain.c \
|
yahfa/HookMain.c \
|
||||||
yahfa/trampoline.c \
|
yahfa/trampoline.c \
|
||||||
java_hook/java_hook.cpp \
|
java_hook/java_hook.cpp \
|
||||||
inject/framework_hook.cpp \
|
inject/framework_hook.cpp
|
||||||
inject/config_manager.cpp
|
|
||||||
|
|
||||||
include $(BUILD_SHARED_LIBRARY)
|
include $(BUILD_SHARED_LIBRARY)
|
||||||
|
|
@ -1,77 +0,0 @@
|
||||||
//
|
|
||||||
// Created by Solo on 2019/1/27.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <jni.h>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <array>
|
|
||||||
#include <thread>
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
|
||||||
#include <include/logging.h>
|
|
||||||
#include "config_manager.h"
|
|
||||||
|
|
||||||
#define BLACK_LIST_PATH "/data/misc/riru/modules/edxposed/blacklist/"
|
|
||||||
#define WHITE_LIST_PATH "/data/misc/riru/modules/edxposed/whitelist/"
|
|
||||||
#define USE_WHITE_LIST "/data/misc/riru/modules/edxposed/usewhitelist"
|
|
||||||
#define GLOBAL_MODE "/data/misc/riru/modules/edxposed/forceglobal"
|
|
||||||
#define DYNAMIC_MODULES "/data/misc/riru/modules/edxposed/dynamicmodules"
|
|
||||||
|
|
||||||
static char package_name[256];
|
|
||||||
static bool dynamic_modules = false;
|
|
||||||
static bool inited = false;
|
|
||||||
|
|
||||||
void initOnce() {
|
|
||||||
if (!inited) {
|
|
||||||
dynamic_modules = access(DYNAMIC_MODULES, F_OK) == 0;
|
|
||||||
inited = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// default is true
|
|
||||||
int is_app_need_hook(JNIEnv *env, jstring appDataDir) {
|
|
||||||
if (!appDataDir) {
|
|
||||||
LOGW("appDataDir is null");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
const char *app_data_dir = env->GetStringUTFChars(appDataDir, nullptr);
|
|
||||||
int user = 0;
|
|
||||||
if (sscanf(app_data_dir, "/data/%*[^/]/%d/%s", &user, package_name) != 2) {
|
|
||||||
if (sscanf(app_data_dir, "/data/%*[^/]/%s", package_name) != 1) {
|
|
||||||
package_name[0] = '\0';
|
|
||||||
LOGW("can't parse %s", app_data_dir);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
env->ReleaseStringUTFChars(appDataDir, app_data_dir);
|
|
||||||
if (strcmp(package_name, "com.solohsu.android.edxp.manager") == 0) {
|
|
||||||
// always hook installer app
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
bool use_white_list = access(USE_WHITE_LIST, F_OK) == 0;
|
|
||||||
bool white_list_exists = access(WHITE_LIST_PATH, F_OK) == 0;
|
|
||||||
bool black_list_exists = access(BLACK_LIST_PATH, F_OK) == 0;
|
|
||||||
if (use_white_list && white_list_exists) {
|
|
||||||
char path[PATH_MAX];
|
|
||||||
snprintf(path, PATH_MAX, WHITE_LIST_PATH "%s", package_name);
|
|
||||||
int res = access(path, F_OK) == 0;
|
|
||||||
LOGD("use whitelist, res=%d", res);
|
|
||||||
return res;
|
|
||||||
} else if (!use_white_list && black_list_exists) {
|
|
||||||
char path[PATH_MAX];
|
|
||||||
snprintf(path, PATH_MAX, BLACK_LIST_PATH "%s", package_name);
|
|
||||||
int res = access(path, F_OK) != 0;
|
|
||||||
LOGD("use blacklist, res=%d", res);
|
|
||||||
return res;
|
|
||||||
} else {
|
|
||||||
LOGD("use nonlist, res=%d", 1);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_dynamic_modules() {
|
|
||||||
initOnce();
|
|
||||||
return dynamic_modules;
|
|
||||||
}
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
//
|
|
||||||
// Created by Solo on 2019/1/27.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef EDXPOSED_CONFIG_MANAGER_H
|
|
||||||
#define EDXPOSED_CONFIG_MANAGER_H
|
|
||||||
|
|
||||||
int is_app_need_hook(JNIEnv *env, jstring appDataDir);
|
|
||||||
|
|
||||||
bool is_dynamic_modules();
|
|
||||||
|
|
||||||
#endif //EDXPOSED_CONFIG_MANAGER_H
|
|
||||||
|
|
@ -5,7 +5,6 @@
|
||||||
#include <include/logging.h>
|
#include <include/logging.h>
|
||||||
#include "framework_hook.h"
|
#include "framework_hook.h"
|
||||||
#include "include/misc.h"
|
#include "include/misc.h"
|
||||||
#include "config_manager.h"
|
|
||||||
|
|
||||||
#define SYSTEM_SERVER_DATA_DIR "/data/user/0/android"
|
#define SYSTEM_SERVER_DATA_DIR "/data/user/0/android"
|
||||||
|
|
||||||
|
|
@ -42,21 +41,15 @@ void onNativeForkSystemServerPre(JNIEnv *env, jclass clazz, uid_t uid, gid_t gid
|
||||||
jint runtime_flags, jobjectArray rlimits,
|
jint runtime_flags, jobjectArray rlimits,
|
||||||
jlong permittedCapabilities, jlong effectiveCapabilities) {
|
jlong permittedCapabilities, jlong effectiveCapabilities) {
|
||||||
sAppDataDir = env->NewStringUTF(SYSTEM_SERVER_DATA_DIR);
|
sAppDataDir = env->NewStringUTF(SYSTEM_SERVER_DATA_DIR);
|
||||||
if (!is_app_need_hook(env, sAppDataDir)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
prepareJavaEnv(env);
|
prepareJavaEnv(env);
|
||||||
// jump to java code
|
// jump to java code
|
||||||
findAndCall(env, "forkSystemServerPre", "(II[II[[IJJZ)V", uid, gid, gids, runtime_flags, rlimits,
|
findAndCall(env, "forkSystemServerPre", "(II[II[[IJJ)V", uid, gid, gids, runtime_flags, rlimits,
|
||||||
permittedCapabilities, effectiveCapabilities, is_dynamic_modules());
|
permittedCapabilities, effectiveCapabilities);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int onNativeForkSystemServerPost(JNIEnv *env, jclass clazz, jint res) {
|
int onNativeForkSystemServerPost(JNIEnv *env, jclass clazz, jint res) {
|
||||||
if (res == 0) {
|
if (res == 0) {
|
||||||
if (!is_app_need_hook(env, sAppDataDir)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
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", "(I)V", res);
|
findAndCall(env, "forkSystemServerPost", "(I)V", res);
|
||||||
|
|
@ -81,22 +74,16 @@ void onNativeForkAndSpecializePre(JNIEnv *env, jclass clazz,
|
||||||
jstring instructionSet,
|
jstring instructionSet,
|
||||||
jstring appDataDir) {
|
jstring appDataDir) {
|
||||||
sAppDataDir = appDataDir;
|
sAppDataDir = appDataDir;
|
||||||
if (!is_app_need_hook(env, appDataDir)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
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;Z)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_dynamic_modules());
|
is_child_zygote, instructionSet, appDataDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
int onNativeForkAndSpecializePost(JNIEnv *env, jclass clazz, jint res) {
|
int onNativeForkAndSpecializePost(JNIEnv *env, jclass clazz, jint res) {
|
||||||
if (res == 0) {
|
if (res == 0) {
|
||||||
if (!is_app_need_hook(env, sAppDataDir)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
prepareJavaEnv(env);
|
prepareJavaEnv(env);
|
||||||
findAndCall(env, "forkAndSpecializePost", "(ILjava/lang/String;)V", res, sAppDataDir);
|
findAndCall(env, "forkAndSpecializePost", "(ILjava/lang/String;)V", res, sAppDataDir);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue