Fix dynamic modules is always enabled when black/white list mode is on

This commit is contained in:
solohsu 2019-02-24 20:46:20 +08:00
parent 367c4eb8ab
commit f473834c7b
8 changed files with 107 additions and 49 deletions

View File

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

View File

@ -1,7 +1,5 @@
package com.elderdrivers.riru.xposed.config;
import com.elderdrivers.riru.xposed.util.Utils;
import java.util.Collections;
import java.util.Set;
@ -18,11 +16,12 @@ public class ConfigManager {
private static final String USE_WHITE_LIST = INSTALLER_DATA_BASE_DIR + "conf/usewhitelist";
private static final String DYNAMIC_MODULES = 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;
private static volatile boolean IS_DYNAMIC_MODULES = false;
static {
IS_DYNAMIC_MODULES = isFileExists(DYNAMIC_MODULES);
Utils.logI("using dynamic modules mode: " + IS_DYNAMIC_MODULES);
public static synchronized void setDynamicModulesMode(boolean isDynamicModulesMode) {
if (isDynamicModulesMode != IS_DYNAMIC_MODULES) {
IS_DYNAMIC_MODULES = isDynamicModulesMode;
}
}
public static boolean isDynamicModulesMode() {

View File

@ -1,6 +1,7 @@
package com.elderdrivers.riru.xposed.proxy.yahfa;
import com.elderdrivers.riru.xposed.Main;
import com.elderdrivers.riru.xposed.config.ConfigManager;
import com.elderdrivers.riru.xposed.entry.Router;
import static com.elderdrivers.riru.xposed.util.FileUtils.getDataPathPrefix;
@ -11,23 +12,43 @@ public class BlackWhiteListProxy {
int[][] rlimits, int mountExternal, String seInfo,
String niceName, int[] fdsToClose, int[] fdsToIgnore,
boolean startChildZygote, String instructionSet,
String appDataDir) {
String appDataDir, boolean isDynamicModulesMode) {
ConfigManager.setDynamicModulesMode(isDynamicModulesMode);
if (!isDynamicModulesMode) {
Router.loadModulesSafely();
Main.closeFilesBeforeForkNative();
}
}
public static void forkAndSpecializePost(int pid, String appDataDir) {
public static void forkAndSpecializePost(int pid, String appDataDir,
boolean isDynamicModulesMode) {
if (!isDynamicModulesMode) {
Main.reopenFilesAfterForkNative();
}
Main.appDataDir = appDataDir;
ConfigManager.setDynamicModulesMode(isDynamicModulesMode);
Router.prepare(false);
Router.installBootstrapHooks(false);
Router.loadModulesSafely();
}
public static void forkSystemServerPre(int uid, int gid, int[] gids, int debugFlags, int[][] rlimits,
long permittedCapabilities, long effectiveCapabilities) {
public static void forkSystemServerPre(int uid, int gid, int[] gids, int debugFlags,
int[][] rlimits, long permittedCapabilities,
long effectiveCapabilities,
boolean isDynamicModulesMode) {
ConfigManager.setDynamicModulesMode(isDynamicModulesMode);
if (!isDynamicModulesMode) {
Router.loadModulesSafely();
Main.closeFilesBeforeForkNative();
}
}
public static void forkSystemServerPost(int pid) {
public static void forkSystemServerPost(int pid, boolean isDynamicModulesMode) {
if (!isDynamicModulesMode) {
Main.reopenFilesAfterForkNative();
}
Main.appDataDir = getDataPathPrefix() + "android";
ConfigManager.setDynamicModulesMode(isDynamicModulesMode);
Router.prepare(true);
Router.installBootstrapHooks(true);
Router.loadModulesSafely();

View File

@ -13,8 +13,9 @@ public class NormalProxy {
int[][] rlimits, int mountExternal, String seInfo,
String niceName, int[] fdsToClose, int[] fdsToIgnore,
boolean startChildZygote, String instructionSet,
String appDataDir) {
String appDataDir, boolean isDynamicModulesMode) {
Main.appDataDir = appDataDir;
ConfigManager.setDynamicModulesMode(isDynamicModulesMode);
Router.prepare(false);
// install bootstrap hooks for secondary zygote
Router.installBootstrapHooks(false);
@ -23,20 +24,20 @@ public class NormalProxy {
Main.closeFilesBeforeForkNative();
}
public static void forkAndSpecializePost(int pid, String appDataDir) {
public static void forkAndSpecializePost(int pid, String appDataDir, boolean isDynamicModulesMode) {
// TODO consider processes without forkAndSpecializePost called
Main.reopenFilesAfterForkNative();
Router.onEnterChildProcess();
DynamicBridge.onForkPost();
if (ConfigManager.isDynamicModulesMode()) {
// load modules for each app process on its forked
Router.loadModulesSafely();
}
// load modules for each app process on its forked if dynamic modules mode is on
Router.loadModulesSafely();
}
public static void forkSystemServerPre(int uid, int gid, int[] gids, int debugFlags, int[][] rlimits,
long permittedCapabilities, long effectiveCapabilities) {
long permittedCapabilities, long effectiveCapabilities,
boolean isDynamicModulesMode) {
Main.appDataDir = getDataPathPrefix() + "android";
ConfigManager.setDynamicModulesMode(isDynamicModulesMode);
Router.prepare(true);
// install bootstrap hooks for main zygote as early as possible
// in case we miss some processes not forked via forkAndSpecialize
@ -49,7 +50,7 @@ public class NormalProxy {
Main.closeFilesBeforeForkNative();
}
public static void forkSystemServerPost(int pid) {
public static void forkSystemServerPost(int pid, boolean isDynamicModulesMode) {
// in system_server process
Main.reopenFilesAfterForkNative();
Router.onEnterChildProcess();

View File

@ -30,6 +30,7 @@ static char dynamic_modules_path[PATH_MAX];
static const char *installer_package_name;
static bool black_white_list_enabled = false;
static bool dynamic_modules_enabled = false;
static bool inited = false;
static const char *get_installer_package_name() {
@ -71,8 +72,10 @@ static void init_once() {
installer_package_name, "blackwhitelist");
snprintf(dynamic_modules_path, PATH_MAX, config_path_tpl, data_path_prefix,
installer_package_name, "dynamicmodules");
dynamic_modules_enabled = access(dynamic_modules_path, F_OK) == 0;
black_white_list_enabled = access(black_white_list_path, F_OK) == 0;
LOGI("black/white list mode: %d", black_white_list_enabled);
LOGI("dynamic modules mode: %d", dynamic_modules_enabled);
inited = true;
}
}
@ -85,7 +88,6 @@ bool is_app_need_hook(JNIEnv *env, jstring appDataDir) {
return true;
}
bool use_white_list = access(use_whitelist_path, F_OK) == 0;
LOGI("using %s list mode", use_white_list ? "white" : "black");
if (!appDataDir) {
LOGE("appDataDir is null");
return !use_white_list;
@ -129,6 +131,11 @@ bool is_black_white_list_enabled() {
return black_white_list_enabled;
}
bool is_dynamic_modules_enabled() {
init_once();
return dynamic_modules_enabled;
}
jstring get_installer_pkg_name(JNIEnv *env) {
init_once();
return env->NewStringUTF(installer_package_name);

View File

@ -9,6 +9,8 @@ bool is_app_need_hook(JNIEnv *env, jstring appDataDir);
bool is_black_white_list_enabled();
bool is_dynamic_modules_enabled();
jstring get_installer_pkg_name(JNIEnv *env);
#endif //EDXPOSED_CONFIG_MANAGER_H

View File

@ -42,14 +42,17 @@ void onNativeForkSystemServerPre(JNIEnv *env, jclass clazz, uid_t uid, gid_t gid
jint runtime_flags, jobjectArray rlimits,
jlong permittedCapabilities, jlong effectiveCapabilities) {
sAppDataDir = env->NewStringUTF(SYSTEM_SERVER_DATA_DIR);
if (is_black_white_list_enabled()) {
// when black/white list is on, never inject into zygote
bool is_black_white_list_mode = is_black_white_list_enabled();
bool is_dynamic_modules_mode = is_dynamic_modules_enabled();
if (is_black_white_list_mode && is_dynamic_modules_mode) {
// when black/white list is on, never inject into zygote if dynamic modules mode is on
return;
}
prepareJavaEnv(env);
// jump to java code
findAndCall(env, "forkSystemServerPre", "(II[II[[IJJ)V", uid, gid, gids, runtime_flags, rlimits,
permittedCapabilities, effectiveCapabilities);
findAndCall(env, "forkSystemServerPre", "(II[II[[IJJZZ)V", uid, gid, gids, runtime_flags,
rlimits, permittedCapabilities, effectiveCapabilities,
is_black_white_list_mode, is_dynamic_modules_mode);
}
@ -60,7 +63,8 @@ int onNativeForkSystemServerPost(JNIEnv *env, jclass clazz, jint res) {
}
prepareJavaEnv(env);
// only do work in child since findAndCall would print log
findAndCall(env, "forkSystemServerPost", "(IZ)V", res, is_black_white_list_enabled());
findAndCall(env, "forkSystemServerPost", "(IZZ)V", res,
is_black_white_list_enabled(), is_dynamic_modules_enabled());
} else {
// 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
@ -82,16 +86,19 @@ void onNativeForkAndSpecializePre(JNIEnv *env, jclass clazz,
jstring instructionSet,
jstring appDataDir) {
sAppDataDir = appDataDir;
if (is_black_white_list_enabled()) {
// when black/white list is on, never inject into zygote
bool is_black_white_list_mode = is_black_white_list_enabled();
bool is_dynamic_modules_mode = is_dynamic_modules_enabled();
if (is_black_white_list_mode && is_dynamic_modules_mode) {
// when black/white list is on, never inject into zygote if dynamic modules mode is on
return;
}
prepareJavaEnv(env);
findAndCall(env, "forkAndSpecializePre",
"(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;)V",
"(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;ZZ)V",
uid, gid, gids, runtime_flags, rlimits,
_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) {
@ -100,8 +107,8 @@ int onNativeForkAndSpecializePost(JNIEnv *env, jclass clazz, jint res) {
return 0;
}
prepareJavaEnv(env);
findAndCall(env, "forkAndSpecializePost", "(ILjava/lang/String;Z)V", res, sAppDataDir,
is_black_white_list_enabled());
findAndCall(env, "forkAndSpecializePost", "(ILjava/lang/String;ZZ)V", res, sAppDataDir,
is_black_white_list_enabled(), is_dynamic_modules_enabled());
} else {
// 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

View File

@ -9,7 +9,6 @@
#include "java_hook/java_hook.h"
#include "include/logging.h"
#include "include/fd_utils-inl.h"
#include "native_hook/native_hook.h"
extern "C"
{
@ -20,16 +19,20 @@ jobject gInjectDexClassLoader;
static bool isInited = false;
static FileDescriptorTable* gClosedFdTable = NULL;
static FileDescriptorTable* gClosedFdTable = nullptr;
void closeFilesBeforeForkNative(JNIEnv*, jclass) {
gClosedFdTable = FileDescriptorTable::Create();
}
void reopenFilesAfterForkNative(JNIEnv*, jclass) {
if (!gClosedFdTable) {
LOGE("gClosedFdTable is null when reopening files");
return;
}
gClosedFdTable->Reopen();
delete gClosedFdTable;
gClosedFdTable = NULL;
gClosedFdTable = nullptr;
}
static JNINativeMethod hookMethods[] = {