diff --git a/build.gradle b/build.gradle
index 5db8a85be..ddd888e98 100644
--- a/build.gradle
+++ b/build.gradle
@@ -7,8 +7,7 @@ buildscript {
jcenter()
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.4.0'
-
+ classpath 'com.android.tools.build:gradle:4.1.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
@@ -24,7 +23,7 @@ allprojects {
templateLibPath = templateRootPath + "/system/lib/"
templateLib64Path = templateRootPath + "/system/lib64/"
templateEtcPath = templateRootPath + "/system/etc/"
- hiddenApiStubJarFilePath = project(":hiddenapi-stubs").projectDir.absolutePath + "/libs/framework-stub.jar"
+ hiddenApiStubJarFilePath = project(":hiddenapi-stubs").buildDir.absolutePath + "/libs/framework-stub.jar"
}
repositories {
google()
diff --git a/dalvikdx/.gitignore b/dalvikdx/.gitignore
index 796b96d1c..8b8c3dc1b 100644
--- a/dalvikdx/.gitignore
+++ b/dalvikdx/.gitignore
@@ -1 +1,2 @@
/build
+dex
diff --git a/dalvikdx/build.gradle b/dalvikdx/build.gradle
index c31ce47ac..a1d358bc5 100644
--- a/dalvikdx/build.gradle
+++ b/dalvikdx/build.gradle
@@ -1,47 +1,33 @@
-import org.gradle.internal.os.OperatingSystem
-apply plugin: 'java-library'
+apply plugin: 'com.android.application'
-dependencies {
- implementation fileTree(dir: 'libs', include: ['*.jar'])
+repositories {
+ jcenter()
}
-sourceCompatibility = "7"
-targetCompatibility = "7"
-
-task findDx {
- if (OperatingSystem.current().isWindows()){
- return true
- }
- doLast {
- new ByteArrayOutputStream().withStream { os ->
- exec {
- commandLine "which", "dx"
- standardOutput os
- }
- rootProject.ext.dxPath = os.toString()
- }
- }
+android {
+ compileSdkVersion androidCompileSdkVersion.toInteger()
+ ndkVersion androidCompileNdkVersion
}
-task dexInJar(type: Jar) {
- dependsOn jar
- dependsOn findDx
- doFirst {
- exec {
- workingDir jar.destinationDir
- if (OperatingSystem.current().isWindows()){
- executable "dx.bat"
- args "--dex", "--output", "classes.dex", "${jar.archiveName}"
- } else {
- executable "bash"
- args rootProject.ext.dxPath.trim(), "--dex", "--output", "classes.dex", "${jar.archiveName}"
+afterEvaluate {
+ android.applicationVariants.all { variant ->
+ def variantNameCapped = variant.name.capitalize()
+ def variantNameLowered = variant.name.toLowerCase()
+
+ task("copyDex${variantNameCapped}", type: Copy) {
+ dependsOn "assemble${variantNameCapped}"
+ def dexOutPath = "${buildDir}/intermediates/dex/${variantNameLowered}/mergeDex${variantNameCapped}"
+ from (dexOutPath){
+ rename("classes.dex", "eddalvikdx.dex")
}
+ destinationDir file(templateRootPath + "system/framework/")
+ outputs.upToDateWhen { false }
+ }
+ task("makeJar${variantNameCapped}", type: Jar, dependsOn: "assemble${variantNameCapped}") {
+ dependsOn "assemble${variantNameCapped}"
+ from "${buildDir}/intermediates/javac/${variantNameLowered}/classes"
+ baseName "dalvikdx"
+ outputs.file(archivePath)
}
}
- from "${jar.destinationDir}/classes.dex"
- destinationDir jar.destinationDir
- baseName "eddalvikdx"
- onlyIf {
- !jar.state.upToDate || !file(archiveName).exists()
- }
-}
\ No newline at end of file
+}
diff --git a/dalvikdx/src/main/AndroidManifest.xml b/dalvikdx/src/main/AndroidManifest.xml
new file mode 100644
index 000000000..7474421e8
--- /dev/null
+++ b/dalvikdx/src/main/AndroidManifest.xml
@@ -0,0 +1 @@
+
diff --git a/dexmaker/.gitignore b/dexmaker/.gitignore
index 42afabfd2..8b8c3dc1b 100644
--- a/dexmaker/.gitignore
+++ b/dexmaker/.gitignore
@@ -1 +1,2 @@
-/build
\ No newline at end of file
+/build
+dex
diff --git a/dexmaker/build.gradle b/dexmaker/build.gradle
index 9d4bc9205..a3a6cc1b5 100644
--- a/dexmaker/build.gradle
+++ b/dexmaker/build.gradle
@@ -1,37 +1,39 @@
-import org.gradle.internal.os.OperatingSystem
-apply plugin: 'java'
+apply plugin: 'com.android.application'
description = "A utility for doing compile or runtime code generation targeting Android's Dalvik VM"
-targetCompatibility = '1.7'
-sourceCompatibility = '1.7'
-
repositories {
jcenter()
}
+android {
+ compileSdkVersion androidCompileSdkVersion.toInteger()
+ ndkVersion androidCompileNdkVersion
+}
+
dependencies {
- compileOnly project(':dalvikdx')
+ compileOnly files(project(":dalvikdx").tasks.getByName("makeJarRelease").outputs)
}
-task dexInJar(type: Jar) {
- dependsOn jar
- doFirst {
- exec {
- workingDir jar.destinationDir
- if (OperatingSystem.current().isWindows()){
- executable "dx.bat"
- args "--dex", "--output", "classes.dex", "${jar.archiveName}"
- } else {
- executable "bash"
- args rootProject.ext.dxPath.trim(), "--dex", "--output", "classes.dex", "${jar.archiveName}"
+afterEvaluate {
+ android.applicationVariants.all { variant ->
+ def variantNameCapped = variant.name.capitalize()
+ def variantNameLowered = variant.name.toLowerCase()
+
+ task("copyDex${variantNameCapped}", type: Copy) {
+ dependsOn "assemble${variantNameCapped}"
+ def dexOutPath = "${buildDir}/intermediates/dex/${variantNameLowered}/mergeDex${variantNameCapped}"
+ from (dexOutPath){
+ rename("classes.dex", "eddexmaker.dex")
}
+ destinationDir file(templateRootPath + "system/framework/")
+ outputs.upToDateWhen { false }
+ }
+ task("makeJar${variantNameCapped}", type: Jar, dependsOn: "assemble${variantNameCapped}") {
+ dependsOn "assemble${variantNameCapped}"
+ from "${buildDir}/intermediates/javac/${variantNameLowered}/classes"
+ baseName "dexmaker"
+ outputs.file(archivePath)
}
}
- from "${jar.destinationDir}/classes.dex"
- destinationDir jar.destinationDir
- baseName "eddexmaker"
- onlyIf {
- !jar.state.upToDate || !file(archiveName).exists()
- }
-}
+}
\ No newline at end of file
diff --git a/dexmaker/src/main/AndroidManifest.xml b/dexmaker/src/main/AndroidManifest.xml
new file mode 100644
index 000000000..419831dd1
--- /dev/null
+++ b/dexmaker/src/main/AndroidManifest.xml
@@ -0,0 +1 @@
+
diff --git a/edxp-common/build.gradle b/edxp-common/build.gradle
index f501d3551..3d07b3003 100644
--- a/edxp-common/build.gradle
+++ b/edxp-common/build.gradle
@@ -17,13 +17,14 @@ android {
}
}
+ ndkVersion androidCompileNdkVersion
}
dependencies {
compileOnly project(':hiddenapi-stubs')
api project(':xposed-bridge')
compileOnly project(':dexmaker')
- api "androidx.annotation:annotation:1.1.0-rc01"
+ compileOnly 'com.android.support:support-annotations:28.0.0'
}
diff --git a/edxp-common/proguard-rules.pro b/edxp-common/proguard-rules.pro
index 721fdf5cf..427bf7d0a 100644
--- a/edxp-common/proguard-rules.pro
+++ b/edxp-common/proguard-rules.pro
@@ -21,6 +21,7 @@
#-renamesourcefileattribute SourceFile
-dontobfuscate
+-dontoptimize
-keep class de.robv.android.xposed.** {*;}
-keep class android.** { *; }
diff --git a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/_hooker/impl/OneplusWorkaround.java b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/_hooker/impl/OneplusWorkaround.java
deleted file mode 100644
index cccc23e26..000000000
--- a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/_hooker/impl/OneplusWorkaround.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.elderdrivers.riru.edxp._hooker.impl;
-
-import com.elderdrivers.riru.edxp.core.Main;
-import com.elderdrivers.riru.edxp.util.Hookers;
-
-import dalvik.system.BaseDexClassLoader;
-import de.robv.android.xposed.XC_MethodHook;
-import de.robv.android.xposed.XposedBridge;
-
-/**
- * On OnePlus stock roms (Android Pie), {@link BaseDexClassLoader#findClass(String)}
- * will open /dev/binder to communicate with PackageManagerService to check whether
- * current package name inCompatConfigList, which is an OnePlus OEM feature enabled only when
- * system prop "persist.sys.oem.region" set to "CN".(detail of related source code:
- * https://gist.github.com/solohsu/ecc07141759958fc096ba0781fac0a5f)
- * If we invoke intZygoteCallbacks in
- * {@link Main#forkAndSpecializePre}, where in zygote process,
- * we would get a chance to invoke findclass, leaving fd of /dev/binder open in zygote process,
- * which is not allowed because /dev/binder is not in predefined whitelist here:
- * http://androidxref.com/9.0.0_r3/xref/frameworks/base/core/jni/fd_utils.cpp#35
- * So we just hook BaseDexClassLoader#inCompatConfigList to return false to prevent
- * open of /dev/binder and we haven't found side effects yet.
- * Other roms might share the same problems but not reported too.
- */
-public class OneplusWorkaround extends XC_MethodHook {
-
- @Override
- protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
- if (XposedBridge.disableHooks || Main.getEdxpImpl().getRouter().isForkCompleted()) {
- return;
- }
- Hookers.logD("BaseDexClassLoader#inCompatConfigList() starts");
- param.setResult(false);
- }
-
-}
diff --git a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/_hooker/yahfa/OnePlusWorkAroundHooker.java b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/_hooker/yahfa/OnePlusWorkAroundHooker.java
deleted file mode 100644
index 8fea63fe3..000000000
--- a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/_hooker/yahfa/OnePlusWorkAroundHooker.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package com.elderdrivers.riru.edxp._hooker.yahfa;
-
-import com.elderdrivers.riru.common.KeepMembers;
-import com.elderdrivers.riru.edxp._hooker.impl.OneplusWorkaround;
-import com.elderdrivers.riru.edxp.core.yahfa.HookMain;
-
-import de.robv.android.xposed.XC_MethodHook;
-import de.robv.android.xposed.annotation.ApiSensitive;
-import de.robv.android.xposed.annotation.Level;
-
-@ApiSensitive(Level.MIDDLE)
-public class OnePlusWorkAroundHooker implements KeepMembers {
-
- static {
- HookMain.addHookItemWhiteList(OnePlusWorkAroundHooker.class.getName());
- }
-
- public static String className = "dalvik.system.BaseDexClassLoader";
- public static String methodName = "inCompatConfigList";
- public static String methodSig = "(ILjava/lang/String;)Z";
-
- public static boolean hook(int type, String packageName) throws Throwable {
- final XC_MethodHook methodHook = new OneplusWorkaround();
- final XC_MethodHook.MethodHookParam param = new XC_MethodHook.MethodHookParam();
- param.thisObject = null;
- param.args = new Object[]{type, packageName};
- methodHook.callBeforeHookedMethod(param);
- if (!param.returnEarly) {
- param.setResult(backup(type, packageName));
- }
- methodHook.callAfterHookedMethod(param);
- return (boolean) param.getResult();
- }
-
- public static boolean backup(int type, String packageName) {
- return false;
- }
-}
\ No newline at end of file
diff --git a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/config/BaseEdxpConfig.java b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/config/BaseEdxpConfig.java
index 12474f647..a4ffce539 100644
--- a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/config/BaseEdxpConfig.java
+++ b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/config/BaseEdxpConfig.java
@@ -51,4 +51,7 @@ public boolean isNoModuleLogEnabled() {
public boolean isBlackWhiteListMode() {
return ConfigManager.isBlackWhiteListEnabled();
}
+
+ @Override
+ public String getModulesList() { return ConfigManager.getModulesList(); }
}
diff --git a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/config/ConfigManager.java b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/config/ConfigManager.java
index e237c276a..c8a14d96d 100644
--- a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/config/ConfigManager.java
+++ b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/config/ConfigManager.java
@@ -49,5 +49,5 @@ private static boolean isFileExists(String path) {
public static native String getDataPathPrefix();
- public static native boolean isAppNeedHook(String appDataDir);
+ public static native String getModulesList();
}
diff --git a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/core/BaseEdxpImpl.java b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/core/BaseEdxpImpl.java
index 8b7593c2a..8d2101d04 100644
--- a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/core/BaseEdxpImpl.java
+++ b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/core/BaseEdxpImpl.java
@@ -1,14 +1,12 @@
package com.elderdrivers.riru.edxp.core;
-import androidx.annotation.NonNull;
+import android.support.annotation.NonNull;
-import com.elderdrivers.riru.edxp.proxy.BlackWhiteListProxy;
import com.elderdrivers.riru.edxp.proxy.NormalProxy;
import com.elderdrivers.riru.edxp.proxy.Router;
public abstract class BaseEdxpImpl implements EdxpImpl {
- protected Proxy mBlackWhiteListProxy;
protected Proxy mNormalProxy;
protected Router mRouter;
@@ -23,15 +21,6 @@ public boolean isInitialized() {
return mInitialized;
}
- @NonNull
- @Override
- public Proxy getBlackWhiteListProxy() {
- if (mBlackWhiteListProxy == null) {
- mBlackWhiteListProxy = createBlackWhiteListProxy();
- }
- return mBlackWhiteListProxy;
- }
-
@NonNull
@Override
public Proxy getNormalProxy() {
@@ -50,10 +39,6 @@ public Router getRouter() {
return mRouter;
}
- protected Proxy createBlackWhiteListProxy() {
- return new BlackWhiteListProxy(getRouter());
- }
-
protected Proxy createNormalProxy() {
return new NormalProxy(getRouter());
}
diff --git a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/core/EdxpImpl.java b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/core/EdxpImpl.java
index 332605942..4309936ff 100644
--- a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/core/EdxpImpl.java
+++ b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/core/EdxpImpl.java
@@ -1,7 +1,7 @@
package com.elderdrivers.riru.edxp.core;
-import androidx.annotation.IntDef;
-import androidx.annotation.NonNull;
+import android.support.annotation.IntDef;
+import android.support.annotation.NonNull;
import com.elderdrivers.riru.common.KeepAll;
import com.elderdrivers.riru.edxp.proxy.Router;
@@ -20,9 +20,6 @@ public interface EdxpImpl extends KeepAll {
@NonNull
Proxy getNormalProxy();
- @NonNull
- Proxy getBlackWhiteListProxy();
-
@NonNull
Router getRouter();
diff --git a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/core/Main.java b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/core/Main.java
index 07ff8c04d..a4acd4d35 100644
--- a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/core/Main.java
+++ b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/core/Main.java
@@ -1,27 +1,20 @@
package com.elderdrivers.riru.edxp.core;
import android.annotation.SuppressLint;
-import android.os.Process;
import com.elderdrivers.riru.common.KeepAll;
-import com.elderdrivers.riru.edxp.common.BuildConfig;
-import com.elderdrivers.riru.edxp.config.ConfigManager;
import com.elderdrivers.riru.edxp.util.Utils;
import java.security.AccessController;
import java.security.PrivilegedAction;
-import java.util.Arrays;
import java.util.Iterator;
import java.util.ServiceLoader;
import java.util.concurrent.atomic.AtomicReference;
+import static com.elderdrivers.riru.edxp.core.EdxpImpl.NONE;
+
@SuppressLint("DefaultLocale")
public class Main implements KeepAll {
-
- private static final boolean logEnabled = BuildConfig.DEBUG;
- private static String forkAndSpecializePramsStr = "";
- private static String forkSystemServerPramsStr = "";
-
private static final AtomicReference edxpImplRef = new AtomicReference<>(null);
static {
@@ -37,67 +30,23 @@ public static void forkAndSpecializePre(int uid, int gid, int[] gids, int debugF
String niceName, int[] fdsToClose, int[] fdsToIgnore,
boolean startChildZygote, String instructionSet,
String appDataDir) {
- final EdxpImpl edxp = getEdxpImpl();
- if (edxp == null || !edxp.isInitialized()) {
- return;
- }
- if (logEnabled) {
- 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);
- }
-
- if (ConfigManager.isBlackWhiteListEnabled()) {
- edxp.getBlackWhiteListProxy().forkAndSpecializePre(uid, gid, gids, debugFlags, rlimits,
- mountExternal, seInfo, niceName, fdsToClose, fdsToIgnore, startChildZygote,
- instructionSet, appDataDir);
- } else {
- edxp.getNormalProxy().forkAndSpecializePre(uid, gid, gids, debugFlags, rlimits, mountExternal,
- seInfo, niceName, fdsToClose, fdsToIgnore, startChildZygote, instructionSet,
- appDataDir);
- }
+ // won't be loaded
}
public static void forkAndSpecializePost(int pid, String appDataDir, String niceName) {
final EdxpImpl edxp = getEdxpImpl();
if (edxp == null || !edxp.isInitialized()) {
+ Utils.logE("Not started up");
return;
}
if (pid == 0) {
- if (logEnabled) {
- Utils.logI(forkAndSpecializePramsStr + " = " + Process.myPid());
- }
- if (ConfigManager.isBlackWhiteListEnabled()) {
- edxp.getBlackWhiteListProxy().forkAndSpecializePost(pid, appDataDir, niceName);
- } else {
- edxp.getNormalProxy().forkAndSpecializePost(pid, appDataDir, niceName);
- }
- } 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
+ edxp.getNormalProxy().forkAndSpecializePost(pid, appDataDir, niceName);
}
}
public static void forkSystemServerPre(int uid, int gid, int[] gids, int debugFlags, int[][] rlimits,
long permittedCapabilities, long effectiveCapabilities) {
- final EdxpImpl edxp = getEdxpImpl();
- if (edxp == null || !edxp.isInitialized()) {
- return;
- }
- if (logEnabled) {
- forkSystemServerPramsStr = String.format("Zygote#forkSystemServer(%d, %d, %s, %d, %s, %d, %d)",
- uid, gid, Arrays.toString(gids), debugFlags, Arrays.toString(rlimits),
- permittedCapabilities, effectiveCapabilities);
- }
- if (ConfigManager.isBlackWhiteListEnabled()) {
- edxp.getBlackWhiteListProxy().forkSystemServerPre(uid, gid, gids, debugFlags, rlimits,
- permittedCapabilities, effectiveCapabilities);
- } else {
- edxp.getNormalProxy().forkSystemServerPre(uid, gid, gids, debugFlags, rlimits,
- permittedCapabilities, effectiveCapabilities);
- }
+ // Won't load
}
public static void forkSystemServerPost(int pid) {
@@ -106,17 +55,7 @@ public static void forkSystemServerPost(int pid) {
return;
}
if (pid == 0) {
- if (logEnabled) {
- Utils.logI(forkSystemServerPramsStr + " = " + Process.myPid());
- }
- if (ConfigManager.isBlackWhiteListEnabled()) {
- edxp.getBlackWhiteListProxy().forkSystemServerPost(pid);
- } else {
- edxp.getNormalProxy().forkSystemServerPost(pid);
- }
- } 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
+ edxp.getNormalProxy().forkSystemServerPost(pid);
}
}
@@ -134,19 +73,21 @@ public static synchronized int getEdxpVariant() {
}
private static void loadEdxpImpls() {
- AccessController.doPrivileged(new PrivilegedAction() {
- public Void run() {
- Iterator iterator = ServiceLoader.load(
- EdxpImpl.class, Main.class.getClassLoader()).iterator();
- try {
- while (iterator.hasNext()) {
- iterator.next();
- }
- } catch (Throwable t) {
- Utils.logE("error when loadEdxpImpls", t);
- }
- return null;
- }
- });
+ // We don't have Manifest now, so we have to load manually.
+ try {
+ Class.forName("com.elderdrivers.riru.edxp.sandhook.core.SandHookEdxpImpl");
+ }catch(Throwable ignored) {
+ Utils.logD("not using sandhook");
+ }
+ try {
+ Class.forName("com.elderdrivers.riru.edxp.yahfa.core.YahfaEdxpImpl");
+ }catch(Throwable ignored) {
+ Utils.logD("not using yahfa");
+ }
+ try {
+ Class.forName("com.elderdrivers.riru.edxp.whale.core.WhaleEdxpImpl");
+ }catch(Throwable ignored) {
+ Utils.logD("not found whale");
+ }
}
}
diff --git a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/entry/yahfa/AppBootstrapHookInfo.java b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/entry/yahfa/AppBootstrapHookInfo.java
index c76b47afc..8fb6d7598 100644
--- a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/entry/yahfa/AppBootstrapHookInfo.java
+++ b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/entry/yahfa/AppBootstrapHookInfo.java
@@ -3,12 +3,10 @@
import com.elderdrivers.riru.common.KeepMembers;
import com.elderdrivers.riru.edxp._hooker.yahfa.HandleBindAppHooker;
import com.elderdrivers.riru.edxp._hooker.yahfa.LoadedApkConstructorHooker;
-import com.elderdrivers.riru.edxp._hooker.yahfa.OnePlusWorkAroundHooker;
public class AppBootstrapHookInfo implements KeepMembers {
public static String[] hookItemNames = {
HandleBindAppHooker.class.getName(),
LoadedApkConstructorHooker.class.getName(),
- OnePlusWorkAroundHooker.class.getName()
};
}
diff --git a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/entry/yahfa/SysBootstrapHookInfo.java b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/entry/yahfa/SysBootstrapHookInfo.java
index 68656961d..fb50926ca 100644
--- a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/entry/yahfa/SysBootstrapHookInfo.java
+++ b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/entry/yahfa/SysBootstrapHookInfo.java
@@ -3,7 +3,6 @@
import com.elderdrivers.riru.common.KeepMembers;
import com.elderdrivers.riru.edxp._hooker.yahfa.HandleBindAppHooker;
import com.elderdrivers.riru.edxp._hooker.yahfa.LoadedApkConstructorHooker;
-import com.elderdrivers.riru.edxp._hooker.yahfa.OnePlusWorkAroundHooker;
import com.elderdrivers.riru.edxp._hooker.yahfa.SystemMainHooker;
public class SysBootstrapHookInfo implements KeepMembers {
@@ -11,6 +10,5 @@ public class SysBootstrapHookInfo implements KeepMembers {
HandleBindAppHooker.class.getName(),
SystemMainHooker.class.getName(),
LoadedApkConstructorHooker.class.getName(),
- OnePlusWorkAroundHooker.class.getName()
};
}
diff --git a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/entry/yahfa/WorkAroundHookInfo.java b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/entry/yahfa/WorkAroundHookInfo.java
deleted file mode 100644
index ecf36e5e8..000000000
--- a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/entry/yahfa/WorkAroundHookInfo.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.elderdrivers.riru.edxp.entry.yahfa;
-
-import com.elderdrivers.riru.common.KeepMembers;
-import com.elderdrivers.riru.edxp._hooker.yahfa.OnePlusWorkAroundHooker;
-
-public class WorkAroundHookInfo implements KeepMembers {
- public static String[] hookItemNames = {
- OnePlusWorkAroundHooker.class.getName()
- };
-}
diff --git a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/proxy/BaseRouter.java b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/proxy/BaseRouter.java
index 996843e77..4c8ef5853 100644
--- a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/proxy/BaseRouter.java
+++ b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/proxy/BaseRouter.java
@@ -7,19 +7,16 @@
import com.elderdrivers.riru.edxp._hooker.impl.HandleBindApp;
import com.elderdrivers.riru.edxp._hooker.impl.LoadedApkCstr;
-import com.elderdrivers.riru.edxp._hooker.impl.OneplusWorkaround;
import com.elderdrivers.riru.edxp._hooker.impl.StartBootstrapServices;
import com.elderdrivers.riru.edxp._hooker.impl.SystemMain;
import com.elderdrivers.riru.edxp._hooker.yahfa.HandleBindAppHooker;
import com.elderdrivers.riru.edxp._hooker.yahfa.LoadedApkConstructorHooker;
-import com.elderdrivers.riru.edxp._hooker.yahfa.OnePlusWorkAroundHooker;
import com.elderdrivers.riru.edxp._hooker.yahfa.StartBootstrapServicesHooker;
import com.elderdrivers.riru.edxp._hooker.yahfa.SystemMainHooker;
import com.elderdrivers.riru.edxp.core.yahfa.HookMain;
import com.elderdrivers.riru.edxp.entry.yahfa.AppBootstrapHookInfo;
import com.elderdrivers.riru.edxp.entry.yahfa.SysBootstrapHookInfo;
import com.elderdrivers.riru.edxp.entry.yahfa.SysInnerHookInfo;
-import com.elderdrivers.riru.edxp.entry.yahfa.WorkAroundHookInfo;
import com.elderdrivers.riru.edxp.util.Utils;
import com.elderdrivers.riru.edxp.util.Versions;
@@ -33,14 +30,11 @@
public abstract class BaseRouter implements Router {
- protected volatile boolean forkCompleted = false;
-
protected volatile AtomicBoolean bootstrapHooked = new AtomicBoolean(false);
protected static boolean useXposedApi = false;
public void initResourcesHook() {
- startWorkAroundHook(); // for OnePlus devices
XposedBridge.initXResources();
}
@@ -49,18 +43,6 @@ public void prepare(boolean isSystem) {
XposedInit.startsSystemServer = isSystem;
}
- public void onForkStart() {
- forkCompleted = false;
- }
-
- public void onForkFinish() {
- forkCompleted = true;
- }
-
- public boolean isForkCompleted() {
- return forkCompleted;
- }
-
public void installBootstrapHooks(boolean isSystem) {
// Initialize the Xposed framework
try {
@@ -75,10 +57,9 @@ public void installBootstrapHooks(boolean isSystem) {
}
}
- public void loadModulesSafely(boolean isInZygote, boolean callInitZygote) {
+ public void loadModulesSafely(boolean callInitZygote) {
try {
- // FIXME some coredomain app can't reading modules.list
- XposedInit.loadModules(isInZygote, callInitZygote);
+ XposedInit.loadModules(callInitZygote);
} catch (Exception exception) {
Utils.logE("error loading module list", exception);
}
@@ -145,22 +126,4 @@ public void startSystemServerHook() {
SysInnerHookInfo.class.getName());
}
}
-
- @ApiSensitive(Level.LOW)
- public void startWorkAroundHook() {
- ClassLoader classLoader = BaseRouter.class.getClassLoader();
- if (useXposedApi) {
- try {
- XposedHelpers.findAndHookMethod(OnePlusWorkAroundHooker.className,
- classLoader, OnePlusWorkAroundHooker.methodName,
- int.class, String.class, new OneplusWorkaround());
- } catch (Throwable ignored) {
- }
- } else {
- HookMain.doHookDefault(
- BaseRouter.class.getClassLoader(),
- classLoader,
- WorkAroundHookInfo.class.getName());
- }
- }
}
diff --git a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/proxy/BlackWhiteListProxy.java b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/proxy/BlackWhiteListProxy.java
deleted file mode 100644
index 0ff1f1346..000000000
--- a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/proxy/BlackWhiteListProxy.java
+++ /dev/null
@@ -1,139 +0,0 @@
-package com.elderdrivers.riru.edxp.proxy;
-
-import android.text.TextUtils;
-
-import com.elderdrivers.riru.edxp.config.ConfigManager;
-import com.elderdrivers.riru.edxp.deopt.PrebuiltMethodsDeopter;
-import com.elderdrivers.riru.edxp.util.ProcessUtils;
-import com.elderdrivers.riru.edxp.util.Utils;
-
-import de.robv.android.xposed.XposedBridge;
-
-import static com.elderdrivers.riru.edxp.util.FileUtils.getDataPathPrefix;
-
-/**
- * 1. Non dynamic mode
- * - system_server is whitelisted
- * * for all child processes of main zygote
- * What've been done in main zygote pre-forking system_server
- * 1) non dynamic flag set (no need to reset)
- * 2) boot image methods deopted (no need to redo)
- * 3) startSystemServer flag set to true (need to reset)
- * 4) workaround hooks installed (need to redo)
- * 5) module list loaded and initZygote called (no need to redo)
- * 6) close all fds (no need to redo because of 5))
- * * for all child processes of secondary zygote
- * 1) do the same things pre-forking first child process
- * - system_server is blacklisted:
- * * for all child processes of both main zygote and secondary zygote
- * 1) do the same things pre-forking first child process
- * 2. Dynamic mode:
- * to be continued
- */
-public class BlackWhiteListProxy extends BaseProxy {
-
- public BlackWhiteListProxy(Router router) {
- super(router);
- }
-
- public void forkAndSpecializePre(int uid, int gid, int[] gids, int debugFlags,
- int[][] rlimits, int mountExternal, String seInfo,
- String niceName, int[] fdsToClose, int[] fdsToIgnore,
- boolean startChildZygote, String instructionSet,
- String appDataDir) {
- final boolean isDynamicModulesMode = ConfigManager.isDynamicModulesEnabled();
- if (isDynamicModulesMode) {
- onForkPreForDynamicMode(false);
- } else {
- onForkPreForNonDynamicMode(false);
- }
- }
-
- public void forkAndSpecializePost(int pid, String appDataDir, String niceName) {
- onForkPostCommon(false, appDataDir, niceName);
- }
-
- public void forkSystemServerPre(int uid, int gid, int[] gids, int debugFlags,
- int[][] rlimits, long permittedCapabilities,
- long effectiveCapabilities) {
- final boolean isDynamicModulesMode = ConfigManager.isDynamicModulesEnabled();
- if (isDynamicModulesMode) {
- onForkPreForDynamicMode(true);
- } else {
- onForkPreForNonDynamicMode(true);
- }
- }
-
- public void forkSystemServerPost(int pid) {
- onForkPostCommon(true, getDataPathPrefix() + "android", "system_server");
- }
-
- private void onForkPreForDynamicMode(boolean isSystemServer) {
- mRouter.onForkStart();
- mRouter.initResourcesHook();
- mRouter.prepare(isSystemServer);
- mRouter.loadModulesSafely(true, false);
- }
-
- /**
- * Some details are different between main zygote and secondary zygote.
- */
- private void onForkPreForNonDynamicMode(boolean isSystemServer) {
- mRouter.onForkStart();
- mRouter.initResourcesHook();
- // set startsSystemServer flag used when loadModules
- mRouter.prepare(isSystemServer);
- // deoptBootMethods once for all child processes of zygote
- PrebuiltMethodsDeopter.deoptBootMethods();
- // we never install bootstrap hooks here in black/white list mode except workaround hooks
- // because installed hooks would be propagated to all child processes of zygote
- mRouter.startWorkAroundHook();
- // loadModules once for all child processes of zygote
- mRouter.loadModulesSafely(true, false);
- }
-
- private void onForkPostCommon(boolean isSystemServer, String appDataDir, String niceName) {
- ConfigManager.appDataDir = appDataDir;
- ConfigManager.niceName = niceName;
- final boolean isDynamicModulesMode = ConfigManager.isDynamicModulesEnabled();
- mRouter.onEnterChildProcess();
- if (!checkNeedHook(appDataDir, niceName)) {
- // if is blacklisted, just stop here
- mRouter.onForkFinish();
- return;
- }
- if (isDynamicModulesMode) {
- mRouter.initResourcesHook();
- }
- mRouter.prepare(isSystemServer);
- PrebuiltMethodsDeopter.deoptBootMethods();
- mRouter.installBootstrapHooks(isSystemServer);
-
- // under dynamic modules mode, don't call initZygote when loadModule
- // cuz loaded module won't has that chance to do it
- if (isDynamicModulesMode) {
- mRouter.loadModulesSafely(false, false);
- }
- // call all initZygote callbacks
- XposedBridge.callInitZygotes();
-
- mRouter.onForkFinish();
- }
-
- private boolean checkNeedHook(String appDataDir, String niceName) {
- boolean needHook;
- if (TextUtils.isEmpty(appDataDir)) {
- Utils.logE("niceName:" + niceName + ", procName:"
- + ProcessUtils.getCurrentProcessName(ConfigManager.appProcessName) + ", appDataDir is null, blacklisted!");
- needHook = false;
- } else {
- // FIXME some process cannot read app_data_file because of MLS, e.g. bluetooth
- needHook = ConfigManager.isAppNeedHook(appDataDir);
- }
- if (!needHook) {
- // clean up the scene
- onBlackListed();
- }
- return needHook;
- }
-}
diff --git a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/proxy/NormalProxy.java b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/proxy/NormalProxy.java
index 54b0d0521..92d262529 100644
--- a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/proxy/NormalProxy.java
+++ b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/proxy/NormalProxy.java
@@ -18,8 +18,9 @@ public void forkAndSpecializePre(int uid, int gid, int[] gids, int debugFlags,
String niceName, int[] fdsToClose, int[] fdsToIgnore,
boolean startChildZygote, String instructionSet,
String appDataDir) {
- // mainly for secondary zygote
- mRouter.onForkStart();
+ }
+
+ public void forkAndSpecializePost(int pid, String appDataDir, String niceName) {
SELinuxHelper.initOnce();
mRouter.initResourcesHook();
// call this to ensure the flag is set to false ASAP
@@ -27,18 +28,15 @@ public void forkAndSpecializePre(int uid, int gid, int[] gids, int debugFlags,
PrebuiltMethodsDeopter.deoptBootMethods(); // do it once for secondary zygote
// install bootstrap hooks for secondary zygote
mRouter.installBootstrapHooks(false);
- // only load modules for secondary zygote
- mRouter.loadModulesSafely(true, true);
- }
-
- public void forkAndSpecializePost(int pid, String appDataDir, String niceName) {
// TODO consider processes without forkAndSpecializePost being called
forkPostCommon(pid, false, appDataDir, niceName);
}
public void forkSystemServerPre(int uid, int gid, int[] gids, int debugFlags, int[][] rlimits,
long permittedCapabilities, long effectiveCapabilities) {
- mRouter.onForkStart();
+ }
+
+ public void forkSystemServerPost(int pid) {
SELinuxHelper.initOnce();
mRouter.initResourcesHook();
// set startsSystemServer flag used when loadModules
@@ -48,13 +46,6 @@ public void forkSystemServerPre(int uid, int gid, int[] gids, int debugFlags, in
// in case we miss some processes not forked via forkAndSpecialize
// for instance com.android.phone
mRouter.installBootstrapHooks(true);
- // loadModules have to be executed in zygote even isDynamicModules is false
- // because if not global hooks installed in initZygote might not be
- // propagated to processes not forked via forkAndSpecialize
- mRouter.loadModulesSafely(true, true);
- }
-
- public void forkSystemServerPost(int pid) {
// in system_server process
forkPostCommon(pid, true,
getDataPathPrefix() + "android", "system_server");
@@ -66,13 +57,7 @@ private void forkPostCommon(int pid, boolean isSystem, String appDataDir, String
ConfigManager.niceName = niceName;
mRouter.prepare(isSystem);
mRouter.onEnterChildProcess();
- // reload module list if dynamic mode is on
- if (ConfigManager.isDynamicModulesEnabled()) {
- // FIXME this could be error-prone because hooks installed inside old versions
- // of initZygote instances of same module are not unhooked
- mRouter.loadModulesSafely(false, true);
- }
- mRouter.onForkFinish();
+ mRouter.loadModulesSafely(true);
}
}
diff --git a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/proxy/Router.java b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/proxy/Router.java
index 1467bcf3a..63fcd31f9 100644
--- a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/proxy/Router.java
+++ b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/proxy/Router.java
@@ -10,21 +10,13 @@ public interface Router {
void installBootstrapHooks(boolean isSystem);
- void loadModulesSafely(boolean isInZygote, boolean callInitZygote);
+ void loadModulesSafely(boolean callInitZygote);
void startBootstrapHook(boolean isSystem);
void startSystemServerHook();
- void startWorkAroundHook();
-
- void onForkStart();
-
- void onForkFinish();
-
void onEnterChildProcess();
void injectConfig();
-
- boolean isForkCompleted();
}
diff --git a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/util/ClassLoaderUtils.java b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/util/ClassLoaderUtils.java
index 4ef454352..2af555e88 100644
--- a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/util/ClassLoaderUtils.java
+++ b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/util/ClassLoaderUtils.java
@@ -21,7 +21,7 @@
@ApiSensitive(Level.LOW)
public class ClassLoaderUtils {
- public static final String DEXPATH = "/system/framework/edxp.jar:/system/framework/eddalvikdx.jar:/system/framework/eddexmaker.jar";
+ public static final String DEXPATH = "/system/framework/edxp.dex:/system/framework/eddalvikdx.dex:/system/framework/eddexmaker.dex";
public static void replaceParentClassLoader(ClassLoader appClassLoader) {
if (appClassLoader == null) {
diff --git a/edxp-core/.gitignore b/edxp-core/.gitignore
index b077bf8d2..05b2e93c6 100644
--- a/edxp-core/.gitignore
+++ b/edxp-core/.gitignore
@@ -6,4 +6,5 @@
/template_override/module.prop
/template_override/system
/template_override/system_x86
-*.iml
\ No newline at end of file
+*.iml
+/.cxx
\ No newline at end of file
diff --git a/edxp-core/build.gradle b/edxp-core/build.gradle
index 42db5a690..e80bd37d0 100644
--- a/edxp-core/build.gradle
+++ b/edxp-core/build.gradle
@@ -4,7 +4,7 @@ import org.gradle.internal.os.OperatingSystem
apply plugin: 'com.android.library'
// Values set here will be overriden by AppVeyor, feel free to modify during development.
-def buildVersionName = 'v0.5.0.6'
+def buildVersionName = 'v0.5.0.8'
def buildVersionCode = 233
if (System.env.APPVEYOR_BUILD_VERSION != null) {
@@ -49,8 +49,8 @@ android {
externalNativeBuild {
cmake {
abiFilters 'arm64-v8a', 'armeabi-v7a', 'x86', 'x86_64'
- cppFlags "-std=c++17 -ffixed-x18 -Qunused-arguments -frtti"
- cFlags "-std=gnu99 -ffixed-x18 -Qunused-arguments -frtti"
+ cppFlags "-std=c++17 -ffixed-x18 -Qunused-arguments -frtti -fomit-frame-pointer"
+ cFlags "-std=gnu99 -ffixed-x18 -Qunused-arguments -frtti -fomit-frame-pointer"
arguments "-DRIRU_MODULE_API_VERSION=$moduleMaxRiruApiVersion",
"-DRIRU_MODULE_VERSION=$buildVersionCode",
"-DRIRU_MODULE_VERSION_NAME:STRING=\"$buildVersionName\""
@@ -70,8 +70,8 @@ android {
release {
externalNativeBuild {
cmake {
- cppFlags "-fvisibility=hidden -fvisibility-inlines-hidden -O2 -s -Wno-unused-value"
- cFlags "-fvisibility=hidden -fvisibility-inlines-hidden -O2 -s -Wno-unused-value"
+ cppFlags "-fvisibility=hidden -fvisibility-inlines-hidden -O2 -s -Wno-unused-value -fomit-frame-pointer"
+ cFlags "-fvisibility=hidden -fvisibility-inlines-hidden -O2 -s -Wno-unused-value -fomit-frame-pointer"
}
}
minifyEnabled true
@@ -83,34 +83,7 @@ android {
path "src/main/cpp/CMakeLists.txt"
}
}
-}
-
-task copyDalvikdxJar {
- def jarTask = tasks.getByPath(':dalvikdx:dexInJar')
- dependsOn jarTask
- doLast {
- copy {
- from jarTask
- into jar_dest_dir
- }
- }
- onlyIf {
- !jarTask.state.upToDate || !file(jar_dest_dir + jarTask.archiveName).exists()
- }
-}
-
-task copyDexmakerJar {
- def jarTask = tasks.getByPath(':dexmaker:dexInJar')
- dependsOn jarTask
- doLast {
- copy {
- from jarTask
- into jar_dest_dir
- }
- }
- onlyIf {
- !jarTask.state.upToDate || !file(jar_dest_dir + jarTask.archiveName).exists()
- }
+ ndkVersion androidCompileNdkVersion
}
task cleanTemplate(type: Delete) {
@@ -132,8 +105,10 @@ afterEvaluate {
def magiskModuleId = property("${backendLowered}" + "_module_id")
def prepareJarsTask = task("prepareJars${backendCapped}${variantCapped}") {
- dependsOn cleanTemplate, copyDalvikdxJar, copyDexmakerJar
- dependsOn tasks.getByPath(":edxp-${backendLowered}:makeAndCopy${variantCapped}")
+ dependsOn cleanTemplate
+ dependsOn tasks.getByPath(":dexmaker:copyDex${variantCapped}")
+ dependsOn tasks.getByPath(":dalvikdx:copyDex${variantCapped}")
+ dependsOn tasks.getByPath(":edxp-${backendLowered}:copyDex${variantCapped}")
}
def prepareMagiskFilesTask = task("prepareMagiskFiles${backendCapped}${variantCapped}", type: Delete) {
@@ -220,7 +195,28 @@ afterEvaluate {
workingDir "${projectDir}/release"
def commands = ["adb", "push",
"${module_name}-${backend}-${project.version}-${variantLowered}.zip",
- "/sdcard/"]
+ "/data/local/tmp/"]
+ if (is_windows) {
+ commandLine 'cmd', '/c', commands.join(" ")
+ } else {
+ commandLine commands
+ }
+ }
+ task("flash${backendCapped}${variantCapped}", type: Exec) {
+ dependsOn tasks.getByPath("push${backendCapped}${variantCapped}")
+ workingDir "${projectDir}/release"
+ def commands = ["adb", "shell", "su", "-c",
+ "magisk --install-module /data/local/tmp/${module_name}-${backend}-${project.version}-${variantLowered}.zip"]
+ if (is_windows) {
+ commandLine 'cmd', '/c', commands.join(" ")
+ } else {
+ commandLine commands
+ }
+ }
+ task("flashAndReboot${backendCapped}${variantCapped}", type: Exec) {
+ dependsOn tasks.getByPath("flash${backendCapped}${variantCapped}")
+ workingDir "${projectDir}/release"
+ def commands = ["adb", "shell", "reboot"]
if (is_windows) {
commandLine 'cmd', '/c', commands.join(" ")
} else {
diff --git a/edxp-core/src/main/cpp/main/include/JNIHelper.h b/edxp-core/src/main/cpp/main/include/JNIHelper.h
index ccee86ba6..f90162e1b 100644
--- a/edxp-core/src/main/cpp/main/include/JNIHelper.h
+++ b/edxp-core/src/main/cpp/main/include/JNIHelper.h
@@ -4,7 +4,7 @@
#include
#include "logging.h"
-#define JNI_START JNIEnv *env, jclass clazz
+#define JNI_START JNIEnv *env, [[maybe_unused]] jclass clazz
ALWAYS_INLINE static void JNIExceptionClear(JNIEnv *env) {
if (env->ExceptionCheck()) {
@@ -126,8 +126,29 @@ class JUTFString {
if (env_ && jstr_) env_->ReleaseStringUTFChars(jstr_, cstr_);
}
+ JUTFString(JUTFString &&other)
+ : env_(std::move(other.env_)), jstr_(std::move(other.jstr_)),
+ cstr_(std::move(other.cstr_)) {
+ other.cstr_ = nullptr;
+ }
+
+ JUTFString &
+ operator=(JUTFString &&other) {
+ if (&other != this) {
+ env_ = std::move(other.env_);
+ jstr_ = std::move(other.jstr_);
+ cstr_ = std::move(other.cstr_);
+ other.cstr_ = nullptr;
+ }
+ return *this;
+ }
+
private:
JNIEnv *env_;
jstring jstr_;
const char *cstr_;
+
+ JUTFString(const JUTFString &) = delete;
+
+ JUTFString &operator=(const JUTFString &) = delete;
};
diff --git a/edxp-core/src/main/cpp/main/include/base/object.h b/edxp-core/src/main/cpp/main/include/base/object.h
index 45806a081..f7ff2fe03 100644
--- a/edxp-core/src/main/cpp/main/include/base/object.h
+++ b/edxp-core/src/main/cpp/main/include/base/object.h
@@ -5,15 +5,15 @@
#include
#include
-#define __uintval(p) reinterpret_cast(p)
-#define __ptr(p) reinterpret_cast(p)
-#define __align_up(x, n) (((x) + ((n) - 1)) & ~((n) - 1))
-#define __align_down(x, n) ((x) & -(n))
-#define __page_size 4096
-#define __page_align(n) __align_up(static_cast(n), __page_size)
-#define __ptr_align(x) __ptr(__align_down(reinterpret_cast(x), __page_size))
-#define __make_rwx(p, n) ::mprotect(__ptr_align(p), \
- __page_align(__uintval(p) + n) != __page_align(__uintval(p)) ? __page_align(n) + __page_size : __page_align(n), \
+#define _uintval(p) reinterpret_cast(p)
+#define _ptr(p) reinterpret_cast(p)
+#define _align_up(x, n) (((x) + ((n) - 1)) & ~((n) - 1))
+#define _align_down(x, n) ((x) & -(n))
+#define _page_size 4096
+#define _page_align(n) _align_up(static_cast(n), _page_size)
+#define _ptr_align(x) _ptr(_align_down(reinterpret_cast(x), _page_size))
+#define _make_rwx(p, n) ::mprotect(_ptr_align(p), \
+ _page_align(_uintval(p) + n) != _page_align(_uintval(p)) ? _page_align(n) + _page_size : _page_align(n), \
PROT_READ | PROT_WRITE | PROT_EXEC)
typedef void (*HookFunType)(void *, void *, void **);
@@ -97,7 +97,7 @@ namespace edxp {
ALWAYS_INLINE inline static void HookFunction(HookFunType hook_fun, void *original,
void *replace, void **backup) {
- __make_rwx(original, __page_size);
+ _make_rwx(original, _page_size);
hook_fun(original, replace, backup);
}
diff --git a/edxp-core/src/main/cpp/main/include/config.h b/edxp-core/src/main/cpp/main/include/config.h
index cd0a9acd7..def24080b 100644
--- a/edxp-core/src/main/cpp/main/include/config.h
+++ b/edxp-core/src/main/cpp/main/include/config.h
@@ -6,6 +6,7 @@
#include
#include "art/base/macros.h"
#include "android_build.h"
+#include "utils.h"
namespace edxp {
@@ -18,39 +19,31 @@ namespace edxp {
# define LP_SELECT(lp32, lp64) (lp32)
#endif
- static constexpr auto kInjectDexPath = "/system/framework/edxp.jar:"
- "/system/framework/eddalvikdx.jar:"
- "/system/framework/eddexmaker.jar";
+ static const auto kInjectDexPath = "/system/framework/edxp.dex:"
+ "/system/framework/eddalvikdx.dex:"
+ "/system/framework/eddexmaker.dex"_str;
- static constexpr auto kEntryClassName = "com.elderdrivers.riru.edxp.core.Main";
- static constexpr auto kClassLinkerClassName = "com.elderdrivers.riru.edxp.art.ClassLinker";
- static constexpr auto kSandHookClassName = "com.swift.sandhook.SandHook";
- static constexpr auto kSandHookNeverCallClassName = "com.swift.sandhook.ClassNeverCall";
- static constexpr auto kXposedBridgeClassName = "de.robv.android.xposed.XposedBridge";
+ static const auto kEntryClassName = "com.elderdrivers.riru.edxp.core.Main"_str;
+ static const auto kClassLinkerClassName = "com.elderdrivers.riru.edxp.art.ClassLinker";
+ static const auto kSandHookClassName = "com.swift.sandhook.SandHook"_str;
+ static const auto kSandHookNeverCallClassName = "com.swift.sandhook.ClassNeverCall"_str;
- static constexpr auto kLibArtName = "libart.so";
- static constexpr auto kLibFwkName = "libandroid_runtime.so";
- static constexpr auto kLibFwName = "libandroidfw.so";
- static constexpr auto kLibWhaleName = "libwhale.edxp.so";
- static constexpr auto kLibSandHookName = "libsandhook.edxp.so";
- static constexpr auto kLibDlName = "libdl.so";
- static constexpr auto kLibSandHookNativeName = "libsandhook-native.so";
+ static const auto kLibArtName = "libart.so"_str;
+ static const auto kLibFwName = "libandroidfw.so"_str;
+ static const auto kLibWhaleName = "libwhale.edxp.so"_str;
+ static const auto kLibSandHookName = "libsandhook.edxp.so"_str;
+ static const auto kLibDlName = "libdl.so"_str;
+ static const auto kLibSandHookNativeName = "libsandhook-native.so"_str;
static const auto kLibBasePath = std::string(
LP_SELECT("/system/lib/",
"/system/lib64/"));
- static const auto kLinkerPath = std::string(
- LP_SELECT("/apex/com.android.runtime/bin/linker",
- "/apex/com.android.runtime/bin/linker64"));
-
- static const auto kLibDlPath = kLibBasePath + kLibDlName;
static const auto kLibArtLegacyPath = kLibBasePath + kLibArtName;
static const auto kLibSandHookPath = kLibBasePath + kLibSandHookName;
static const auto kLibSandHookNativePath = kLibBasePath + kLibSandHookNativeName;
static const auto kLibFwPath = kLibBasePath + kLibFwName;
- static const auto kLibFwkPath = kLibBasePath + kLibFwkName;
- inline const char *const BoolToString(bool b) {
+ inline constexpr const char *const BoolToString(bool b) {
return b ? "true" : "false";
}
}
\ No newline at end of file
diff --git a/edxp-core/src/main/cpp/main/include/framework/fd_utils.h b/edxp-core/src/main/cpp/main/include/framework/fd_utils.h
deleted file mode 100644
index 8fe4190c4..000000000
--- a/edxp-core/src/main/cpp/main/include/framework/fd_utils.h
+++ /dev/null
@@ -1,38 +0,0 @@
-
-#pragma once
-
-#include
-#include "base/object.h"
-
-namespace android {
-
- // Static whitelist of open paths that the zygote is allowed to keep open.
- static const char *kPathWhitelist[] = {
- "/data/app/",
- "/data/app-private/"
- };
-
- class FileDescriptorWhitelist : public edxp::HookedObject {
-
- public:
- FileDescriptorWhitelist(void *thiz) : HookedObject(thiz) {}
-
- static void Setup(void *handle, HookFunType hook_func) {
- HOOK_FUNC(IsAllowed,
- "_ZNK23FileDescriptorWhitelist9IsAllowedERKNSt3__112"
- "basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE");
- }
-
- private:
-
- CREATE_HOOK_STUB_ENTRIES(bool, IsAllowed, void *thiz, const std::string &path) {
- for (const auto &whitelist_path : kPathWhitelist) {
- if (android::base::StartsWith(path, whitelist_path))
- return true;
- }
- return IsAllowedBackup(thiz, path);
- }
-
- };
-
-}
\ No newline at end of file
diff --git a/edxp-core/src/main/cpp/main/include/logging.h b/edxp-core/src/main/cpp/main/include/logging.h
index 01e381848..9298749b9 100644
--- a/edxp-core/src/main/cpp/main/include/logging.h
+++ b/edxp-core/src/main/cpp/main/include/logging.h
@@ -1,15 +1,12 @@
#ifndef _LOGGING_H
#define _LOGGING_H
-#include
-#include "android/log.h"
+#include
#ifndef LOG_TAG
#define LOG_TAG "EdXposed"
#endif
-#include "config.h"
-
#ifdef LOG_DISABLED
#define LOGD(...)
#define LOGV(...)
@@ -17,7 +14,7 @@
#define LOGW(...)
#define LOGE(...)
#else
-#ifndef NDEBUG
+#if 1
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#else
#define LOGD(...)
diff --git a/edxp-core/src/main/cpp/main/include/utils.h b/edxp-core/src/main/cpp/main/include/utils.h
new file mode 100644
index 000000000..33a9d02c1
--- /dev/null
+++ b/edxp-core/src/main/cpp/main/include/utils.h
@@ -0,0 +1,23 @@
+//
+// Created by loves on 11/13/2020.
+//
+#pragma once
+
+#include
+#include
+#include "logging.h"
+
+namespace edxp {
+ inline const std::string operator ""_str(const char *str, std::size_t size) {
+ return {str, size};
+ }
+
+ inline bool path_exists(const std::filesystem::path &path) {
+ try {
+ return std::filesystem::exists(path);
+ } catch (const std::filesystem::filesystem_error &e) {
+ LOGE("%s", e.what());
+ return false;
+ }
+ }
+}
diff --git a/edxp-core/src/main/cpp/main/src/config_manager.cpp b/edxp-core/src/main/cpp/main/src/config_manager.cpp
index bb3f59ba1..3167cc6ce 100644
--- a/edxp-core/src/main/cpp/main/src/config_manager.cpp
+++ b/edxp-core/src/main/cpp/main/src/config_manager.cpp
@@ -14,68 +14,62 @@
#include
#include
-#include
-#include
+#include
+#include
+#include
#include "art/runtime/native/native_util.h"
#include "config_manager.h"
-using namespace std;
-using namespace art;
-
namespace edxp {
+ namespace fs = std::filesystem;
std::string ConfigManager::RetrieveInstallerPkgName() const {
- std::string data_test_path = data_path_prefix_ + kPrimaryInstallerPkgName;
- if (access(data_test_path.c_str(), F_OK) == 0) {
- LOGI("using installer %s", kPrimaryInstallerPkgName);
+ std::string data_test_path = data_path_prefix_ / kPrimaryInstallerPkgName;
+ if (path_exists(data_test_path)) {
+ LOGI("using installer %s", kPrimaryInstallerPkgName.c_str());
return kPrimaryInstallerPkgName;
}
- data_test_path = data_path_prefix_ + kLegacyInstallerPkgName;
- if (access(data_test_path.c_str(), F_OK) == 0) {
- LOGI("using installer %s", kLegacyInstallerPkgName);
+ data_test_path = data_path_prefix_ / kLegacyInstallerPkgName;
+ if (path_exists(data_test_path)) {
+ LOGI("using installer %s", kLegacyInstallerPkgName.c_str());
return kLegacyInstallerPkgName;
}
- LOGE("no supported installer app found, using default: %s", kPrimaryInstallerPkgName);
+ LOGE("no supported installer app found, using default: %s",
+ kPrimaryInstallerPkgName.c_str());
return kPrimaryInstallerPkgName;
}
void ConfigManager::SnapshotBlackWhiteList() {
- DIR *dir;
- struct dirent *dent;
- dir = opendir(whitelist_path_.c_str());
- 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);
+ white_list_default_.clear();
+ black_list_default_.clear();
+ try {
+ for (auto &item: fs::directory_iterator(whitelist_path_)) {
+ if (item.is_regular_file()) {
+ const auto &file_name = item.path().filename();
+ LOGI(" whitelist: %s", file_name.c_str());
+ white_list_default_.emplace(file_name);
}
}
- closedir(dir);
- }
- dir = opendir(blacklist_path_.c_str());
- 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);
+ for (auto &item: fs::directory_iterator(blacklist_path_)) {
+ if (item.is_regular_file()) {
+ const auto &file_name = item.path().filename();
+ LOGI(" blacklist: %s", file_name.c_str());
+ black_list_default_.emplace(file_name);
}
}
- closedir(dir);
+ } catch (const fs::filesystem_error &e) {
+ LOGE("%s", e.what());
}
}
void ConfigManager::UpdateConfigPath(const uid_t user) {
- if (last_user_ != user) {
- LOGI("updating config data paths from %u to %u...", last_user_, user);
- last_user_ = user;
- }
+ if (LIKELY(last_user_ == user && instance_)) return;
- const char *format = use_prot_storage_ ? "/data/user_de/%u/" : "/data/user/%u/";
- char buff[PATH_MAX];
- snprintf(buff, sizeof(buff), format, last_user_);
- data_path_prefix_ = buff;
+ LOGI("updating config data paths from %u to %u...", last_user_, user);
+ last_user_ = user;
+
+ data_path_prefix_ = use_prot_storage_ ? "/data/user_de" : "/data/user";
+ data_path_prefix_ /= std::to_string(last_user_);
installer_pkg_name_ = RetrieveInstallerPkgName();
base_config_path_ = GetConfigPath("");
@@ -83,15 +77,20 @@ namespace edxp {
whitelist_path_ = GetConfigPath("whitelist/");
use_whitelist_path_ = GetConfigPath("usewhitelist");
- dynamic_modules_enabled_ = access(GetConfigPath("dynamicmodules").c_str(), F_OK) == 0;
- black_white_list_enabled_ = access(GetConfigPath("blackwhitelist").c_str(), F_OK) == 0;
- deopt_boot_image_enabled_ = access(GetConfigPath("deoptbootimage").c_str(), F_OK) == 0;
- resources_hook_enabled_ = access(GetConfigPath("enable_resources").c_str(), F_OK) == 0;
- no_module_log_enabled_ = access(GetConfigPath("disable_modules_log").c_str(), F_OK) == 0;
- hidden_api_bypass_enabled_ = access(GetConfigPath("disable_hidden_api_bypass").c_str(), F_OK) != 0;
+ dynamic_modules_enabled_ = path_exists(GetConfigPath("dynamicmodules"));
+ black_white_list_enabled_ = path_exists(GetConfigPath("blackwhitelist"));
+ deopt_boot_image_enabled_ = path_exists(GetConfigPath("deoptbootimage"));
+ resources_hook_enabled_ = path_exists(GetConfigPath("enable_resources"));
+ no_module_log_enabled_ = path_exists(GetConfigPath("disable_modules_log"));
+ hidden_api_bypass_enabled_ =
+ !path_exists(GetConfigPath("disable_hidden_api_bypass"));
+ modules_list_.clear();
+ app_modules_list_.clear();
+
+ UpdateModuleList();
// use_white_list snapshot
- use_white_list_snapshot_ = access(use_whitelist_path_.c_str(), F_OK) == 0;
+ use_white_list_snapshot_ = path_exists(use_whitelist_path_);
LOGI("data path prefix: %s", data_path_prefix_.c_str());
LOGI(" application list mode: %s", BoolToString(black_white_list_enabled_));
LOGI(" using whitelist: %s", BoolToString(use_white_list_snapshot_));
@@ -105,119 +104,130 @@ namespace edxp {
}
}
+ std::string ConfigManager::GetPackageNameFromBaseApkPath(const fs::path &path) {
+ std::vector paths(path.begin(), path.end());
+ auto base_apk = paths.back(); // base.apk
+ if (base_apk != "base.apk") return {};
+ paths.pop_back();
+ auto pkg_name_with_obfuscation = paths.back();
+ if (auto pos = pkg_name_with_obfuscation.find('-'); pos != std::string::npos) {
+ return pkg_name_with_obfuscation.substr(0, pos);
+ }
+ return {};
+ }
+
// TODO ignore unrelated processes
- bool ConfigManager::IsAppNeedHook(const std::string &app_data_dir) {
+ bool ConfigManager::IsAppNeedHook(const uid_t user, const std::string &package_name) {
// zygote always starts with `uid == 0` and then fork into different user.
// so we have to check if we are the correct user or not.
- uid_t user = 0;
- char package_name[PATH_MAX];
- if (sscanf(app_data_dir.c_str(), "/data/%*[^/]/%u/%s", &user, package_name) != 2) {
- if (sscanf(app_data_dir.c_str(), "/data/%*[^/]/%s", package_name) != 1) {
- package_name[0] = '\0';
- LOGE("can't parse %s", app_data_dir.c_str());
- return false; // default to no hooking for safety
- }
- }
-
- if (last_user_ != user) {
- UpdateConfigPath(user);
- }
+ UpdateConfigPath(user);
if (!black_white_list_enabled_) {
return true;
}
- bool can_access_app_data = access(base_config_path_.c_str(), F_OK) == 0;
+ bool can_access_app_data = path_exists(base_config_path_);
bool use_white_list;
if (can_access_app_data) {
- use_white_list = access(use_whitelist_path_.c_str(), F_OK) == 0;
+ use_white_list = path_exists(use_whitelist_path_);
} else {
LOGE("can't access config path, using snapshot use_white_list: %s",
- app_data_dir.c_str());
+ package_name.c_str());
use_white_list = use_white_list_snapshot_;
}
- if (strcmp(package_name, kPrimaryInstallerPkgName) == 0
- || strcmp(package_name, kLegacyInstallerPkgName) == 0) {
+ if (package_name == kPrimaryInstallerPkgName
+ || package_name == kLegacyInstallerPkgName) {
// always hook installer apps
return true;
}
if (use_white_list) {
if (!can_access_app_data) {
LOGE("can't access config path, using snapshot white list: %s",
- app_data_dir.c_str());
- return !(find(white_list_default_.begin(), white_list_default_.end(),
- package_name) ==
- white_list_default_.end());
+ package_name.c_str());
+ return white_list_default_.count(package_name);
}
- std::string target_path = whitelist_path_ + package_name;
- bool res = access(target_path.c_str(), F_OK) == 0;
- LOGD("using whitelist, %s -> %d", app_data_dir.c_str(), res);
+ std::string target_path = whitelist_path_ / package_name;
+ bool res = path_exists(target_path);
+ LOGD("using whitelist, %s -> %d", package_name.c_str(), res);
return res;
} else {
if (!can_access_app_data) {
LOGE("can't access config path, using snapshot black list: %s",
- app_data_dir.c_str());
- return find(black_list_default_.begin(), black_list_default_.end(), package_name) ==
- black_list_default_.end();
+ package_name.c_str());
+ return black_list_default_.count(package_name);
}
- std::string target_path = blacklist_path_ + package_name;
- bool res = access(target_path.c_str(), F_OK) != 0;
- LOGD("using blacklist, %s -> %d", app_data_dir.c_str(), res);
+ std::string target_path = blacklist_path_ / package_name;
+ bool res = !path_exists(target_path);
+ LOGD("using blacklist, %s -> %d", package_name.c_str(), res);
return res;
}
}
- ALWAYS_INLINE bool ConfigManager::IsBlackWhiteListEnabled() const {
- return black_white_list_enabled_;
- }
-
- ALWAYS_INLINE bool ConfigManager::IsDynamicModulesEnabled() const {
- return dynamic_modules_enabled_;
- }
-
- ALWAYS_INLINE bool ConfigManager::IsNoModuleLogEnabled() const {
- return no_module_log_enabled_;
- }
-
- ALWAYS_INLINE bool ConfigManager::IsResourcesHookEnabled() const {
- return resources_hook_enabled_;
- }
-
- ALWAYS_INLINE bool ConfigManager::IsDeoptBootImageEnabled() const {
- return deopt_boot_image_enabled_;
- }
-
- ALWAYS_INLINE bool ConfigManager::IsHiddenAPIBypassEnabled() const {
- return hidden_api_bypass_enabled_;
- }
-
- ALWAYS_INLINE std::string ConfigManager::GetInstallerPackageName() const {
- return installer_pkg_name_;
- }
-
- ALWAYS_INLINE std::string ConfigManager::GetXposedPropPath() const {
- return kXposedPropPath;
+ ConfigManager::ConfigManager() {
+ use_prot_storage_ = GetAndroidApiLevel() >= __ANDROID_API_N__;
+ last_user_ = 0;
+ UpdateConfigPath(last_user_);
}
- ALWAYS_INLINE std::string ConfigManager::GetLibSandHookName() const {
- return kLibSandHookName;
- }
+ bool ConfigManager::UpdateModuleList() {
+ if (LIKELY(!modules_list_.empty()) && !IsDynamicModulesEnabled())
+ return true;
+ modules_list_.clear();
+ auto global_modules_list = GetConfigPath("modules.list");
+ if (!path_exists(global_modules_list)) {
+ LOGE("Cannot access path %s", global_modules_list.c_str());
+ return false;
+ }
- ALWAYS_INLINE std::string ConfigManager::GetLibWhaleName() const {
- return kLibWhaleName;
- }
+ if (auto last_write_time = fs::last_write_time(global_modules_list);
+ LIKELY(last_write_time < last_write_time_)) {
+ return true;
+ } else {
+ last_write_time_ = last_write_time;
+ }
- ALWAYS_INLINE std::string ConfigManager::GetDataPathPrefix() const {
- return data_path_prefix_;
+ std::ifstream ifs(global_modules_list);
+ if (!ifs.good()) {
+ LOGE("Cannot access path %s", global_modules_list.c_str());
+ return false;
+ }
+ std::string module;
+ while (std::getline(ifs, module)) {
+ const auto &module_pkg_name = GetPackageNameFromBaseApkPath(module);
+ modules_list_.emplace_back(std::move(module), std::unordered_set{});
+ const auto &module_scope_conf = GetConfigPath(module_pkg_name + ".conf");
+ if (!path_exists(module_scope_conf)) {
+ LOGD("module scope is not set for %s", module_pkg_name.c_str());
+ continue;
+ }
+ std::ifstream ifs_c(module_scope_conf);
+ if (!ifs_c.good()) {
+ LOGE("Cannot access path %s", module_scope_conf.c_str());
+ continue;
+ }
+ auto &scope = modules_list_.back().second;
+ std::string app_pkg_name;
+ while (std::getline(ifs_c, app_pkg_name)) {
+ if (!app_pkg_name.empty())
+ scope.emplace(std::move(app_pkg_name));
+ }
+ scope.insert(module_pkg_name); // Always add module itself
+ LOGD("scope of %s is:\n%s", module_pkg_name.c_str(), ([&scope]() {
+ std::ostringstream join;
+ std::copy(scope.begin(), scope.end(),
+ std::ostream_iterator(join, "\n"));
+ return join.str();
+ })().c_str());
+ }
+ return true;
}
- ALWAYS_INLINE std::string ConfigManager::GetConfigPath(const std::string &suffix) const {
- return data_path_prefix_ + installer_pkg_name_ + "/conf/" + suffix;
- };
-
- ConfigManager::ConfigManager() {
- use_prot_storage_ = GetAndroidApiLevel() >= __ANDROID_API_N__;
- last_user_ = 0;
- UpdateConfigPath(last_user_);
+ bool ConfigManager::UpdateAppModuleList(const uid_t user, const std::string &pkg_name) {
+ UpdateConfigPath(user);
+ app_modules_list_.clear();
+ for (const auto&[module, scope]: modules_list_) {
+ if (scope.empty() || scope.count(pkg_name)) app_modules_list_.push_back(module);
+ }
+ return !app_modules_list_.empty() || pkg_name == installer_pkg_name_;
}
}
\ No newline at end of file
diff --git a/edxp-core/src/main/cpp/main/src/config_manager.h b/edxp-core/src/main/cpp/main/src/config_manager.h
index cc05405a4..9047417ce 100644
--- a/edxp-core/src/main/cpp/main/src/config_manager.h
+++ b/edxp-core/src/main/cpp/main/src/config_manager.h
@@ -3,62 +3,77 @@
#include
#include
-#include
+#include "JNIHelper.h"
+#include
#include
+#include
+#include
+#include
+#include "config.h"
namespace edxp {
- static constexpr const char *kPrimaryInstallerPkgName = "org.meowcat.edxposed.manager";
- static constexpr const char *kLegacyInstallerPkgName = "de.robv.android.xposed.installer";
- static constexpr auto kXposedPropPath = "/system/framework/edconfig.jar";
+ static const std::string kPrimaryInstallerPkgName = "org.meowcat.edxposed.manager";
+ static const std::string kLegacyInstallerPkgName = "de.robv.android.xposed.installer";
+ static const std::string kXposedPropPath = "/system/framework/edconfig.jar";
class ConfigManager {
public:
-
- static ConfigManager *GetInstance() {
- if (instance_ == 0) {
- instance_ = new ConfigManager();
+ inline static ConfigManager *GetInstance() {
+ if (!instance_) {
+ instance_ = std::make_unique();
}
- return instance_;
+ return instance_.get();
}
- bool IsBlackWhiteListEnabled() const;
+ inline static std::unique_ptr ReleaseInstance() {
+ return std::move(instance_);
+ }
- bool IsDynamicModulesEnabled() const;
+ inline auto IsBlackWhiteListEnabled() const { return black_white_list_enabled_; }
- bool IsResourcesHookEnabled() const;
+ inline auto IsDynamicModulesEnabled() const { return dynamic_modules_enabled_; }
- bool IsDeoptBootImageEnabled() const;
+ inline auto IsResourcesHookEnabled() const { return resources_hook_enabled_; }
- bool IsNoModuleLogEnabled() const;
+ inline auto IsDeoptBootImageEnabled() const { return deopt_boot_image_enabled_; }
- bool IsHiddenAPIBypassEnabled() const;
+ inline auto IsNoModuleLogEnabled() const { return no_module_log_enabled_; }
- std::string GetInstallerPackageName() const;
+ inline auto IsHiddenAPIBypassEnabled() const { return hidden_api_bypass_enabled_; }
- std::string GetXposedPropPath() const;
+ inline auto GetInstallerPackageName() const { return installer_pkg_name_; }
- std::string GetLibSandHookName() const;
+ inline auto GetXposedPropPath() const { return kXposedPropPath; }
- std::string GetLibWhaleName() const;
+ inline auto GetLibSandHookName() const { return kLibSandHookName; }
- std::string GetDataPathPrefix() const;
+ inline auto GetLibWhaleName() const { return kLibWhaleName; }
- std::string GetConfigPath(const std::string &suffix) const;
+ inline auto GetDataPathPrefix() const { return data_path_prefix_; }
- bool IsAppNeedHook(const std::string &app_data_dir);
+ inline auto GetConfigPath(const std::string &suffix) const {
+ return data_path_prefix_ / installer_pkg_name_ / "conf" / suffix;
+ }
+
+ inline auto GetAppModulesList() const { return app_modules_list_; };
+
+ bool UpdateAppModuleList(const uid_t user, const std::string &pkg_name);
+
+ bool IsAppNeedHook(const uid_t user, const std::string &pkg_name);
+
+ bool UpdateModuleList();
- bool hidden_api_bypass_enabled_ = false;
private:
- inline static ConfigManager *instance_;
- uid_t last_user_ = false;
+ inline static std::unique_ptr instance_ = nullptr;
+ uid_t last_user_ = 0;
bool use_prot_storage_ = true;
- std::string data_path_prefix_;
- std::string installer_pkg_name_;
- std::string base_config_path_;
- std::string blacklist_path_;
- std::string whitelist_path_;
- std::string use_whitelist_path_;
+ std::filesystem::path data_path_prefix_;
+ std::filesystem::path installer_pkg_name_;
+ std::filesystem::path base_config_path_;
+ std::filesystem::path blacklist_path_;
+ std::filesystem::path whitelist_path_;
+ std::filesystem::path use_whitelist_path_;
bool black_white_list_enabled_ = false;
bool dynamic_modules_enabled_ = false;
bool deopt_boot_image_enabled_ = false;
@@ -66,8 +81,15 @@ namespace edxp {
bool resources_hook_enabled_ = false;
// snapshot at boot
bool use_white_list_snapshot_ = false;
- std::vector white_list_default_;
- std::vector black_list_default_;
+ std::unordered_set white_list_default_;
+ std::unordered_set black_list_default_;
+ bool hidden_api_bypass_enabled_ = false;
+
+ std::vector>> modules_list_;
+
+ std::vector app_modules_list_;
+
+ std::filesystem::file_time_type last_write_time_;
ConfigManager();
@@ -76,6 +98,11 @@ namespace edxp {
void SnapshotBlackWhiteList();
std::string RetrieveInstallerPkgName() const;
+
+ static std::string GetPackageNameFromBaseApkPath(const std::filesystem::path &path);
+
+ friend std::unique_ptr std::make_unique();
+
};
} // namespace edxp
diff --git a/edxp-core/src/main/cpp/main/src/edxp_context.cpp b/edxp-core/src/main/cpp/main/src/edxp_context.cpp
index 890733009..f9d2d604a 100644
--- a/edxp-core/src/main/cpp/main/src/edxp_context.cpp
+++ b/edxp-core/src/main/cpp/main/src/edxp_context.cpp
@@ -14,6 +14,8 @@
#include
#include
#include
+#include
+#include
#include "edxp_context.h"
#include "config_manager.h"
@@ -21,6 +23,8 @@
#pragma clang diagnostic ignored "-Wunused-value"
namespace edxp {
+ namespace fs = std::filesystem;
+
constexpr int FIRST_ISOLATED_UID = 99000;
constexpr int LAST_ISOLATED_UID = 99999;
constexpr int FIRST_APP_ZYGOTE_ISOLATED_UID = 90000;
@@ -52,7 +56,28 @@ namespace edxp {
CallPostFixupStaticTrampolinesCallback(class_ptr, post_fixup_static_mid_);
}
- void Context::LoadDexAndInit(JNIEnv *env, const char *dex_path) {
+ void Context::PreLoadDex(JNIEnv *env, const std::string &dex_path) {
+ if (LIKELY(!dexes.empty())) return;
+ std::vector paths;
+ {
+ std::istringstream is(dex_path);
+ std::string path;
+ while (std::getline(is, path, ':')) {
+ paths.emplace_back(std::move(path));
+ }
+ }
+ for (const auto &path: paths) {
+ std::ifstream is(path, std::ios::binary);
+ if (!is.good()) {
+ LOGE("Cannot load path %s", path.c_str());
+ }
+ dexes.emplace_back(std::istreambuf_iterator(is),
+ std::istreambuf_iterator());
+ LOGD("Loaded %s with size %zu", path.c_str(), dexes.back().size());
+ }
+ }
+
+ void Context::InjectDexAndInit(JNIEnv *env) {
if (LIKELY(initialized_)) {
return;
}
@@ -62,21 +87,34 @@ namespace edxp {
env, classloader, "getSystemClassLoader", "()Ljava/lang/ClassLoader;");
jobject sys_classloader = JNI_CallStaticObjectMethod(env, classloader, getsyscl_mid);
if (UNLIKELY(!sys_classloader)) {
- LOG(ERROR) << "getSystemClassLoader failed!!!";
+ LOGE("getSystemClassLoader failed!!!");
return;
}
- jclass path_classloader = JNI_FindClass(env, "dalvik/system/PathClassLoader");
- jmethodID initMid = JNI_GetMethodID(env, path_classloader, "",
- "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;)V");
- jobject my_cl = JNI_NewObject(env, path_classloader, initMid, env->NewStringUTF(dex_path),
- nullptr, sys_classloader);
-
+ jclass in_memory_classloader = JNI_FindClass(env, "dalvik/system/InMemoryDexClassLoader");
+ jmethodID initMid = JNI_GetMethodID(env, in_memory_classloader, "",
+ "([Ljava/nio/ByteBuffer;Ljava/lang/ClassLoader;)V");
+ jclass byte_buffer_class = JNI_FindClass(env, "java/nio/ByteBuffer");
+ jmethodID byte_buffer_wrap = JNI_GetStaticMethodID(env, byte_buffer_class, "wrap",
+ "([B)Ljava/nio/ByteBuffer;");
+ auto buffer_array = env->NewObjectArray(dexes.size(), byte_buffer_class, nullptr);
+ for (size_t i = 0; i != dexes.size(); ++i) {
+ const auto dex = dexes.at(i);
+ auto byte_array = env->NewByteArray(dex.size());
+ env->SetByteArrayRegion(byte_array, 0, dex.size(),
+ dex.data());
+ auto buffer = JNI_CallStaticObjectMethod(env, byte_buffer_class, byte_buffer_wrap,
+ byte_array);
+ env->SetObjectArrayElement(buffer_array, i, buffer);
+ }
+ jobject my_cl = env->NewObject(in_memory_classloader, initMid,
+ buffer_array, sys_classloader);
env->DeleteLocalRef(classloader);
env->DeleteLocalRef(sys_classloader);
- env->DeleteLocalRef(path_classloader);
+ env->DeleteLocalRef(in_memory_classloader);
+ env->DeleteLocalRef(byte_buffer_class);
if (UNLIKELY(my_cl == nullptr)) {
- LOG(ERROR) << "PathClassLoader creation failed!!!";
+ LOGE("InMemoryDexClassLoader creation failed!!!");
return;
}
@@ -140,7 +178,7 @@ namespace edxp {
}
jclass
- Context::FindClassFromLoader(JNIEnv *env, jobject class_loader, const char *class_name) const {
+ Context::FindClassFromLoader(JNIEnv *env, jobject class_loader, const char *class_name) {
jclass clz = JNI_GetObjectClass(env, class_loader);
jmethodID mid = JNI_GetMethodID(env, clz, "loadClass",
"(Ljava/lang/String;)Ljava/lang/Class;");
@@ -155,57 +193,17 @@ namespace edxp {
return (jclass) target;
}
} else {
- LOG(ERROR) << "No loadClass/findClass method found";
+ LOGE("No loadClass/findClass method found");
}
- LOG(ERROR) << "Class " << class_name << " not found";
+ LOGE("Class %s not found", class_name);
return ret;
}
- jclass Context::FindClassFromLoader(JNIEnv *env, const char *className) const {
- return FindClassFromLoader(env, GetCurrentClassLoader(), className);
- }
inline void Context::PrepareJavaEnv(JNIEnv *env) {
- LoadDexAndInit(env, kInjectDexPath);
- }
-
- void Context::ReleaseJavaEnv(JNIEnv *env) {
- if (UNLIKELY(!instance_)) return;
-
- auto xposed_bridge_class = FindClassFromLoader(env, inject_class_loader_, kXposedBridgeClassName);
- if(LIKELY(xposed_bridge_class)){
- jmethodID clear_all_callbacks_method = JNI_GetStaticMethodID(env, xposed_bridge_class, "clearAllCallbacks",
- "()V");
- if(LIKELY(clear_all_callbacks_method)) {
- JNI_CallStaticVoidMethod(env, xposed_bridge_class, clear_all_callbacks_method);
- }
- }
-
- initialized_ = false;
- if (entry_class_) {
- env->DeleteGlobalRef(entry_class_);
- entry_class_ = nullptr;
- }
- if (class_linker_class_) {
- env->DeleteGlobalRef(class_linker_class_);
- class_linker_class_ = nullptr;
- }
- if (inject_class_loader_) {
- env->DeleteGlobalRef(inject_class_loader_);
- inject_class_loader_ = nullptr;
- }
- app_data_dir_ = nullptr;
- nice_name_ = nullptr;
- vm_ = nullptr;
- pre_fixup_static_mid_ = nullptr;
- post_fixup_static_mid_ = nullptr;
-
- auto systemClass = env->FindClass("java/lang/System");
- auto systemGCMethod = env->GetStaticMethodID(systemClass, "gc", "()V");
- env->CallStaticVoidMethod(systemClass, systemGCMethod);
+ InjectDexAndInit(env);
}
-
inline void Context::FindAndCall(JNIEnv *env, const char *method_name,
const char *method_sig, ...) const {
if (UNLIKELY(!entry_class_)) {
@@ -224,24 +222,37 @@ namespace edxp {
}
void
- Context::OnNativeForkSystemServerPre(JNIEnv *env, jclass clazz, uid_t uid, gid_t gid,
+ Context::OnNativeForkSystemServerPre(JNIEnv *env, [[maybe_unused]] jclass clazz, uid_t uid,
+ gid_t gid,
jintArray gids,
jint runtime_flags, jobjectArray rlimits,
jlong permitted_capabilities,
jlong effective_capabilities) {
- app_data_dir_ = env->NewStringUTF(SYSTEM_SERVER_DATA_DIR);
- PrepareJavaEnv(env);
- // jump to java code
- FindAndCall(env, "forkSystemServerPre", "(II[II[[IJJ)V", uid, gid, gids, runtime_flags,
- rlimits, permitted_capabilities, effective_capabilities);
+ ConfigManager::GetInstance()->UpdateModuleList(); // I don't think we need this, but anyway
+ skip_ = false;
+ if (!ConfigManager::GetInstance()->IsAppNeedHook(0, "android")) {
+ skip_ = true;
+ LOGW("skip injecting xposed into android because it's whitelisted/blacklisted");
+ }
+ if (!skip_ && !ConfigManager::GetInstance()->UpdateAppModuleList(0, "android")) {
+ skip_ = true;
+ LOGW("skip injecting into android because no module hooks it");
+ }
+ PreLoadDex(env, kInjectDexPath);
}
int Context::OnNativeForkSystemServerPost(JNIEnv *env, jclass clazz, jint res) {
if (res == 0) {
- PrepareJavaEnv(env);
- // only do work in child since FindAndCall would print log
- FindAndCall(env, "forkSystemServerPost", "(I)V", res);
+ if (!skip_) {
+ PrepareJavaEnv(env);
+ // only do work in child since FindAndCall would print log
+ FindAndCall(env, "forkSystemServerPost", "(I)V", res);
+ } else {
+ auto config_manager = ConfigManager::ReleaseInstance();
+ auto context = Context::ReleaseInstance();
+ LOGD("skipped android");
+ }
} 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
@@ -249,33 +260,62 @@ namespace edxp {
return 0;
}
- std::tuple Context::ShouldSkipInject(JNIEnv *env, jstring nice_name, jstring data_dir, jint uid,
+ std::tuple
+ Context::GetAppInfoFromDir(JNIEnv *env, jstring dir) {
+ uid_t uid = 0;
+ JUTFString app_data_dir(env, dir);
+ if (!app_data_dir) return {false, 0, {}};
+ fs::path path(app_data_dir.get());
+ std::vector splits(path.begin(), path.end());
+ if (splits.size() < 5u) {
+ LOGE("can't parse %s", path.c_str());
+ return {false, uid, {}};
+ }
+ const auto &uid_str = splits[3];
+ const auto &package_name = splits[4];
+ try {
+ uid = stol(uid_str);
+ } catch (const std::invalid_argument &ignored) {
+ LOGE("can't parse %s", app_data_dir.get());
+ return {false, uid, {}};
+ }
+ return {true, uid, package_name};
+ }
+
+ bool Context::ShouldSkipInject(JNIEnv *env, jstring nice_name, jstring data_dir, jint uid,
jboolean is_child_zygote) {
const auto app_id = uid % PER_USER_RANGE;
- const JUTFString package_name(env, nice_name, "UNKNOWN");
+ const auto&[res, user, package_name] = GetAppInfoFromDir(env, data_dir);
bool skip = false;
- bool release = true;
- if (is_child_zygote) {
+ if (!res) {
+ LOGW("skip injecting into %s because it has no data dir", package_name.c_str());
+ skip = true;
+ }
+ if (!skip && is_child_zygote) {
skip = true;
- release = false; // In Android R, calling XposedBridge.clearAllCallbacks cause crashes.
- LOGW("skip injecting into %s because it's a child zygote", package_name.get());
+ LOGW("skip injecting into %s because it's a child zygote", package_name.c_str());
}
- if ((app_id >= FIRST_ISOLATED_UID && app_id <= LAST_ISOLATED_UID) ||
- (app_id >= FIRST_APP_ZYGOTE_ISOLATED_UID && app_id <= LAST_APP_ZYGOTE_ISOLATED_UID) ||
- app_id == SHARED_RELRO_UID) {
+ if (!skip && ((app_id >= FIRST_ISOLATED_UID && app_id <= LAST_ISOLATED_UID) ||
+ (app_id >= FIRST_APP_ZYGOTE_ISOLATED_UID &&
+ app_id <= LAST_APP_ZYGOTE_ISOLATED_UID) ||
+ app_id == SHARED_RELRO_UID)) {
skip = true;
- release = false; // In Android R, calling XposedBridge.clearAllCallbacks cause crashes.
- LOGW("skip injecting into %s because it's isolated", package_name.get());
+ LOGW("skip injecting into %s because it's isolated", package_name.c_str());
}
- const JUTFString dir(env, data_dir);
- if(!dir || !ConfigManager::GetInstance()->IsAppNeedHook(dir)) {
+ if (!skip && !ConfigManager::GetInstance()->IsAppNeedHook(user, package_name)) {
skip = true;
LOGW("skip injecting xposed into %s because it's whitelisted/blacklisted",
- package_name.get());
+ package_name.c_str());
}
- return {skip, release};
+
+ if (!skip && !ConfigManager::GetInstance()->UpdateAppModuleList(user, package_name)) {
+ skip = true;
+ LOGW("skip injecting xposed into %s because no module hooks it",
+ package_name.c_str());
+ }
+ return skip;
}
void Context::OnNativeForkAndSpecializePre(JNIEnv *env, jclass clazz,
@@ -291,32 +331,30 @@ namespace edxp {
jboolean is_child_zygote,
jstring instruction_set,
jstring app_data_dir) {
- std::tie(skip_, release_) = ShouldSkipInject(env, nice_name, app_data_dir, uid, is_child_zygote);
+ ConfigManager::GetInstance()->UpdateModuleList();
+ skip_ = ShouldSkipInject(env, nice_name, app_data_dir, uid,
+ is_child_zygote);
+ const JUTFString dir(env, app_data_dir, "");
app_data_dir_ = app_data_dir;
nice_name_ = nice_name;
- PrepareJavaEnv(env);
- if(!skip_) {
- FindAndCall(env, "forkAndSpecializePre",
- "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;)V",
- uid, gid, gids, runtime_flags, rlimits,
- mount_external, se_info, nice_name, fds_to_close, fds_to_ignore,
- is_child_zygote, instruction_set, app_data_dir);
- }
+ PreLoadDex(env, kInjectDexPath);
}
- int Context::OnNativeForkAndSpecializePost(JNIEnv *env, jclass clazz, jint res) {
+ int
+ Context::OnNativeForkAndSpecializePost(JNIEnv *env, [[maybe_unused]]jclass clazz, jint res) {
if (res == 0) {
- const JUTFString package_name(env, nice_name_);
+ const JUTFString process_name(env, nice_name_);
if (!skip_) {
PrepareJavaEnv(env);
+ LOGD("Done prepare");
FindAndCall(env, "forkAndSpecializePost",
"(ILjava/lang/String;Ljava/lang/String;)V",
res, app_data_dir_, nice_name_);
- LOGD("injected xposed into %s", package_name.get());
+ LOGD("injected xposed into %s", process_name.get());
} else {
- if(release_)
- ReleaseJavaEnv(env);
- LOGD("skipped %s", package_name.get());
+ auto config_manager = ConfigManager::ReleaseInstance();
+ auto context = Context::ReleaseInstance();
+ LOGD("skipped %s", process_name.get());
}
} else {
// in zygote process, res is child zygote pid
diff --git a/edxp-core/src/main/cpp/main/src/edxp_context.h b/edxp-core/src/main/cpp/main/src/edxp_context.h
index 974300daa..a25a7bb9c 100644
--- a/edxp-core/src/main/cpp/main/src/edxp_context.h
+++ b/edxp-core/src/main/cpp/main/src/edxp_context.h
@@ -1,13 +1,16 @@
#pragma once
+#include
#include
-#include
+#include
+#include
+#include
+#include
+#include "utils.h"
namespace edxp {
-
-#define SYSTEM_SERVER_DATA_DIR "/data/user/0/android"
-
+ static const auto SYSTEM_SERVER_DATA_DIR = "/data/user/0/android"_str;
enum Variant {
NONE = 0,
YAHFA = 1,
@@ -18,11 +21,15 @@ namespace edxp {
class Context {
public:
- inline static auto GetInstance() {
- if (instance_ == nullptr) {
- instance_ = new Context();
+ inline static Context *GetInstance() {
+ if (!instance_) {
+ instance_ = std::make_unique();
}
- return instance_;
+ return instance_.get();
+ }
+
+ inline static std::unique_ptr ReleaseInstance() {
+ return std::move(instance_);
}
inline auto GetCurrentClassLoader() const { return inject_class_loader_; }
@@ -45,7 +52,13 @@ namespace edxp {
inline auto GetNiceName() const { return nice_name_; }
- jclass FindClassFromLoader(JNIEnv *env, const char *className) const;
+ inline jclass FindClassFromLoader(JNIEnv *env, const std::string &className) const {
+ return FindClassFromLoader(env, className.c_str());
+ };
+
+ inline jclass FindClassFromLoader(JNIEnv *env, const char *className) const {
+ return FindClassFromLoader(env, GetCurrentClassLoader(), className);
+ }
void OnNativeForkAndSpecializePre(JNIEnv *env, jclass clazz, jint uid, jint gid,
jintArray gids, jint runtime_flags, jobjectArray rlimits,
@@ -68,7 +81,7 @@ namespace edxp {
inline auto GetVariant() const { return variant_; };
private:
- inline static Context *instance_;
+ inline static std::unique_ptr instance_;
bool initialized_ = false;
Variant variant_ = NONE;
jobject inject_class_loader_ = nullptr;
@@ -80,22 +93,30 @@ namespace edxp {
jmethodID pre_fixup_static_mid_ = nullptr;
jmethodID post_fixup_static_mid_ = nullptr;
bool skip_ = false;
- bool release_ = true;
+ std::vector> dexes;
Context() {}
- ~Context() {}
+ void PreLoadDex(JNIEnv *env, const std::string &dex_path);
+
+ void InjectDexAndInit(JNIEnv *env);
- void LoadDexAndInit(JNIEnv *env, const char *dex_path);
+ inline jclass FindClassFromLoader(JNIEnv *env, jobject class_loader,
+ const std::string &class_name) const {
+ return FindClassFromLoader(env, class_loader, class_name.c_str());
+ }
- jclass FindClassFromLoader(JNIEnv *env, jobject class_loader, const char *class_name) const;
+ static jclass
+ FindClassFromLoader(JNIEnv *env, jobject class_loader, const char *class_name);
void CallPostFixupStaticTrampolinesCallback(void *class_ptr, jmethodID mid);
- static std::tuple ShouldSkipInject(JNIEnv *env, jstring nice_name, jstring data_dir, jint uid,
+ static bool ShouldSkipInject(JNIEnv *env, jstring nice_name, jstring data_dir, jint uid,
jboolean is_child_zygote);
- void ReleaseJavaEnv(JNIEnv *env);
+ static std::tuple GetAppInfoFromDir(JNIEnv *env, jstring dir);
+
+ friend std::unique_ptr std::make_unique();
};
}
diff --git a/edxp-core/src/main/cpp/main/src/jni/edxp_config_manager.cpp b/edxp-core/src/main/cpp/main/src/jni/edxp_config_manager.cpp
index 21983d4c1..47a938328 100644
--- a/edxp-core/src/main/cpp/main/src/jni/edxp_config_manager.cpp
+++ b/edxp-core/src/main/cpp/main/src/jni/edxp_config_manager.cpp
@@ -2,6 +2,7 @@
#include
#include
#include
+#include
#include "edxp_config_manager.h"
namespace edxp {
@@ -54,11 +55,13 @@ namespace edxp {
}
- static jboolean ConfigManager_isAppNeedHook(JNI_START, jstring appDataDir) {
- const char *app_data_dir = env->GetStringUTFChars(appDataDir, JNI_FALSE);
- auto result = (jboolean) ConfigManager::GetInstance()->IsAppNeedHook(app_data_dir);
- env->ReleaseStringUTFChars(appDataDir, app_data_dir);
- return result;
+ static jstring ConfigManager_getModulesList(JNI_START) {
+ auto module_list = ConfigManager::GetInstance()->GetAppModulesList();
+ std::ostringstream join;
+ std::copy(module_list.begin(), module_list.end(), std::ostream_iterator(join, "\n"));
+ const auto &list = join.str();
+ LOGD("module list: %s", list.c_str());
+ return env->NewStringUTF(list.c_str());
}
static JNINativeMethod gMethods[] = {
@@ -72,8 +75,9 @@ namespace edxp {
NATIVE_METHOD(ConfigManager, getLibSandHookName, "()Ljava/lang/String;"),
NATIVE_METHOD(ConfigManager, getLibWhaleName, "()Ljava/lang/String;"),
NATIVE_METHOD(ConfigManager, getDataPathPrefix, "()Ljava/lang/String;"),
- NATIVE_METHOD(ConfigManager, getInstallerConfigPath, "(Ljava/lang/String;)Ljava/lang/String;"),
- NATIVE_METHOD(ConfigManager, isAppNeedHook, "(Ljava/lang/String;)Z"),
+ NATIVE_METHOD(ConfigManager, getInstallerConfigPath,
+ "(Ljava/lang/String;)Ljava/lang/String;"),
+ NATIVE_METHOD(ConfigManager, getModulesList, "()Ljava/lang/String;"),
};
void RegisterConfigManagerMethods(JNIEnv *env) {
diff --git a/edxp-core/src/main/cpp/main/src/native_hook.cpp b/edxp-core/src/main/cpp/main/src/native_hook.cpp
index 77866b917..bb67be172 100644
--- a/edxp-core/src/main/cpp/main/src/native_hook.cpp
+++ b/edxp-core/src/main/cpp/main/src/native_hook.cpp
@@ -18,7 +18,6 @@
#include "art/runtime/gc/heap.h"
#include "art/runtime/hidden_api.h"
#include "art/runtime/oat_file_manager.h"
-#include "framework/fd_utils.h"
std::vector linker_get_solist(); // Dobby but not in .h
@@ -26,13 +25,10 @@ namespace edxp {
static volatile bool installed = false;
static volatile bool art_hooks_installed = false;
- static volatile bool fwk_hooks_installed = false;
static HookFunType hook_func = nullptr;
void InstallArtHooks(void *art_handle);
- void InstallFwkHooks(void *fwk_handle);
-
void InstallInlineHooks() {
if (installed) {
LOGI("Inline hooks have been installed, skip");
@@ -72,9 +68,6 @@ namespace edxp {
ScopedDlHandle art_handle(kLibArtLegacyPath.c_str());
InstallArtHooks(art_handle.Get());
}
-
- ScopedDlHandle fwk_handle(kLibFwkPath.c_str());
- InstallFwkHooks(fwk_handle.Get());
}
void InstallArtHooks(void *art_handle) {
@@ -94,13 +87,5 @@ namespace edxp {
art_hooks_installed = true;
LOGI("ART hooks installed");
}
-
- void InstallFwkHooks(void *fwk_handle) {
- if (fwk_hooks_installed) {
- return;
- }
- android::FileDescriptorWhitelist::Setup(fwk_handle, hook_func);
- }
-
}
diff --git a/edxp-core/src/main/cpp/main/src/resource_hook.cpp b/edxp-core/src/main/cpp/main/src/resource_hook.cpp
index 41d2fb8f6..ad960f541 100644
--- a/edxp-core/src/main/cpp/main/src/resource_hook.cpp
+++ b/edxp-core/src/main/cpp/main/src/resource_hook.cpp
@@ -14,6 +14,7 @@
#include "framework/androidfw/ResourceTypes.h"
#include "resource_hook.h"
#include "dl_util.h"
+#include "config.h"
// @ApiSensitive(Level.HIGH)
namespace edxp {
diff --git a/edxp-core/template_override/customize.sh b/edxp-core/template_override/customize.sh
index 0b6f9995f..85daef1ab 100644
--- a/edxp-core/template_override/customize.sh
+++ b/edxp-core/template_override/customize.sh
@@ -36,18 +36,18 @@ PROP_PRODUCT=$(getprop ro.build.product)
PROP_BRAND=$(getprop ro.product.brand)
PROP_MANUFACTURER=$(getprop ro.product.manufacturer)
-JAR_EDXP="$(getRandomNameExist 8 "" ".jar" "
+JAR_EDXP="$(getRandomNameExist 8 "" ".dex" "
/system/framework
-").jar"
-JAR_EDDALVIKDX="$(getRandomNameExist 8 "" ".jar" "
+").dex"
+JAR_EDDALVIKDX="$(getRandomNameExist 8 "" ".dex" "
/system/framework
-").jar"
-JAR_EDDEXMAKER="$(getRandomNameExist 8 "" ".jar" "
+").dex"
+JAR_EDDEXMAKER="$(getRandomNameExist 8 "" ".dex" "
/system/framework
-").jar"
-JAR_EDCONFIG="$(getRandomNameExist 8 "" ".jar" "
-/system/framework
-").jar"
+").dex"
+#JAR_EDCONFIG="$(getRandomNameExist 8 "" ".jar" "
+#/system/framework
+#").jar"
LIB_RIRU_EDXP="libriru_${RIRU_EDXP}.so"
LIB_WHALE_EDXP="lib$(getRandomNameExist 10 "lib" ".so" "
/system/lib
@@ -267,10 +267,10 @@ fi
ui_print "- Copying framework libraries"
-mv "${MODPATH}/system/framework/eddalvikdx.jar" "${MODPATH}/system/framework/${JAR_EDDALVIKDX}"
-mv "${MODPATH}/system/framework/edxp.jar" "${MODPATH}/system/framework/${JAR_EDXP}"
-mv "${MODPATH}/system/framework/eddexmaker.jar" "${MODPATH}/system/framework/${JAR_EDDEXMAKER}"
-mv "${MODPATH}/system/framework/edconfig.jar" "${MODPATH}/system/framework/${JAR_EDCONFIG}"
+mv "${MODPATH}/system/framework/eddalvikdx.dex" "${MODPATH}/system/framework/${JAR_EDDALVIKDX}"
+mv "${MODPATH}/system/framework/edxp.dex" "${MODPATH}/system/framework/${JAR_EDXP}"
+mv "${MODPATH}/system/framework/eddexmaker.dex" "${MODPATH}/system/framework/${JAR_EDDEXMAKER}"
+#mv "${MODPATH}/system/framework/edconfig.jar" "${MODPATH}/system/framework/${JAR_EDCONFIG}"
mv "${MODPATH}/system/lib/libriru_edxp.so" "${MODPATH}/system/lib/${LIB_RIRU_EDXP}"
#mv "${MODPATH}/system/lib/libwhale.edxp.so" "${MODPATH}/system/lib/${LIB_WHALE_EDXP}"
mv "${MODPATH}/system/lib/libsandhook-native.so" "${MODPATH}/system/lib/libsandhook-native.so"
@@ -290,15 +290,15 @@ fi
ui_print "- Resetting libraries path"
-sed -i 's:/system/framework/edxp.jar\:/system/framework/eddalvikdx.jar\:/system/framework/eddexmaker.jar:/system/framework/'"${JAR_EDXP}"'\:/system/framework/'"${JAR_EDDALVIKDX}"'\:/system/framework/'"${JAR_EDDEXMAKER}"':g' "${MODPATH}/system/lib/${LIB_RIRU_EDXP}"
-sed -i 's:/system/framework/edconfig.jar:/system/framework/'"${JAR_EDCONFIG}"':g' "${MODPATH}/system/lib/${LIB_RIRU_EDXP}"
+sed -i 's:/system/framework/edxp.dex\:/system/framework/eddalvikdx.dex\:/system/framework/eddexmaker.dex:/system/framework/'"${JAR_EDXP}"'\:/system/framework/'"${JAR_EDDALVIKDX}"'\:/system/framework/'"${JAR_EDDEXMAKER}"':g' "${MODPATH}/system/lib/${LIB_RIRU_EDXP}"
+#sed -i 's:/system/framework/edconfig.jar:/system/framework/'"${JAR_EDCONFIG}"':g' "${MODPATH}/system/lib/${LIB_RIRU_EDXP}"
sed -i 's:libriru_edxp.so:'"${LIB_RIRU_EDXP}"':g' "${MODPATH}/system/lib/${LIB_RIRU_EDXP}"
#sed -i 's:libwhale.edxp.so:'"${LIB_WHALE_EDXP}"':g' "${MODPATH}/system/lib/${LIB_RIRU_EDXP}"
sed -i 's:libsandhook.edxp.so:'"${LIB_SANDHOOK_EDXP}"':g' "${MODPATH}/system/lib/${LIB_RIRU_EDXP}"
if [[ "${IS64BIT}" == true ]]; then
- sed -i 's:/system/framework/edxp.jar\:/system/framework/eddalvikdx.jar\:/system/framework/eddexmaker.jar:/system/framework/'"${JAR_EDXP}"'\:/system/framework/'"${JAR_EDDALVIKDX}"'\:/system/framework/'"${JAR_EDDEXMAKER}"':g' "${MODPATH}/system/lib64/${LIB_RIRU_EDXP}"
- sed -i 's:/system/framework/edconfig.jar:/system/framework/'"${JAR_EDCONFIG}"':g' "${MODPATH}/system/lib64/${LIB_RIRU_EDXP}"
+ sed -i 's:/system/framework/edxp.dex\:/system/framework/eddalvikdx.dex\:/system/framework/eddexmaker.dex:/system/framework/'"${JAR_EDXP}"'\:/system/framework/'"${JAR_EDDALVIKDX}"'\:/system/framework/'"${JAR_EDDEXMAKER}"':g' "${MODPATH}/system/lib64/${LIB_RIRU_EDXP}"
+# sed -i 's:/system/framework/edconfig.jar:/system/framework/'"${JAR_EDCONFIG}"':g' "${MODPATH}/system/lib64/${LIB_RIRU_EDXP}"
sed -i 's:libriru_edxp.so:'"${LIB_RIRU_EDXP}"':g' "${MODPATH}/system/lib64/${LIB_RIRU_EDXP}"
#sed -i 's:libwhale.edxp.so:'"${LIB_WHALE_EDXP}"':g' "${MODPATH}/system/lib64/${LIB_RIRU_EDXP}"
sed -i 's:libsandhook.edxp.so:'"${LIB_SANDHOOK_EDXP}"':g' "${MODPATH}/system/lib64/${LIB_RIRU_EDXP}"
diff --git a/edxp-core/template_override/riru/module.prop.new b/edxp-core/template_override/riru/module.prop.new
index 69bd5bd18..0df553039 100644
--- a/edxp-core/template_override/riru/module.prop.new
+++ b/edxp-core/template_override/riru/module.prop.new
@@ -1,5 +1,5 @@
name=Riru - EdXposed
-version=v0.5.0.6 (YAHFA)
+version=v0.5.0.8 (YAHFA)
versionCode=233
author=solohsu, MlgmXyysd & rk700
description=Another enhanced implementation of Xposed Framework. Supports Android 8.0, 8.1, 9, 10 or above. Requires Riru - Core v19 or above installed. Telegram: @EdXposed
diff --git a/edxp-core/template_override/sepolicy.rule b/edxp-core/template_override/sepolicy.rule
index b5a8c6abb..fc54e92c3 100644
--- a/edxp-core/template_override/sepolicy.rule
+++ b/edxp-core/template_override/sepolicy.rule
@@ -1,6 +1,4 @@
allow system_server system_server process execmem
allow system_server system_server memprotect mmap_zero
-allow coredomain coredomain process execmem
-allow coredomain app_data_file * *
-attradd {system_app platform_app} mlstrustedsubject
-allow zygote apk_data_file * *
+allow zygote app_data_file dir { search read }
+allow zygote app_data_file file { getattr read open }
\ No newline at end of file
diff --git a/edxp-sandhook/.gitignore b/edxp-sandhook/.gitignore
index 845f99801..3a66a1982 100644
--- a/edxp-sandhook/.gitignore
+++ b/edxp-sandhook/.gitignore
@@ -1,2 +1,2 @@
/build
-/template_override/system/framework/edxp.jar
\ No newline at end of file
+/template_override/system/framework
\ No newline at end of file
diff --git a/edxp-sandhook/build.gradle b/edxp-sandhook/build.gradle
index f1e426488..09a22a55b 100644
--- a/edxp-sandhook/build.gradle
+++ b/edxp-sandhook/build.gradle
@@ -22,13 +22,14 @@ android {
}
}
+ ndkVersion androidCompileNdkVersion
}
dependencies {
- compileOnly files("${hiddenApiStubJarFilePath}")
+ compileOnly project(':hiddenapi-stubs')
implementation project(':edxp-common')
implementation 'com.swift.sandhook:hooklib:4.2.1'
- compileOnly project(':dexmaker')
+ compileOnly files(project(":dexmaker").tasks.getByName("makeJarRelease").outputs)
}
@@ -57,23 +58,17 @@ afterEvaluate {
def variantNameCapped = variant.name.capitalize()
def variantNameLowered = variant.name.toLowerCase()
- def myTemplatePath = "${projectDir}/template_override/"
-
- task("makeAndCopy${variantNameCapped}", type: Jar, dependsOn: "assemble${variantNameCapped}") {
+ task("copyDex${variantNameCapped}", type: Copy) {
+ dependsOn "assemble${variantNameCapped}"
dependsOn tasks.getByPath(":edxp-common:copyCommonProperties")
- def dexOutPath = variant.name.contains("release") ?
- "${buildDir}/intermediates/transforms/dexMerger/${variantNameLowered}/0/" :
- "${buildDir}/intermediates/dex/${variantNameLowered}/mergeDex${variantNameCapped}/out/"
- from dexOutPath, "${projectDir}/src/main/resources/"
- destinationDir file(myTemplatePath + "system/framework/")
- baseName "edxp"
- doLast {
- copy {
- from file(myTemplatePath)
- into file(templateRootPath)
- }
+ def dexOutPath = "${buildDir}/intermediates/dex/${variantNameLowered}/minify${variantNameCapped}WithR8"
+ from (dexOutPath){
+ rename("classes.dex", "edxp.dex")
}
+ from "${projectDir}/src/main/resources/"
+ destinationDir file(templateRootPath + "system/framework/")
outputs.upToDateWhen { false }
}
+
}
}
\ No newline at end of file
diff --git a/edxp-sandhook/proguard-rules.pro b/edxp-sandhook/proguard-rules.pro
index 520e46fdc..45557eded 100644
--- a/edxp-sandhook/proguard-rules.pro
+++ b/edxp-sandhook/proguard-rules.pro
@@ -20,6 +20,7 @@
# hide the original source file name.
#-renamesourcefileattribute SourceFile
+-dontoptimize
-dontobfuscate
-keep class de.robv.android.xposed.** {*;}
-keep class android.** { *; }
@@ -32,6 +33,6 @@
-keep class com.swift.sandhook.** {*;}
--keepclasseswithmember class * {
+-keepclasseswithmembers class * {
native ;
}
\ No newline at end of file
diff --git a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/core/SandHookRouter.java b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/core/SandHookRouter.java
index 9f621f803..b5a9a792f 100644
--- a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/core/SandHookRouter.java
+++ b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/core/SandHookRouter.java
@@ -7,7 +7,6 @@
import com.elderdrivers.riru.edxp.sandhook.entry.AppBootstrapHookInfo;
import com.elderdrivers.riru.edxp.sandhook.entry.SysBootstrapHookInfo;
import com.elderdrivers.riru.edxp.sandhook.entry.SysInnerHookInfo;
-import com.elderdrivers.riru.edxp.sandhook.entry.WorkAroundHookInfo;
import com.elderdrivers.riru.edxp.sandhook.hooker.SystemMainHooker;
import com.elderdrivers.riru.edxp.util.Utils;
import com.swift.sandhook.xposedcompat.XposedCompat;
@@ -45,14 +44,6 @@ public void startSystemServerHook() {
}
}
- public void startWorkAroundHook() {
- if (useSandHook) {
- XposedCompat.addHookers(XposedBridge.BOOTCLASSLOADER, WorkAroundHookInfo.hookItems);
- } else {
- super.startWorkAroundHook();
- }
- }
-
public void onEnterChildProcess() {
SandHookXposedBridge.onForkPost();
//enable compile in child process
diff --git a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/AppBootstrapHookInfo.java b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/AppBootstrapHookInfo.java
index 35d215ca6..c976a6c25 100644
--- a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/AppBootstrapHookInfo.java
+++ b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/AppBootstrapHookInfo.java
@@ -3,11 +3,9 @@
import com.elderdrivers.riru.common.KeepMembers;
import com.elderdrivers.riru.edxp.sandhook.hooker.HandleBindAppHooker;
import com.elderdrivers.riru.edxp.sandhook.hooker.LoadedApkConstructorHooker;
-import com.elderdrivers.riru.edxp.sandhook.hooker.OnePlusWorkAroundHooker;
public class AppBootstrapHookInfo implements KeepMembers {
public static String[] hookItemNames = {
- OnePlusWorkAroundHooker.class.getName(),
HandleBindAppHooker.class.getName(),
LoadedApkConstructorHooker.class.getName(),
};
@@ -15,6 +13,5 @@ public class AppBootstrapHookInfo implements KeepMembers {
public static Class[] hookItems = {
HandleBindAppHooker.class,
LoadedApkConstructorHooker.class,
- OnePlusWorkAroundHooker.class
};
}
diff --git a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/SysBootstrapHookInfo.java b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/SysBootstrapHookInfo.java
index 434a9f344..25e9d9fc0 100644
--- a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/SysBootstrapHookInfo.java
+++ b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/SysBootstrapHookInfo.java
@@ -3,12 +3,10 @@
import com.elderdrivers.riru.common.KeepMembers;
import com.elderdrivers.riru.edxp.sandhook.hooker.HandleBindAppHooker;
import com.elderdrivers.riru.edxp.sandhook.hooker.LoadedApkConstructorHooker;
-import com.elderdrivers.riru.edxp.sandhook.hooker.OnePlusWorkAroundHooker;
import com.elderdrivers.riru.edxp.sandhook.hooker.SystemMainHooker;
public class SysBootstrapHookInfo implements KeepMembers {
public static String[] hookItemNames = {
- OnePlusWorkAroundHooker.class.getName(),
HandleBindAppHooker.class.getName(),
SystemMainHooker.class.getName(),
LoadedApkConstructorHooker.class.getName()
@@ -18,6 +16,5 @@ public class SysBootstrapHookInfo implements KeepMembers {
HandleBindAppHooker.class,
SystemMainHooker.class,
LoadedApkConstructorHooker.class,
- OnePlusWorkAroundHooker.class
};
}
diff --git a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/WorkAroundHookInfo.java b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/WorkAroundHookInfo.java
deleted file mode 100644
index cb7031bba..000000000
--- a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/entry/WorkAroundHookInfo.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.elderdrivers.riru.edxp.sandhook.entry;
-
-import com.elderdrivers.riru.common.KeepMembers;
-import com.elderdrivers.riru.edxp.sandhook.hooker.OnePlusWorkAroundHooker;
-
-public class WorkAroundHookInfo implements KeepMembers {
- public static String[] hookItemNames = {
- OnePlusWorkAroundHooker.class.getName()
- };
-
- public static Class[] hookItems = {
- OnePlusWorkAroundHooker.class
- };
-}
diff --git a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/hooker/OnePlusWorkAroundHooker.java b/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/hooker/OnePlusWorkAroundHooker.java
deleted file mode 100644
index 92089ad6f..000000000
--- a/edxp-sandhook/src/main/java/com/elderdrivers/riru/edxp/sandhook/hooker/OnePlusWorkAroundHooker.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package com.elderdrivers.riru.edxp.sandhook.hooker;
-
-import com.elderdrivers.riru.common.KeepMembers;
-import com.elderdrivers.riru.edxp._hooker.impl.OneplusWorkaround;
-import com.elderdrivers.riru.edxp.core.yahfa.HookMain;
-import com.swift.sandhook.SandHook;
-import com.swift.sandhook.annotation.HookClass;
-import com.swift.sandhook.annotation.HookMethod;
-import com.swift.sandhook.annotation.HookMethodBackup;
-import com.swift.sandhook.annotation.SkipParamCheck;
-
-import java.lang.reflect.Method;
-
-import dalvik.system.BaseDexClassLoader;
-import de.robv.android.xposed.XC_MethodHook;
-import de.robv.android.xposed.annotation.ApiSensitive;
-import de.robv.android.xposed.annotation.Level;
-
-// TODO check HOS / OOS ver.11 when available
-@ApiSensitive(Level.MIDDLE)
-@HookClass(BaseDexClassLoader.class)
-public class OnePlusWorkAroundHooker implements KeepMembers {
-
- static {
- HookMain.addHookItemWhiteList(OnePlusWorkAroundHooker.class.getName());
- }
-
- public static String className = "dalvik.system.BaseDexClassLoader";
- public static String methodName = "inCompatConfigList";
- public static String methodSig = "(ILjava/lang/String;)Z";
-
- @HookMethodBackup("inCompatConfigList")
- @SkipParamCheck
- static Method backup;
-
- @HookMethod("inCompatConfigList")
- public static boolean hook(int type, String packageName) throws Throwable {
- final XC_MethodHook methodHook = new OneplusWorkaround();
- final XC_MethodHook.MethodHookParam param = new XC_MethodHook.MethodHookParam();
- param.thisObject = null;
- param.args = new Object[]{type, packageName};
- methodHook.callBeforeHookedMethod(param);
- if (!param.returnEarly) {
- param.setResult(backup(type, packageName));
- }
- methodHook.callAfterHookedMethod(param);
- return (boolean) param.getResult();
- }
-
- public static boolean backup(int type, String packageName) throws Throwable {
- return (boolean) SandHook.callOriginByBackup(backup, null, type, packageName);
- }
-}
\ No newline at end of file
diff --git a/edxp-whale/.gitignore b/edxp-whale/.gitignore
index 845f99801..3a66a1982 100644
--- a/edxp-whale/.gitignore
+++ b/edxp-whale/.gitignore
@@ -1,2 +1,2 @@
/build
-/template_override/system/framework/edxp.jar
\ No newline at end of file
+/template_override/system/framework
\ No newline at end of file
diff --git a/edxp-whale/build.gradle b/edxp-whale/build.gradle
index 76a1d7fb2..649fec74d 100644
--- a/edxp-whale/build.gradle
+++ b/edxp-whale/build.gradle
@@ -22,12 +22,13 @@ android {
}
}
+ ndkVersion androidCompileNdkVersion
}
dependencies {
- compileOnly files("${hiddenApiStubJarFilePath}")
+ compileOnly project(':hiddenapi-stubs')
implementation project(':edxp-common')
- compileOnly project(':dexmaker')
+ compileOnly files(project(":dexmaker").tasks.getByName("makeJarRelease").outputs)
}
@@ -56,22 +57,15 @@ afterEvaluate {
def variantNameCapped = variant.name.capitalize()
def variantNameLowered = variant.name.toLowerCase()
- def myTemplatePath = "${projectDir}/template_override/"
-
- task("makeAndCopy${variantNameCapped}", type: Jar, dependsOn: "assemble${variantNameCapped}") {
+ task("copyDex${variantNameCapped}", type: Copy) {
+ dependsOn "assemble${variantNameCapped}"
dependsOn tasks.getByPath(":edxp-common:copyCommonProperties")
- def dexOutPath = variant.name.contains("release") ?
- "${buildDir}/intermediates/transforms/dexMerger/${variantNameLowered}/0/" :
- "${buildDir}/intermediates/dex/${variantNameLowered}/mergeDex${variantNameCapped}/out/"
- from dexOutPath, "${projectDir}/src/main/resources/"
- destinationDir file(myTemplatePath + "system/framework/")
- baseName "edxp"
- doLast {
- copy {
- from file(myTemplatePath)
- into file(templateRootPath)
- }
+ def dexOutPath = "${buildDir}/intermediates/dex/${variantNameLowered}/minify${variantNameCapped}WithR8"
+ from (dexOutPath){
+ rename("classes.dex", "edxp.dex")
}
+ from "${projectDir}/src/main/resources/"
+ destinationDir file(templateRootPath + "system/framework/")
outputs.upToDateWhen { false }
}
}
diff --git a/edxp-whale/proguard-rules.pro b/edxp-whale/proguard-rules.pro
index 503061cbb..a998d8b22 100644
--- a/edxp-whale/proguard-rules.pro
+++ b/edxp-whale/proguard-rules.pro
@@ -20,6 +20,7 @@
# hide the original source file name.
#-renamesourcefileattribute SourceFile
+-dontoptimize
-dontobfuscate
-keep class de.robv.android.xposed.** {*;}
-keep class android.** { *; }
@@ -32,6 +33,6 @@
-keep class com.lody.** {*;}
--keepclasseswithmember class * {
+-keepclasseswithmembers class * {
native ;
}
\ No newline at end of file
diff --git a/edxp-yahfa/.gitignore b/edxp-yahfa/.gitignore
index 845f99801..3a66a1982 100644
--- a/edxp-yahfa/.gitignore
+++ b/edxp-yahfa/.gitignore
@@ -1,2 +1,2 @@
/build
-/template_override/system/framework/edxp.jar
\ No newline at end of file
+/template_override/system/framework
\ No newline at end of file
diff --git a/edxp-yahfa/build.gradle b/edxp-yahfa/build.gradle
index f142309c1..b84ac58f8 100644
--- a/edxp-yahfa/build.gradle
+++ b/edxp-yahfa/build.gradle
@@ -22,12 +22,13 @@ android {
}
}
+ ndkVersion androidCompileNdkVersion
}
dependencies {
- compileOnly files("${hiddenApiStubJarFilePath}")
+ compileOnly project(':hiddenapi-stubs')
implementation project(':edxp-common')
- compileOnly project(':dexmaker')
+ compileOnly files(project(":dexmaker").tasks.getByName("makeJarRelease").outputs)
}
@@ -56,23 +57,17 @@ afterEvaluate {
def variantNameCapped = variant.name.capitalize()
def variantNameLowered = variant.name.toLowerCase()
- def myTemplatePath = "${projectDir}/template_override/"
-
- task("makeAndCopy${variantNameCapped}", type: Jar, dependsOn: "assemble${variantNameCapped}") {
+ task("copyDex${variantNameCapped}", type: Copy) {
+ dependsOn "assemble${variantNameCapped}"
dependsOn tasks.getByPath(":edxp-common:copyCommonProperties")
- def dexOutPath = variant.name.contains("release") ?
- "${buildDir}/intermediates/transforms/dexMerger/${variantNameLowered}/0/" :
- "${buildDir}/intermediates/dex/${variantNameLowered}/mergeDex${variantNameCapped}/out/"
- from dexOutPath, "${projectDir}/src/main/resources/"
- destinationDir file(myTemplatePath + "system/framework/")
- baseName "edxp"
- doLast {
- copy {
- from file(myTemplatePath)
- into file(templateRootPath)
- }
+ def dexOutPath = "${buildDir}/intermediates/dex/${variantNameLowered}/minify${variantNameCapped}WithR8"
+ from (dexOutPath){
+ rename("classes.dex", "edxp.dex")
}
+ from "${projectDir}/src/main/resources/"
+ destinationDir file(templateRootPath + "system/framework/")
outputs.upToDateWhen { false }
}
+
}
}
\ No newline at end of file
diff --git a/edxp-yahfa/proguard-rules.pro b/edxp-yahfa/proguard-rules.pro
index c600fee6c..50e9b7978 100644
--- a/edxp-yahfa/proguard-rules.pro
+++ b/edxp-yahfa/proguard-rules.pro
@@ -20,6 +20,7 @@
# hide the original source file name.
#-renamesourcefileattribute SourceFile
+-dontoptimize
-dontobfuscate
-keep class de.robv.android.xposed.** {*;}
-keep class android.** { *; }
@@ -30,6 +31,6 @@
-keep class * implements com.elderdrivers.riru.common.KeepAll { *; }
-keepclassmembers class * implements com.elderdrivers.riru.common.KeepMembers { *; }
--keepclasseswithmember class * {
+-keepclasseswithmembers class * {
native ;
-}
\ No newline at end of file
+}
diff --git a/edxp-yahfa/src/main/java/com/elderdrivers/riru/edxp/yahfa/core/YahfaEdxpImpl.java b/edxp-yahfa/src/main/java/com/elderdrivers/riru/edxp/yahfa/core/YahfaEdxpImpl.java
index 8a05b27dc..628dbde6c 100644
--- a/edxp-yahfa/src/main/java/com/elderdrivers/riru/edxp/yahfa/core/YahfaEdxpImpl.java
+++ b/edxp-yahfa/src/main/java/com/elderdrivers/riru/edxp/yahfa/core/YahfaEdxpImpl.java
@@ -8,7 +8,6 @@
import com.elderdrivers.riru.edxp.core.Proxy;
import com.elderdrivers.riru.edxp.core.Yahfa;
import com.elderdrivers.riru.edxp.core.yahfa.HookMethodResolver;
-import com.elderdrivers.riru.edxp.proxy.BlackWhiteListProxy;
import com.elderdrivers.riru.edxp.proxy.NormalProxy;
import com.elderdrivers.riru.edxp.proxy.Router;
@@ -35,11 +34,6 @@ public void init() {
setInitialized();
}
- @Override
- protected Proxy createBlackWhiteListProxy() {
- return new BlackWhiteListProxy(getRouter());
- }
-
@Override
protected Proxy createNormalProxy() {
return new NormalProxy(getRouter());
diff --git a/gradle.properties b/gradle.properties
index a19ed5f95..6eeb58e9e 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,3 +1,2 @@
-android.enableR8=false
-
-androidCompileSdkVersion=30
\ No newline at end of file
+androidCompileSdkVersion=30
+androidCompileNdkVersion=22.0.6917172
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 797f6b0cd..208ce983c 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Sat Apr 20 12:28:06 CST 2019
+#Fri Nov 13 15:00:57 CST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip
diff --git a/hiddenapi-stubs/.gitignore b/hiddenapi-stubs/.gitignore
index 796b96d1c..97873191d 100644
--- a/hiddenapi-stubs/.gitignore
+++ b/hiddenapi-stubs/.gitignore
@@ -1 +1,2 @@
/build
+/libs
diff --git a/hiddenapi-stubs/build.gradle b/hiddenapi-stubs/build.gradle
index beb26cf19..31adb017e 100644
--- a/hiddenapi-stubs/build.gradle
+++ b/hiddenapi-stubs/build.gradle
@@ -1,22 +1,15 @@
-import com.android.builder.core.BuilderConstants
-
apply plugin: 'com.android.library'
android {
compileSdkVersion androidCompileSdkVersion.toInteger()
+ ndkVersion androidCompileNdkVersion
}
task makeStubJar(type: Jar){
+ dependsOn assemble
baseName 'framework-stub'
- from("${projectDir}/build/intermediates/javac/release/compileReleaseJavaWithJavac/classes/")
- into('')
- destinationDir file("${projectDir}/libs")
+ from("${buildDir}/intermediates/javac/release/classes/")
exclude('BuildConfig.class', 'R.class')
exclude{ it.name.startsWith('R$')}
-}
-
-afterEvaluate {
- tasks.withType(JavaCompile) {
- it.finalizedBy(makeStubJar)
- }
+ outputs.file(archivePath)
}
diff --git a/hiddenapi-stubs/libs/framework-stub.jar b/hiddenapi-stubs/libs/framework-stub.jar
deleted file mode 100644
index 2c94a740a..000000000
Binary files a/hiddenapi-stubs/libs/framework-stub.jar and /dev/null differ
diff --git a/xposed-bridge/build.gradle b/xposed-bridge/build.gradle
index a4ed4a4a4..831afc029 100644
--- a/xposed-bridge/build.gradle
+++ b/xposed-bridge/build.gradle
@@ -2,7 +2,7 @@ apply plugin: 'com.android.library'
android {
compileSdkVersion androidCompileSdkVersion.toInteger()
- buildToolsVersion '28.0.3'
+ ndkVersion androidCompileNdkVersion
defaultConfig {
minSdkVersion 26
@@ -39,8 +39,8 @@ preBuild.doLast {
}
dependencies {
- compileOnly project(':hiddenapi-stubs')
- compileOnly project(':dexmaker')
+ compileOnly files(project(":dexmaker").tasks.getByName("makeJarRelease").outputs)
+ compileOnly files(project(":hiddenapi-stubs").tasks.getByName("makeStubJar").outputs)
}
afterEvaluate {
diff --git a/xposed-bridge/proguard-rules.pro b/xposed-bridge/proguard-rules.pro
index e72d685a6..867f79750 100644
--- a/xposed-bridge/proguard-rules.pro
+++ b/xposed-bridge/proguard-rules.pro
@@ -21,5 +21,6 @@
#-renamesourcefileattribute SourceFile
-dontobfuscate
+-dontoptimize
-keep class de.robv.android.xposed.** {*;}
-keep class android.** { *; }
\ No newline at end of file
diff --git a/xposed-bridge/src/main/java/com/elderdrivers/riru/edxp/config/EdxpConfig.java b/xposed-bridge/src/main/java/com/elderdrivers/riru/edxp/config/EdxpConfig.java
index a8959cfd9..58e6d3410 100644
--- a/xposed-bridge/src/main/java/com/elderdrivers/riru/edxp/config/EdxpConfig.java
+++ b/xposed-bridge/src/main/java/com/elderdrivers/riru/edxp/config/EdxpConfig.java
@@ -21,4 +21,6 @@ public interface EdxpConfig {
boolean isResourcesHookEnabled();
boolean isBlackWhiteListMode();
+
+ String getModulesList();
}
diff --git a/xposed-bridge/src/main/java/de/robv/android/xposed/XposedBridge.java b/xposed-bridge/src/main/java/de/robv/android/xposed/XposedBridge.java
index 79dc3f7b5..103bea8cd 100644
--- a/xposed-bridge/src/main/java/de/robv/android/xposed/XposedBridge.java
+++ b/xposed-bridge/src/main/java/de/robv/android/xposed/XposedBridge.java
@@ -146,7 +146,7 @@ public static void initXResources() {
*/
public static int getXposedVersion() {
// ed: fixed value for now
- return 91;
+ return 92;
}
/**
diff --git a/xposed-bridge/src/main/java/de/robv/android/xposed/XposedInit.java b/xposed-bridge/src/main/java/de/robv/android/xposed/XposedInit.java
index 51169f4d0..3d63c66a6 100644
--- a/xposed-bridge/src/main/java/de/robv/android/xposed/XposedInit.java
+++ b/xposed-bridge/src/main/java/de/robv/android/xposed/XposedInit.java
@@ -17,10 +17,12 @@
import com.elderdrivers.riru.edxp.config.EdXpConfigGlobal;
import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
+import java.io.StringBufferInputStream;
import java.lang.ref.WeakReference;
import java.lang.reflect.Method;
import java.util.ArrayList;
@@ -307,38 +309,21 @@ private static boolean needsToCloseFilesForFork() {
private static final Object moduleLoadLock = new Object();
// @GuardedBy("moduleLoadLock")
private static final ArraySet loadedModules = new ArraySet<>();
- // @GuardedBy("moduleLoadLock")
- private static long lastModuleListModifiedTime = -1;
- public static boolean loadModules(boolean isInZygote, boolean callInitZygote) throws IOException {
+ public static boolean loadModules(boolean callInitZygote) throws IOException {
boolean hasLoaded = !modulesLoaded.compareAndSet(false, true);
if (hasLoaded && !EdXpConfigGlobal.getConfig().isDynamicModulesMode()) {
return false;
}
synchronized (moduleLoadLock) {
- final String filename = EdXpConfigGlobal.getConfig().getInstallerConfigPath("modules.list");
- BaseService service = SELinuxHelper.getAppDataFileService();
- if (!service.checkFileExists(filename)) {
- Log.e(TAG, "Cannot load any modules because " + filename + " was not found");
- // FIXME module list is cleared but never could be reload again
- // when using dynamic-module-list under multi-user environment
- clearAllCallbacks();
- return false;
- }
-
- long moduleListModifiedTime = service.getFileModificationTime(filename);
- if (lastModuleListModifiedTime == moduleListModifiedTime) {
- // module list has not changed
- return false;
- }
-
ClassLoader topClassLoader = XposedBridge.BOOTCLASSLOADER;
ClassLoader parent;
while ((parent = topClassLoader.getParent()) != null) {
topClassLoader = parent;
}
- InputStream stream = service.getFileInputStream(filename);
+ String moduleList = EdXpConfigGlobal.getConfig().getModulesList();
+ InputStream stream = new ByteArrayInputStream(moduleList.getBytes());
BufferedReader apks = new BufferedReader(new InputStreamReader(stream));
ArraySet newLoadedApk = new ArraySet<>();
String apk;
@@ -358,9 +343,6 @@ public static boolean loadModules(boolean isInZygote, boolean callInitZygote) th
// refresh callback according to current loaded module list
pruneCallbacks(loadedModules);
-
- lastModuleListModifiedTime = moduleListModifiedTime;
-
}
return true;
}