Skip to content

Commit

Permalink
Load XResources's dex data from memory
Browse files Browse the repository at this point in the history
  • Loading branch information
canyie committed Jan 25, 2021
1 parent 58f766b commit d2dd846
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 7 deletions.
25 changes: 22 additions & 3 deletions app/src/main/java/top/canyie/dreamland/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

import androidx.annotation.Keep;

import dalvik.system.InMemoryDexClassLoader;
import dalvik.system.PathClassLoader;
import de.robv.android.xposed.DexCreator;
import de.robv.android.xposed.XposedBridge;
import top.canyie.dreamland.core.Dreamland;
Expand All @@ -35,6 +37,7 @@
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.nio.ByteBuffer;

import mirror.android.app.ActivityThread;
import mirror.android.os.ServiceManager;
Expand Down Expand Up @@ -140,10 +143,11 @@ public static int init() {
return 1;
}

@SuppressLint("NewApi")
private static void initXResources(ClassLoader myCL) throws Exception {
Resources res = Resources.getSystem();
String dexForXResources = ensureSuperDexFor("XResources", res.getClass(), Resources.class);

Class resClass = res.getClass();
Class<?> taClass = TypedArray.class;
try {
TypedArray ta = res.obtainTypedArray(res.getIdentifier("preloaded_drawables", "array", "android"));
Expand All @@ -153,10 +157,25 @@ private static void initXResources(ClassLoader myCL) throws Exception {
XposedBridge.log(e);
}

String dexForXTypedArray = ensureSuperDexFor("XTypedArray", taClass, TypedArray.class);
ClassLoader dummy;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// Load dex from memory to prevent some detections
RuntimeUtils.makeExtendable(resClass);
RuntimeUtils.makeExtendable(taClass);
ByteBuffer dexForXResources = DexCreator.create("XResources", resClass);
ByteBuffer dexForXTypedArray = DexCreator.create("XTypedArray", taClass);
ByteBuffer[] buffers = new ByteBuffer[] {
dexForXResources, dexForXTypedArray
};
dummy = new InMemoryDexClassLoader(buffers, myCL.getParent());
} else {
String dexForXResources = ensureSuperDexFor("XResources", resClass, Resources.class);
String dexForXTypedArray = ensureSuperDexFor("XTypedArray", taClass, TypedArray.class);
dummy = new PathClassLoader(dexForXResources + File.pathSeparator + dexForXTypedArray, myCL.getParent());
}

// Inject a ClassLoader for the created classes as parent of XposedBridge's ClassLoader.
RuntimeUtils.injectDex(myCL, dexForXResources + File.pathSeparator + dexForXTypedArray);
RuntimeUtils.setParent(myCL, dummy);

// native initialize resources hook.
// this must be executed after XResourcesSuperClass is created,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import androidx.annotation.NonNull;

import java.lang.reflect.Modifier;
import dalvik.system.PathClassLoader;

import top.canyie.dreamland.utils.reflect.Reflection;

/**
Expand All @@ -26,8 +26,7 @@ public static void makeExtendable(Class<?> c) {
}
}

public static void injectDex(@NonNull ClassLoader target, @NonNull String path) {
PathClassLoader dummy = new PathClassLoader(path, target.getParent());
parent.setValue(target, dummy);
public static void setParent(@NonNull ClassLoader target, @NonNull ClassLoader newParent) {
parent.setValue(target, newParent);
}
}

0 comments on commit d2dd846

Please sign in to comment.