Merge branch 'master' of https://github.com/ElderDrivers/EdXposed
This commit is contained in:
commit
190ce95dc5
|
|
@ -17,6 +17,7 @@ import java.util.Arrays;
|
||||||
public class Main implements KeepAll {
|
public class Main implements KeepAll {
|
||||||
|
|
||||||
public static String appDataDir = "";
|
public static String appDataDir = "";
|
||||||
|
public static String niceName = "";
|
||||||
public static String appProcessName = "";
|
public static String appProcessName = "";
|
||||||
public static long closedFdTable = 0;
|
public static long closedFdTable = 0;
|
||||||
private static String forkAndSpecializePramsStr = "";
|
private static String forkAndSpecializePramsStr = "";
|
||||||
|
|
@ -54,13 +55,13 @@ public class Main implements KeepAll {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void forkAndSpecializePost(int pid, String appDataDir) {
|
public static void forkAndSpecializePost(int pid, String appDataDir, String niceName) {
|
||||||
if (pid == 0) {
|
if (pid == 0) {
|
||||||
Utils.logD(forkAndSpecializePramsStr + " = " + Process.myPid());
|
Utils.logD(forkAndSpecializePramsStr + " = " + Process.myPid());
|
||||||
if (isBlackWhiteListEnabled()) {
|
if (isBlackWhiteListEnabled()) {
|
||||||
BlackWhiteListProxy.forkAndSpecializePost(pid, appDataDir);
|
BlackWhiteListProxy.forkAndSpecializePost(pid, appDataDir, niceName);
|
||||||
} else {
|
} else {
|
||||||
NormalProxy.forkAndSpecializePost(pid, appDataDir);
|
NormalProxy.forkAndSpecializePost(pid, appDataDir, niceName);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// in zygote process, res is child zygote pid
|
// in zygote process, res is child zygote pid
|
||||||
|
|
@ -121,9 +122,9 @@ public class Main implements KeepAll {
|
||||||
|
|
||||||
// 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 long closeFilesBeforeForkNative();
|
public static native void closeFilesBeforeForkNative();
|
||||||
|
|
||||||
public static native void reopenFilesAfterForkNative(long fdTable);
|
public static native void reopenFilesAfterForkNative();
|
||||||
|
|
||||||
public static native void deoptMethodNative(Object object);
|
public static native void deoptMethodNative(Object object);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ package com.elderdrivers.riru.xposed.entry;
|
||||||
|
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import com.elderdrivers.riru.xposed.Main;
|
|
||||||
import com.elderdrivers.riru.xposed.core.HookMain;
|
import com.elderdrivers.riru.xposed.core.HookMain;
|
||||||
import com.elderdrivers.riru.xposed.dexmaker.DynamicBridge;
|
import com.elderdrivers.riru.xposed.dexmaker.DynamicBridge;
|
||||||
import com.elderdrivers.riru.xposed.entry.bootstrap.AppBootstrapHookInfo;
|
import com.elderdrivers.riru.xposed.entry.bootstrap.AppBootstrapHookInfo;
|
||||||
|
|
@ -52,25 +51,11 @@ public class Router {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void loadModulesSafely(boolean isInZygote) {
|
public static void loadModulesSafely(boolean isInZygote) {
|
||||||
boolean loadedByMe;
|
|
||||||
try {
|
try {
|
||||||
// FIXME some coredomain app can't reading modules.list
|
// FIXME some coredomain app can't reading modules.list
|
||||||
loadedByMe = XposedInit.loadModules();
|
XposedInit.loadModules(isInZygote);
|
||||||
} catch (Exception exception) {
|
} catch (Exception exception) {
|
||||||
Utils.logE("error loading module list", exception);
|
Utils.logE("error loading module list", exception);
|
||||||
// return true in case there are files opened...
|
|
||||||
loadedByMe = true;
|
|
||||||
}
|
|
||||||
// at last close all fds
|
|
||||||
if (isInZygote && loadedByMe) {
|
|
||||||
Main.closedFdTable = Main.closeFilesBeforeForkNative();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void reopenFilesIfNeeded() {
|
|
||||||
long closedFdTable = Main.closedFdTable;
|
|
||||||
if (closedFdTable != 0) {
|
|
||||||
Main.reopenFilesAfterForkNative(closedFdTable);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,15 @@
|
||||||
package com.elderdrivers.riru.xposed.proxy.yahfa;
|
package com.elderdrivers.riru.xposed.proxy.yahfa;
|
||||||
|
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import com.elderdrivers.riru.xposed.Main;
|
import com.elderdrivers.riru.xposed.Main;
|
||||||
import com.elderdrivers.riru.xposed.config.ConfigManager;
|
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.PrebuiltMethodsDeopter;
|
import com.elderdrivers.riru.xposed.util.PrebuiltMethodsDeopter;
|
||||||
|
import com.elderdrivers.riru.xposed.util.ProcessUtils;
|
||||||
|
import com.elderdrivers.riru.xposed.util.Utils;
|
||||||
|
|
||||||
|
import de.robv.android.xposed.XposedBridge;
|
||||||
|
|
||||||
import static com.elderdrivers.riru.xposed.Main.isAppNeedHook;
|
import static com.elderdrivers.riru.xposed.Main.isAppNeedHook;
|
||||||
import static com.elderdrivers.riru.xposed.util.FileUtils.getDataPathPrefix;
|
import static com.elderdrivers.riru.xposed.util.FileUtils.getDataPathPrefix;
|
||||||
|
|
@ -25,7 +31,7 @@ import static com.elderdrivers.riru.xposed.util.FileUtils.getDataPathPrefix;
|
||||||
* * for all child processes of both main zygote and secondary zygote
|
* * for all child processes of both main zygote and secondary zygote
|
||||||
* 1) do the same things pre-forking first child process
|
* 1) do the same things pre-forking first child process
|
||||||
* 2. Dynamic mode:
|
* 2. Dynamic mode:
|
||||||
* to be continued
|
* to be continued
|
||||||
*/
|
*/
|
||||||
public class BlackWhiteListProxy {
|
public class BlackWhiteListProxy {
|
||||||
|
|
||||||
|
|
@ -43,8 +49,8 @@ public class BlackWhiteListProxy {
|
||||||
onForkPreForNonDynamicMode(false);
|
onForkPreForNonDynamicMode(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void forkAndSpecializePost(int pid, String appDataDir) {
|
public static void forkAndSpecializePost(int pid, String appDataDir, String niceName) {
|
||||||
onForkPostCommon(false, appDataDir);
|
onForkPostCommon(false, appDataDir, niceName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void forkSystemServerPre(int uid, int gid, int[] gids, int debugFlags,
|
public static void forkSystemServerPre(int uid, int gid, int[] gids, int debugFlags,
|
||||||
|
|
@ -60,7 +66,7 @@ public class BlackWhiteListProxy {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void forkSystemServerPost(int pid) {
|
public static void forkSystemServerPost(int pid) {
|
||||||
onForkPostCommon(true, getDataPathPrefix() + "android");
|
onForkPostCommon(true, getDataPathPrefix() + "android", "system_server");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -76,24 +82,51 @@ public class BlackWhiteListProxy {
|
||||||
// because installed hooks would be propagated to all child processes of zygote
|
// because installed hooks would be propagated to all child processes of zygote
|
||||||
Router.startWorkAroundHook();
|
Router.startWorkAroundHook();
|
||||||
// loadModules once for all child processes of zygote
|
// loadModules once for all child processes of zygote
|
||||||
|
// TODO maybe just save initZygote callbacks and call them when whitelisted process forked?
|
||||||
Router.loadModulesSafely(true);
|
Router.loadModulesSafely(true);
|
||||||
|
Main.closeFilesBeforeForkNative();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void onForkPostCommon(boolean isSystemServer, String appDataDir) {
|
private static void onForkPostCommon(boolean isSystemServer, String appDataDir, String niceName) {
|
||||||
Main.appDataDir = appDataDir;
|
Main.appDataDir = appDataDir;
|
||||||
|
Main.niceName = niceName;
|
||||||
|
final boolean isDynamicModulesMode = Main.isDynamicModulesEnabled();
|
||||||
|
ConfigManager.setDynamicModulesMode(isDynamicModulesMode);
|
||||||
Router.onEnterChildProcess();
|
Router.onEnterChildProcess();
|
||||||
if (!isAppNeedHook(Main.appDataDir)) {
|
if (!isDynamicModulesMode) {
|
||||||
|
Main.reopenFilesAfterForkNative();
|
||||||
|
}
|
||||||
|
if (!checkNeedHook(appDataDir, niceName)) {
|
||||||
// if is blacklisted, just stop here
|
// if is blacklisted, just stop here
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final boolean isDynamicModulesMode = Main.isDynamicModulesEnabled();
|
|
||||||
ConfigManager.setDynamicModulesMode(isDynamicModulesMode);
|
|
||||||
Router.prepare(isSystemServer);
|
Router.prepare(isSystemServer);
|
||||||
PrebuiltMethodsDeopter.deoptBootMethods();
|
PrebuiltMethodsDeopter.deoptBootMethods();
|
||||||
Router.reopenFilesIfNeeded();
|
|
||||||
Router.installBootstrapHooks(isSystemServer);
|
Router.installBootstrapHooks(isSystemServer);
|
||||||
if (isDynamicModulesMode) {
|
if (isDynamicModulesMode) {
|
||||||
Router.loadModulesSafely(false);
|
Router.loadModulesSafely(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean checkNeedHook(String appDataDir, String niceName) {
|
||||||
|
boolean needHook;
|
||||||
|
if (TextUtils.isEmpty(appDataDir)) {
|
||||||
|
Utils.logE("niceName:" + niceName + ", procName:"
|
||||||
|
+ ProcessUtils.getCurrentProcessName() + ", appDataDir is null, blacklisted!");
|
||||||
|
needHook = false;
|
||||||
|
} else {
|
||||||
|
// FIXME some process cannot read app_data_file because of MLS, e.g. bluetooth
|
||||||
|
needHook = isAppNeedHook(appDataDir);
|
||||||
|
}
|
||||||
|
if (!needHook) {
|
||||||
|
// clean up the scene
|
||||||
|
onBlackListed();
|
||||||
|
}
|
||||||
|
return needHook;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void onBlackListed() {
|
||||||
|
XposedBridge.clearLoadedPackages();
|
||||||
|
XposedBridge.clearInitPackageResources();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,17 +22,17 @@ public class NormalProxy {
|
||||||
PrebuiltMethodsDeopter.deoptBootMethods(); // do it once for secondary zygote
|
PrebuiltMethodsDeopter.deoptBootMethods(); // do it once for secondary zygote
|
||||||
// install bootstrap hooks for secondary zygote
|
// install bootstrap hooks for secondary zygote
|
||||||
Router.installBootstrapHooks(false);
|
Router.installBootstrapHooks(false);
|
||||||
if (Main.closedFdTable == 0) {
|
// only load modules for secondary zygote
|
||||||
// only load modules for secondary zygote
|
Router.loadModulesSafely(true);
|
||||||
Router.loadModulesSafely(true);
|
Main.closeFilesBeforeForkNative();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void forkAndSpecializePost(int pid, String appDataDir) {
|
public static void forkAndSpecializePost(int pid, String appDataDir, String niceName) {
|
||||||
// TODO consider processes without forkAndSpecializePost called
|
// TODO consider processes without forkAndSpecializePost called
|
||||||
Main.appDataDir = appDataDir;
|
Main.appDataDir = appDataDir;
|
||||||
|
Main.niceName = niceName;
|
||||||
Router.prepare(false);
|
Router.prepare(false);
|
||||||
Router.reopenFilesIfNeeded();
|
Main.reopenFilesAfterForkNative();
|
||||||
Router.onEnterChildProcess();
|
Router.onEnterChildProcess();
|
||||||
// load modules for each app process on its forked if dynamic modules mode is on
|
// load modules for each app process on its forked if dynamic modules mode is on
|
||||||
Router.loadModulesSafely(false);
|
Router.loadModulesSafely(false);
|
||||||
|
|
@ -53,13 +53,15 @@ public class NormalProxy {
|
||||||
// because if not global hooks installed in initZygote might not be
|
// because if not global hooks installed in initZygote might not be
|
||||||
// propagated to processes not forked via forkAndSpecialize
|
// propagated to processes not forked via forkAndSpecialize
|
||||||
Router.loadModulesSafely(true);
|
Router.loadModulesSafely(true);
|
||||||
|
Main.closeFilesBeforeForkNative();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void forkSystemServerPost(int pid) {
|
public static void forkSystemServerPost(int pid) {
|
||||||
// in system_server process
|
// in system_server process
|
||||||
Main.appDataDir = getDataPathPrefix() + "android";
|
Main.appDataDir = getDataPathPrefix() + "android";
|
||||||
|
Main.niceName = "system_server";
|
||||||
Router.prepare(true);
|
Router.prepare(true);
|
||||||
Router.reopenFilesIfNeeded();
|
Main.reopenFilesAfterForkNative();
|
||||||
Router.onEnterChildProcess();
|
Router.onEnterChildProcess();
|
||||||
// reload module list if dynamic mode is on
|
// reload module list if dynamic mode is on
|
||||||
Router.loadModulesSafely(false);
|
Router.loadModulesSafely(false);
|
||||||
|
|
|
||||||
|
|
@ -393,6 +393,12 @@ public final class XposedBridge {
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void clearInitPackageResources() {
|
||||||
|
synchronized (sInitPackageResourcesCallbacks) {
|
||||||
|
sInitPackageResourcesCallbacks.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Intercept every call to the specified method and call a handler function instead.
|
* Intercept every call to the specified method and call a handler function instead.
|
||||||
* @param method The method to intercept
|
* @param method The method to intercept
|
||||||
|
|
|
||||||
|
|
@ -88,10 +88,11 @@ public final class XposedInit {
|
||||||
*/
|
*/
|
||||||
private static volatile AtomicBoolean modulesLoaded = new AtomicBoolean(false);
|
private static volatile AtomicBoolean modulesLoaded = new AtomicBoolean(false);
|
||||||
|
|
||||||
public static boolean loadModules() throws IOException {
|
public static void loadModules(boolean isInZygote) throws IOException {
|
||||||
if (!modulesLoaded.compareAndSet(false, true)
|
boolean hasLoaded = !modulesLoaded.compareAndSet(false, true);
|
||||||
&& !ConfigManager.isDynamicModulesMode()) {
|
// dynamic module list mode doesn't apply to loading in zygote
|
||||||
return false;
|
if (hasLoaded && (isInZygote || !ConfigManager.isDynamicModulesMode())) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
// FIXME module list is cleared but never could be reload again when using dynamic-module-list under multi-user environment
|
// FIXME module list is cleared but never could be reload again when using dynamic-module-list under multi-user environment
|
||||||
XposedBridge.clearLoadedPackages();
|
XposedBridge.clearLoadedPackages();
|
||||||
|
|
@ -99,7 +100,7 @@ public final class XposedInit {
|
||||||
BaseService service = SELinuxHelper.getAppDataFileService();
|
BaseService service = SELinuxHelper.getAppDataFileService();
|
||||||
if (!service.checkFileExists(filename)) {
|
if (!service.checkFileExists(filename)) {
|
||||||
Log.e(TAG, "Cannot load any modules because " + filename + " was not found");
|
Log.e(TAG, "Cannot load any modules because " + filename + " was not found");
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ClassLoader topClassLoader = XposedBridge.BOOTCLASSLOADER;
|
ClassLoader topClassLoader = XposedBridge.BOOTCLASSLOADER;
|
||||||
|
|
@ -115,7 +116,6 @@ public final class XposedInit {
|
||||||
loadModule(apk, topClassLoader);
|
loadModule(apk, topClassLoader);
|
||||||
}
|
}
|
||||||
apks.close();
|
apks.close();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
apply plugin: 'com.android.library'
|
apply plugin: 'com.android.library'
|
||||||
version "v0.3.0.0_beta3-SNAPSHOT"
|
version "v0.3.1.0_beta-SNAPSHOT"
|
||||||
extensions["module_name"] = "EdXposed"
|
extensions["module_name"] = "EdXposed"
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 28
|
compileSdkVersion 28
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <dirent.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
@ -10,10 +11,14 @@
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <include/android_build.h>
|
#include <include/android_build.h>
|
||||||
#include <include/logging.h>
|
#include <include/logging.h>
|
||||||
|
#include <linux/limits.h>
|
||||||
#include "config_manager.h"
|
#include "config_manager.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
#define PRIMARY_INSTALLER_PKG_NAME "com.solohsu.android.edxp.manager"
|
#define PRIMARY_INSTALLER_PKG_NAME "com.solohsu.android.edxp.manager"
|
||||||
#define SECONDARY_INSTALLER_PKG_NAME "org.meowcat.edxposed.manager"
|
#define SECONDARY_INSTALLER_PKG_NAME "org.meowcat.edxposed.manager"
|
||||||
#define LEGACY_INSTALLER_PKG_NAME "de.robv.android.xposed.installer"
|
#define LEGACY_INSTALLER_PKG_NAME "de.robv.android.xposed.installer"
|
||||||
|
|
@ -22,6 +27,7 @@ static bool use_prot_storage = GetAndroidApiLevel() >= ANDROID_N;
|
||||||
static const char *data_path_prefix = use_prot_storage ? "/data/user_de/0/" : "/data/user/0/";
|
static const char *data_path_prefix = use_prot_storage ? "/data/user_de/0/" : "/data/user/0/";
|
||||||
static const char *config_path_tpl = "%s/%s/conf/%s";
|
static const char *config_path_tpl = "%s/%s/conf/%s";
|
||||||
static char data_test_path[PATH_MAX];
|
static char data_test_path[PATH_MAX];
|
||||||
|
static char base_config_path[PATH_MAX];
|
||||||
static char blacklist_path[PATH_MAX];
|
static char blacklist_path[PATH_MAX];
|
||||||
static char whitelist_path[PATH_MAX];
|
static char whitelist_path[PATH_MAX];
|
||||||
static char use_whitelist_path[PATH_MAX];
|
static char use_whitelist_path[PATH_MAX];
|
||||||
|
|
@ -34,6 +40,10 @@ static bool black_white_list_enabled = false;
|
||||||
static bool dynamic_modules_enabled = false;
|
static bool dynamic_modules_enabled = false;
|
||||||
static bool deopt_boot_image_enabled = false;
|
static bool deopt_boot_image_enabled = false;
|
||||||
static bool inited = false;
|
static bool inited = false;
|
||||||
|
// snapshot at boot
|
||||||
|
static bool use_white_list_snapshot = false;
|
||||||
|
static vector<string> white_list_default;
|
||||||
|
static vector<string> black_list_default;
|
||||||
|
|
||||||
static const char *get_installer_package_name() {
|
static const char *get_installer_package_name() {
|
||||||
snprintf(data_test_path, PATH_MAX, config_path_tpl, data_path_prefix,
|
snprintf(data_test_path, PATH_MAX, config_path_tpl, data_path_prefix,
|
||||||
|
|
@ -61,9 +71,38 @@ static const char *get_installer_package_name() {
|
||||||
return PRIMARY_INSTALLER_PKG_NAME;
|
return PRIMARY_INSTALLER_PKG_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void snapshotBlackWhiteList() {
|
||||||
|
DIR *dir;
|
||||||
|
struct dirent *dent;
|
||||||
|
dir = opendir(whitelist_path);
|
||||||
|
if (dir != nullptr) {
|
||||||
|
while ((dent = readdir(dir)) != nullptr) {
|
||||||
|
if (dent->d_type == DT_REG) {
|
||||||
|
const char *fileName = dent->d_name;
|
||||||
|
LOGI("whitelist: %s", fileName);
|
||||||
|
white_list_default.emplace_back(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closedir(dir);
|
||||||
|
}
|
||||||
|
dir = opendir(blacklist_path);
|
||||||
|
if (dir != nullptr) {
|
||||||
|
while ((dent = readdir(dir)) != nullptr) {
|
||||||
|
if (dent->d_type == DT_REG) {
|
||||||
|
const char *fileName = dent->d_name;
|
||||||
|
LOGI("blacklist: %s", fileName);
|
||||||
|
black_list_default.emplace_back(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closedir(dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void init_once() {
|
static void init_once() {
|
||||||
if (!inited) {
|
if (!inited) {
|
||||||
installer_package_name = get_installer_package_name();
|
installer_package_name = get_installer_package_name();
|
||||||
|
snprintf(base_config_path, PATH_MAX, config_path_tpl, data_path_prefix,
|
||||||
|
installer_package_name, "");
|
||||||
snprintf(blacklist_path, PATH_MAX, config_path_tpl, data_path_prefix,
|
snprintf(blacklist_path, PATH_MAX, config_path_tpl, data_path_prefix,
|
||||||
installer_package_name, "blacklist/");
|
installer_package_name, "blacklist/");
|
||||||
snprintf(whitelist_path, PATH_MAX, config_path_tpl, data_path_prefix,
|
snprintf(whitelist_path, PATH_MAX, config_path_tpl, data_path_prefix,
|
||||||
|
|
@ -78,9 +117,15 @@ static void init_once() {
|
||||||
installer_package_name, "deoptbootimage");
|
installer_package_name, "deoptbootimage");
|
||||||
dynamic_modules_enabled = access(dynamic_modules_path, F_OK) == 0;
|
dynamic_modules_enabled = access(dynamic_modules_path, F_OK) == 0;
|
||||||
black_white_list_enabled = access(black_white_list_path, F_OK) == 0;
|
black_white_list_enabled = access(black_white_list_path, F_OK) == 0;
|
||||||
|
// use_white_list snapshot
|
||||||
|
use_white_list_snapshot = access(use_whitelist_path, F_OK) == 0;
|
||||||
deopt_boot_image_enabled = access(deopt_boot_image_path, F_OK) == 0;
|
deopt_boot_image_enabled = access(deopt_boot_image_path, F_OK) == 0;
|
||||||
LOGI("black/white list mode: %d", black_white_list_enabled);
|
LOGI("black/white list mode: %d, using whitelist: %d", black_white_list_enabled,
|
||||||
|
use_white_list_snapshot);
|
||||||
LOGI("dynamic modules mode: %d", dynamic_modules_enabled);
|
LOGI("dynamic modules mode: %d", dynamic_modules_enabled);
|
||||||
|
if (black_white_list_enabled) {
|
||||||
|
snapshotBlackWhiteList();
|
||||||
|
}
|
||||||
inited = true;
|
inited = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -92,12 +137,16 @@ bool is_app_need_hook(JNIEnv *env, jclass, jstring appDataDir) {
|
||||||
if (!black_white_list_enabled) {
|
if (!black_white_list_enabled) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool use_white_list = access(use_whitelist_path, F_OK) == 0;
|
|
||||||
if (!appDataDir) {
|
|
||||||
LOGE("appDataDir is null");
|
|
||||||
return !use_white_list;
|
|
||||||
}
|
|
||||||
const char *app_data_dir = env->GetStringUTFChars(appDataDir, nullptr);
|
const char *app_data_dir = env->GetStringUTFChars(appDataDir, nullptr);
|
||||||
|
bool can_access_app_data = access(base_config_path, F_OK) == 0;
|
||||||
|
bool use_white_list;
|
||||||
|
if (can_access_app_data) {
|
||||||
|
use_white_list = access(use_whitelist_path, F_OK) == 0;
|
||||||
|
} else {
|
||||||
|
LOGE("can't access config path, using snapshot use_white_list: %s", app_data_dir);
|
||||||
|
use_white_list = use_white_list_snapshot;
|
||||||
|
}
|
||||||
int user = 0;
|
int user = 0;
|
||||||
if (sscanf(app_data_dir, "/data/%*[^/]/%d/%s", &user, package_name) != 2) {
|
if (sscanf(app_data_dir, "/data/%*[^/]/%d/%s", &user, package_name) != 2) {
|
||||||
if (sscanf(app_data_dir, "/data/%*[^/]/%s", package_name) != 1) {
|
if (sscanf(app_data_dir, "/data/%*[^/]/%s", package_name) != 1) {
|
||||||
|
|
@ -115,6 +164,11 @@ bool is_app_need_hook(JNIEnv *env, jclass, jstring appDataDir) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (use_white_list) {
|
if (use_white_list) {
|
||||||
|
if (!can_access_app_data) {
|
||||||
|
LOGE("can't access config path, using snapshot white list: %s", app_data_dir);
|
||||||
|
return find(white_list_default.begin(), white_list_default.end(), package_name) !=
|
||||||
|
white_list_default.end();
|
||||||
|
}
|
||||||
char path[PATH_MAX];
|
char path[PATH_MAX];
|
||||||
snprintf(path, PATH_MAX, "%s%s", whitelist_path, package_name);
|
snprintf(path, PATH_MAX, "%s%s", whitelist_path, package_name);
|
||||||
bool res = access(path, F_OK) == 0;
|
bool res = access(path, F_OK) == 0;
|
||||||
|
|
@ -122,6 +176,11 @@ bool is_app_need_hook(JNIEnv *env, jclass, jstring appDataDir) {
|
||||||
env->ReleaseStringUTFChars(appDataDir, app_data_dir);
|
env->ReleaseStringUTFChars(appDataDir, app_data_dir);
|
||||||
return res;
|
return res;
|
||||||
} else {
|
} else {
|
||||||
|
if (!can_access_app_data) {
|
||||||
|
LOGE("can't access config path, using snapshot black list: %s", app_data_dir);
|
||||||
|
return !(find(black_list_default.begin(), black_list_default.end(), package_name) !=
|
||||||
|
black_list_default.end());
|
||||||
|
}
|
||||||
char path[PATH_MAX];
|
char path[PATH_MAX];
|
||||||
snprintf(path, PATH_MAX, "%s%s", blacklist_path, package_name);
|
snprintf(path, PATH_MAX, "%s%s", blacklist_path, package_name);
|
||||||
bool res = access(path, F_OK) != 0;
|
bool res = access(path, F_OK) != 0;
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
static jclass sEntryClass;
|
static jclass sEntryClass;
|
||||||
static jstring sAppDataDir;
|
static jstring sAppDataDir;
|
||||||
|
static jstring sNiceName;
|
||||||
|
|
||||||
void prepareJavaEnv(JNIEnv *env) {
|
void prepareJavaEnv(JNIEnv *env) {
|
||||||
loadDexAndInit(env, INJECT_DEX_PATH);
|
loadDexAndInit(env, INJECT_DEX_PATH);
|
||||||
|
|
@ -81,6 +82,7 @@ void onNativeForkAndSpecializePre(JNIEnv *env, jclass clazz,
|
||||||
jstring instructionSet,
|
jstring instructionSet,
|
||||||
jstring appDataDir) {
|
jstring appDataDir) {
|
||||||
sAppDataDir = appDataDir;
|
sAppDataDir = appDataDir;
|
||||||
|
sNiceName = se_name;
|
||||||
bool is_black_white_list_mode = is_black_white_list_enabled();
|
bool is_black_white_list_mode = is_black_white_list_enabled();
|
||||||
bool is_dynamic_modules_mode = is_dynamic_modules_enabled();
|
bool is_dynamic_modules_mode = is_dynamic_modules_enabled();
|
||||||
if (is_black_white_list_mode && is_dynamic_modules_mode) {
|
if (is_black_white_list_mode && is_dynamic_modules_mode) {
|
||||||
|
|
@ -98,7 +100,7 @@ void onNativeForkAndSpecializePre(JNIEnv *env, jclass clazz,
|
||||||
int onNativeForkAndSpecializePost(JNIEnv *env, jclass clazz, jint res) {
|
int onNativeForkAndSpecializePost(JNIEnv *env, jclass clazz, jint res) {
|
||||||
if (res == 0) {
|
if (res == 0) {
|
||||||
prepareJavaEnv(env);
|
prepareJavaEnv(env);
|
||||||
findAndCall(env, "forkAndSpecializePost", "(ILjava/lang/String;)V", res, sAppDataDir);
|
findAndCall(env, "forkAndSpecializePost", "(ILjava/lang/String;Ljava/lang/String;)V", res, sAppDataDir, sNiceName);
|
||||||
} 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
|
||||||
|
|
|
||||||
|
|
@ -20,18 +20,21 @@ jobject gInjectDexClassLoader;
|
||||||
|
|
||||||
static bool isInited = false;
|
static bool isInited = false;
|
||||||
|
|
||||||
jlong closeFilesBeforeForkNative(JNIEnv *, jclass) {
|
static FileDescriptorTable *gClosedFdTable = nullptr;
|
||||||
return reinterpret_cast<jlong>(FileDescriptorTable::Create());
|
|
||||||
|
void closeFilesBeforeForkNative(JNIEnv *, jclass) {
|
||||||
|
// FIXME what if gClosedFdTable is not null
|
||||||
|
gClosedFdTable = FileDescriptorTable::Create();
|
||||||
}
|
}
|
||||||
|
|
||||||
void reopenFilesAfterForkNative(JNIEnv *, jclass, jlong fdTable) {
|
void reopenFilesAfterForkNative(JNIEnv *, jclass) {
|
||||||
if (fdTable == 0) {
|
if (!gClosedFdTable) {
|
||||||
LOGE("fdTable is null when reopening files");
|
LOGE("gClosedFdTable is null when reopening files");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto *closedFdTable = reinterpret_cast<FileDescriptorTable *>(fdTable);
|
gClosedFdTable->Reopen();
|
||||||
closedFdTable->Reopen();
|
delete gClosedFdTable;
|
||||||
delete closedFdTable;
|
gClosedFdTable = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
jlong suspendAllThreads(JNIEnv *, jclass) {
|
jlong suspendAllThreads(JNIEnv *, jclass) {
|
||||||
|
|
@ -90,10 +93,10 @@ static JNINativeMethod hookMethods[] = {
|
||||||
"getInstallerPkgName", "()Ljava/lang/String;", (void *) get_installer_pkg_name
|
"getInstallerPkgName", "()Ljava/lang/String;", (void *) get_installer_pkg_name
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"closeFilesBeforeForkNative", "()J", (void *) closeFilesBeforeForkNative
|
"closeFilesBeforeForkNative", "()V", (void *) closeFilesBeforeForkNative
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"reopenFilesAfterForkNative", "(J)V", (void *) reopenFilesAfterForkNative
|
"reopenFilesAfterForkNative", "()V", (void *) reopenFilesAfterForkNative
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"deoptMethodNative", "(Ljava/lang/Object;)V", (void *) deoptimize_method
|
"deoptMethodNative", "(Ljava/lang/Object;)V", (void *) deoptimize_method
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ MODDIR=${0%/*}
|
||||||
# More info in the main Magisk thread
|
# More info in the main Magisk thread
|
||||||
|
|
||||||
# EdXposed Version
|
# EdXposed Version
|
||||||
edxp_ver="0.3.0.0_beta3-SNAPSHOT"
|
edxp_ver="0.3.1.0_beta-SNAPSHOT (3100)"
|
||||||
|
|
||||||
# necessary for using mmap in system_server process
|
# necessary for using mmap in system_server process
|
||||||
supolicy --live "allow system_server system_server process {execmem}"
|
supolicy --live "allow system_server system_server process {execmem}"
|
||||||
|
|
@ -24,24 +24,14 @@ supolicy --live "attradd {system_app platform_app} mlstrustedsubject"
|
||||||
supolicy --live "allow zygote apk_data_file * *"
|
supolicy --live "allow zygote apk_data_file * *"
|
||||||
|
|
||||||
# beginning of Log Catcher
|
# beginning of Log Catcher
|
||||||
msg[0]="Now just a little more only just a little more..."
|
|
||||||
msg[1]="It's not a right that I'm due, my duty that is must have been kept..."
|
|
||||||
msg[2]="Since one day you will disappear, I'll keep every part of you..."
|
|
||||||
msg[3]="Yes we are time fliers scaling the walls of time climbers, tired of playing hide and seek with time..."
|
|
||||||
msg[4]="Wherever you are in the world, I'll search for you..."
|
|
||||||
msg[5]="Mitsuha. Mitsuha. Mitsuha, your name is Mitsuha..."
|
|
||||||
msg[6]="Someone dear to me. I don't want to forget. I shouldn't forget!"
|
|
||||||
time=$(date +%Y-%m-%d-%H-%M-%S)
|
|
||||||
android_sdk=`getprop ro.build.version.sdk`
|
android_sdk=`getprop ro.build.version.sdk`
|
||||||
if [ ${android_sdk} -ge 24 ]
|
if [[ ${android_sdk} -ge 24 ]]
|
||||||
then
|
then
|
||||||
path=/data/user_de/0/com.solohsu.android.edxp.manager/log
|
path=/data/user_de/0/com.solohsu.android.edxp.manager/log
|
||||||
else
|
else
|
||||||
path=/data/data/com.solohsu.android.edxp.manager/log
|
path=/data/data/com.solohsu.android.edxp.manager/log
|
||||||
fi
|
fi
|
||||||
file=$path/error.log
|
file=${path}/error.log
|
||||||
num=$(($RANDOM+100000000))
|
|
||||||
rand=$(($num%7))
|
|
||||||
build_desc=`getprop ro.build.description`
|
build_desc=`getprop ro.build.description`
|
||||||
product=`getprop ro.build.product`
|
product=`getprop ro.build.product`
|
||||||
manufacturer=`getprop ro.product.manufacturer`
|
manufacturer=`getprop ro.product.manufacturer`
|
||||||
|
|
@ -51,24 +41,25 @@ arch=`getprop ro.product.cpu.abi`
|
||||||
device=`getprop ro.product.device`
|
device=`getprop ro.product.device`
|
||||||
android=`getprop ro.build.version.release`
|
android=`getprop ro.build.version.release`
|
||||||
build=`getprop ro.build.id`
|
build=`getprop ro.build.id`
|
||||||
mkdir -p $path
|
mkdir -p ${path}
|
||||||
rm -rf $file
|
rm -rf ${file}
|
||||||
touch $file
|
touch ${file}
|
||||||
echo "--------- beginning of head">>$file
|
chmod 755 ${file}
|
||||||
echo "EdXposed Log">>$file
|
echo "--------- beginning of head">>${file}
|
||||||
echo "Powered by Log Catcher">>$file
|
echo "EdXposed Log">>${file}
|
||||||
echo "QQ chat group 855219808">>$file
|
echo "Powered by Log Catcher">>${file}
|
||||||
echo ${msg[$rand]}>>$file
|
echo "QQ chat group 855219808">>${file}
|
||||||
echo "--------- beginning of system info">>$file
|
echo "--------- beginning of system info">>${file}
|
||||||
echo "Android version: ${android}">>$file
|
echo "Android version: ${android}">>${file}
|
||||||
echo "Android sdk: ${android_sdk}">>$file
|
echo "Android sdk: ${android_sdk}">>${file}
|
||||||
echo "Android build: ${build}">>$file
|
echo "Android build: ${build}">>${file}
|
||||||
echo "Fingerprint: ${fingerprint}">>$file
|
echo "Fingerprint: ${fingerprint}">>${file}
|
||||||
echo "ROM build description: ${build_desc}">>$file
|
echo "ROM build description: ${build_desc}">>${file}
|
||||||
echo "EdXposed Version: ${edxp_ver}">>$file
|
echo "EdXposed Version: ${edxp_ver}">>${file}
|
||||||
echo "Architecture: ${arch}">>$file
|
echo "Architecture: ${arch}">>${file}
|
||||||
echo "Device: ${device}">>$file
|
echo "Device: ${device}">>${file}
|
||||||
echo "Manufacturer: ${manufacturer}">>$file
|
echo "Manufacturer: ${manufacturer}">>${file}
|
||||||
echo "Brand: ${brand}">>$file
|
echo "Brand: ${brand}">>${file}
|
||||||
echo "Product: ${product}">>$file
|
echo "Product: ${product}">>${file}
|
||||||
logcat *:V logcatcher-xposed-mlgmxyysd:S|grep -i "EdXposed-">>$file &
|
logcat -f ${file} *:S logcatcher-xposed-mlgmxyysd:S EdXposed-Fwk:V EdXposed-dexmaker:V XSharedPreferences:V EdXposed-Bridge:V EdXposed-YAHFA:V EdXposed-Core-Native:V xhook:V EdXposed-Manager:V Riru:V RiruManager:V XposedInstaller:V &
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ LATESTARTSERVICE=false
|
||||||
|
|
||||||
print_modname() {
|
print_modname() {
|
||||||
ui_print "************************************"
|
ui_print "************************************"
|
||||||
ui_print " Riru - Ed Xposed v0.3.0.0 "
|
ui_print " Riru - Ed Xposed v0.3.1.0 "
|
||||||
ui_print "************************************"
|
ui_print "************************************"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
id=riru_edxposed
|
id=riru_edxposed
|
||||||
name=Riru - Ed Xposed
|
name=Riru - Ed Xposed
|
||||||
version=v0.3.0.0_beta3-SNAPSHOT
|
version=v0.3.1.0_beta-SNAPSHOT
|
||||||
versionCode=3003
|
versionCode=3100
|
||||||
author=solohsu & MlgmXyysd
|
author=solohsu & MlgmXyysd
|
||||||
description=Magisk version of Xposed. Require Riru - Core installed.
|
description=Magisk version of Xposed. Require Riru - Core installed.
|
||||||
minMagisk=17000
|
minMagisk=17000
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
name=Ed Xposed
|
name=Ed Xposed
|
||||||
version=v0.3.0.0_beta3-SNAPSHOT
|
version=v0.3.1.0_beta-SNAPSHOT
|
||||||
versionCode=3003
|
versionCode=3100
|
||||||
author=solohsu & MlgmXyysd
|
author=solohsu & MlgmXyysd
|
||||||
description=Magisk version of Xposed. Require Riru - Core installed.
|
description=Magisk version of Xposed. Require Riru - Core installed.
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
version=90.0-0.3.0.0-beta3-SNAPSHOT
|
version=90.0-0.3.1.0-beta-SNAPSHOT
|
||||||
arch=arm64
|
arch=arm64
|
||||||
minsdk=23
|
minsdk=23
|
||||||
maxsdk=28
|
maxsdk=28
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue