Add support for switching between compat mode and speed mode (the latter as default)

This commit is contained in:
solohsu 2019-01-29 18:33:18 +08:00
parent 258d40d01f
commit 0e88cee282
3 changed files with 31 additions and 14 deletions

View File

@ -1,14 +1,37 @@
package com.elderdrivers.riru.xposed.dexmaker;
import external.com.android.dx.Code;
import external.com.android.dx.Local;
import external.com.android.dx.TypeId;
import android.app.AndroidAppHelper;
import android.os.Build;
import android.text.TextUtils;
import com.elderdrivers.riru.xposed.Main;
import java.util.HashMap;
import java.util.Map;
import de.robv.android.xposed.SELinuxHelper;
import external.com.android.dx.Code;
import external.com.android.dx.Local;
import external.com.android.dx.TypeId;
public class DexMakerUtils {
private static final boolean IN_MEMORY_DEX_ELIGIBLE = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
private static final String COMPAT_LIST_PATH = "/data/misc/riru/modules/edxposed/compatlist/";
public static boolean shouldUseInMemoryHook() {
if (!IN_MEMORY_DEX_ELIGIBLE) {
return false;
}
String packageName = AndroidAppHelper.currentPackageName();
if (TextUtils.isEmpty(packageName)) { //default to true
DexLog.w("packageName is empty, processName=" + Main.sAppProcessName
+ ", appDataDir=" + Main.sAppDataDir);
return true;
}
return !SELinuxHelper.getAppDataFileService().checkFileExists(COMPAT_LIST_PATH + packageName);
}
public static void autoBoxIfNecessary(Code code, Local<Object> target, Local source) {
String boxMethod = "valueOf";
TypeId<?> boxTypeId;
@ -99,7 +122,7 @@ public class DexMakerUtils {
code.invokeVirtual(boxTypeId.getMethod(TypeId.SHORT, unboxMethod), target, boxTypedLocal);
} else if (typeId.equals(TypeId.VOID)) {
code.loadConstant(target, null);
} else if (castObj){
} else if (castObj) {
code.cast(target, source);
} else {
code.move(target, source);

View File

@ -16,7 +16,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
import de.robv.android.xposed.XposedBridge;
import static com.elderdrivers.riru.xposed.dexmaker.HookerDexMaker.SHOULD_USE_IN_MEMORY_DEX;
import static com.elderdrivers.riru.xposed.dexmaker.DexMakerUtils.shouldUseInMemoryHook;
import static com.elderdrivers.riru.xposed.util.FileUtils.getDataPathPrefix;
public final class DynamicBridge {
@ -50,7 +50,7 @@ public final class DynamicBridge {
DexLog.d("start to generate class for: " + hookMethod);
try {
// for Android Oreo and later use InMemoryClassLoader
if (!SHOULD_USE_IN_MEMORY_DEX) {
if (!shouldUseInMemoryHook()) {
// under Android Oreo, using DexClassLoader
if (dexPathInited.compareAndSet(false, true)) {
// delete previous compiled dex to prevent potential crashing

View File

@ -1,6 +1,5 @@
package com.elderdrivers.riru.xposed.dexmaker;
import android.os.Build;
import android.text.TextUtils;
import com.elderdrivers.riru.xposed.core.HookMain;
@ -31,15 +30,10 @@ import static com.elderdrivers.riru.xposed.dexmaker.DexMakerUtils.autoBoxIfNeces
import static com.elderdrivers.riru.xposed.dexmaker.DexMakerUtils.autoUnboxIfNecessary;
import static com.elderdrivers.riru.xposed.dexmaker.DexMakerUtils.createResultLocals;
import static com.elderdrivers.riru.xposed.dexmaker.DexMakerUtils.getObjTypeIdIfPrimitive;
import static com.elderdrivers.riru.xposed.dexmaker.DexMakerUtils.shouldUseInMemoryHook;
public class HookerDexMaker {
public static final boolean IN_MEMORY_DEX_ELIGIBLE = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
// using InMemoryDexClassLoader when too many methods (about >175 ?)
// are to hook might lead to large memory allocation and gc problems, forbid it for now
public static final boolean IN_MEMORY_DEX_FORBIDDEN = true;
public static final boolean SHOULD_USE_IN_MEMORY_DEX = IN_MEMORY_DEX_ELIGIBLE && !IN_MEMORY_DEX_FORBIDDEN;
public static final String METHOD_NAME_BACKUP = "backup";
public static final String METHOD_NAME_HOOK = "hook";
public static final String METHOD_NAME_CALL_BACKUP = "callBackup";
@ -199,7 +193,7 @@ public class HookerDexMaker {
generateCallBackupMethod();
ClassLoader loader;
if (SHOULD_USE_IN_MEMORY_DEX) {
if (shouldUseInMemoryHook()) {
// in memory dex classloader
byte[] dexBytes = mDexMaker.generate();
loader = new InMemoryDexClassLoader(ByteBuffer.wrap(dexBytes), mAppClassLoader);