Add support for EdXp Manager
This commit is contained in:
parent
4b767f35bc
commit
ce5c2bbe47
|
|
@ -25,6 +25,7 @@ public class Main implements KeepAll {
|
||||||
// private static String sForkSystemServerPramsStr = "";
|
// private static String sForkSystemServerPramsStr = "";
|
||||||
public static String sAppDataDir = "";
|
public static String sAppDataDir = "";
|
||||||
public static String sAppProcessName = "";
|
public static String sAppProcessName = "";
|
||||||
|
private static boolean sIsGlobalMode = false;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
init(Build.VERSION.SDK_INT);
|
init(Build.VERSION.SDK_INT);
|
||||||
|
|
@ -39,13 +40,16 @@ public class Main implements KeepAll {
|
||||||
public static void forkAndSpecializePre(int uid, int gid, int[] gids, int debugFlags,
|
public static void forkAndSpecializePre(int uid, int gid, int[] gids, int debugFlags,
|
||||||
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, String appDataDir) {
|
boolean startChildZygote, String instructionSet,
|
||||||
|
String appDataDir, boolean isGlobalMode) {
|
||||||
// sForkAndSpecializePramsStr = String.format(
|
// sForkAndSpecializePramsStr = 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);
|
||||||
if (!DYNAMIC_LOAD_MODULES) {
|
sAppDataDir = appDataDir;
|
||||||
|
sIsGlobalMode = isGlobalMode;
|
||||||
|
if (!DYNAMIC_LOAD_MODULES && isGlobalMode) {
|
||||||
Router.onProcessForked(false);
|
Router.onProcessForked(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -54,8 +58,7 @@ public class Main implements KeepAll {
|
||||||
// Utils.logD(sForkAndSpecializePramsStr + " = " + pid);
|
// Utils.logD(sForkAndSpecializePramsStr + " = " + pid);
|
||||||
if (pid == 0) {
|
if (pid == 0) {
|
||||||
// in app process
|
// in app process
|
||||||
sAppDataDir = appDataDir;
|
if (DYNAMIC_LOAD_MODULES || !sIsGlobalMode) {
|
||||||
if (DYNAMIC_LOAD_MODULES) {
|
|
||||||
Router.onProcessForked(false);
|
Router.onProcessForked(false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -69,13 +72,13 @@ public class Main implements KeepAll {
|
||||||
// sForkSystemServerPramsStr = String.format("Zygote#forkSystemServer(%d, %d, %s, %d, %s, %d, %d)",
|
// sForkSystemServerPramsStr = 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);
|
||||||
|
sAppDataDir = getDataPathPrefix() + "android/";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void forkSystemServerPost(int pid) {
|
public static void forkSystemServerPost(int pid) {
|
||||||
// Utils.logD(sForkSystemServerPramsStr + " = " + pid);
|
// Utils.logD(sForkSystemServerPramsStr + " = " + pid);
|
||||||
if (pid == 0) {
|
if (pid == 0) {
|
||||||
// in system_server process
|
// in system_server process
|
||||||
sAppDataDir = getDataPathPrefix() + "android/";
|
|
||||||
Router.onProcessForked(true);
|
Router.onProcessForked(true);
|
||||||
} else {
|
} else {
|
||||||
// in zygote process, res is child zygote pid
|
// in zygote process, res is child zygote pid
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import android.text.TextUtils;
|
||||||
import android.util.Log;
|
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.entry.Router;
|
import com.elderdrivers.riru.xposed.entry.Router;
|
||||||
import com.elderdrivers.riru.xposed.util.Utils;
|
import com.elderdrivers.riru.xposed.util.Utils;
|
||||||
|
|
||||||
|
|
@ -50,6 +51,7 @@ public final class XposedInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static volatile AtomicBoolean bootstrapHooked = new AtomicBoolean(false);
|
private static volatile AtomicBoolean bootstrapHooked = new AtomicBoolean(false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook some methods which we want to create an easier interface for developers.
|
* Hook some methods which we want to create an easier interface for developers.
|
||||||
*/
|
*/
|
||||||
|
|
@ -122,10 +124,12 @@ public final class XposedInit {
|
||||||
* in <code>assets/xposed_init</code>.
|
* in <code>assets/xposed_init</code>.
|
||||||
*/
|
*/
|
||||||
private static void loadModule(String apk, ClassLoader topClassLoader) {
|
private static void loadModule(String apk, ClassLoader topClassLoader) {
|
||||||
Log.i(TAG, "Loading modules from " + apk);
|
if (BuildConfig.DEBUG)
|
||||||
|
Log.i(TAG, "Loading modules from " + apk);
|
||||||
|
|
||||||
if (!TextUtils.isEmpty(apk) && apk.contains(BLACK_LIST_PACKAGE_NAME)) {
|
if (!TextUtils.isEmpty(apk) && apk.contains(BLACK_LIST_PACKAGE_NAME)) {
|
||||||
Log.i(TAG, "We are going to take over black list's job...");
|
if (BuildConfig.DEBUG)
|
||||||
|
Log.i(TAG, "We are going to take over black list's job...");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -186,7 +190,8 @@ public final class XposedInit {
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Log.i(TAG, " Loading class " + moduleClassName);
|
if (BuildConfig.DEBUG)
|
||||||
|
Log.i(TAG, " Loading class " + moduleClassName);
|
||||||
Class<?> moduleClass = mcl.loadClass(moduleClassName);
|
Class<?> moduleClass = mcl.loadClass(moduleClassName);
|
||||||
|
|
||||||
if (!IXposedMod.class.isAssignableFrom(moduleClass)) {
|
if (!IXposedMod.class.isAssignableFrom(moduleClass)) {
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ 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)
|
||||||
|
|
@ -0,0 +1,65 @@
|
||||||
|
//
|
||||||
|
// 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"
|
||||||
|
|
||||||
|
static char package_name[256];
|
||||||
|
|
||||||
|
// default is true
|
||||||
|
int is_app_need_hook(JNIEnv *env, jstring appDataDir) {
|
||||||
|
if (is_global_mode()) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int is_global_mode() {
|
||||||
|
return access(GLOBAL_MODE, F_OK) == 0;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
//
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
int is_global_mode();
|
||||||
|
|
||||||
|
#endif //EDXPOSED_CONFIG_MANAGER_H
|
||||||
|
|
@ -5,6 +5,9 @@
|
||||||
#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/"
|
||||||
|
|
||||||
static jclass sEntryClass;
|
static jclass sEntryClass;
|
||||||
static jstring sAppDataDir;
|
static jstring sAppDataDir;
|
||||||
|
|
@ -38,6 +41,9 @@ void findAndCall(JNIEnv *env, const char *methodName, const char *methodSig, ...
|
||||||
void onNativeForkSystemServerPre(JNIEnv *env, jclass clazz, uid_t uid, gid_t gid, jintArray gids,
|
void onNativeForkSystemServerPre(JNIEnv *env, jclass clazz, uid_t uid, gid_t gid, jintArray gids,
|
||||||
jint runtime_flags, jobjectArray rlimits,
|
jint runtime_flags, jobjectArray rlimits,
|
||||||
jlong permittedCapabilities, jlong effectiveCapabilities) {
|
jlong permittedCapabilities, jlong effectiveCapabilities) {
|
||||||
|
if (!is_app_need_hook(env, env->NewStringUTF(SYSTEM_SERVER_DATA_DIR))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
prepareJavaEnv(env);
|
prepareJavaEnv(env);
|
||||||
// jump to java code
|
// jump to java code
|
||||||
findAndCall(env, "forkSystemServerPre", "(II[II[[IJJ)V", uid, gid, gids, runtime_flags, rlimits,
|
findAndCall(env, "forkSystemServerPre", "(II[II[[IJJ)V", uid, gid, gids, runtime_flags, rlimits,
|
||||||
|
|
@ -47,6 +53,9 @@ void onNativeForkSystemServerPre(JNIEnv *env, jclass clazz, uid_t uid, gid_t gid
|
||||||
|
|
||||||
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, env->NewStringUTF(SYSTEM_SERVER_DATA_DIR))) {
|
||||||
|
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);
|
||||||
|
|
@ -70,17 +79,23 @@ void onNativeForkAndSpecializePre(JNIEnv *env, jclass clazz,
|
||||||
jboolean is_child_zygote,
|
jboolean is_child_zygote,
|
||||||
jstring instructionSet,
|
jstring instructionSet,
|
||||||
jstring appDataDir) {
|
jstring 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;)V",
|
"(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;Z)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_global_mode());
|
||||||
sAppDataDir = 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