From 265d8e7e768ae3e918e634b88db791316a75e7db Mon Sep 17 00:00:00 2001 From: LoveSy Date: Mon, 2 Jan 2023 01:15:16 +0800 Subject: [PATCH] Refine XposedResources --- core/build.gradle.kts | 119 ++++++++++++++++++ .../java/android/content/res/XResources.java | 1 - .../android/content/res/XposedResources.java | 14 +++ .../android/content/res/XposedTypedArray.java | 7 ++ .../libxposed/XposedModuleInterface.java | 1 + .../io/github/libxposed/XposedResources.java | 16 --- 6 files changed, 141 insertions(+), 17 deletions(-) create mode 100644 core/src/main/java/android/content/res/XposedResources.java create mode 100644 core/src/main/java/android/content/res/XposedTypedArray.java delete mode 100644 core/src/main/java/io/github/libxposed/XposedResources.java diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 9d105deb..c05b3305 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -17,6 +17,17 @@ * Copyright (C) 2021 - 2022 LSPosed Contributors */ +import com.android.build.api.instrumentation.AsmClassVisitorFactory +import com.android.build.api.instrumentation.ClassContext +import com.android.build.api.instrumentation.ClassData +import com.android.build.api.instrumentation.InstrumentationParameters +import com.android.build.api.instrumentation.InstrumentationScope +import com.android.build.api.instrumentation.FramesComputationMode +import org.objectweb.asm.ClassVisitor +import org.objectweb.asm.MethodVisitor +import org.objectweb.asm.Opcodes +import org.objectweb.asm.Type + val apiCode: Int by rootProject.extra val verName: String by rootProject.extra val verCode: Int by rootProject.extra @@ -45,6 +56,7 @@ android { } } } + copy { from("src/main/jni/template/") { expand("VERSION_CODE" to "$verCode", "VERSION_NAME" to verName) @@ -52,6 +64,113 @@ copy { into("src/main/jni/src/") } +abstract class ExampleClassVisitorFactory : AsmClassVisitorFactory { + override fun createClassVisitor( + classContext: ClassContext, nextClassVisitor: ClassVisitor + ): ClassVisitor { + return object : ClassVisitor(Opcodes.ASM9, nextClassVisitor) { + override fun visit( + version: Int, + access: Int, + name: String?, + signature: String?, + superName: String?, + interfaces: Array? + ) { + val newSuperName = "xposed/dummy/X${superName?.substringAfterLast('/')}SuperClass" + println("replace super class of $name to $newSuperName") + super.visit( + version, + access, + name, + signature, + newSuperName, + interfaces + ) + } + + override fun visitMethod( + access: Int, + name: String?, + descriptor: String?, + signature: String?, + exceptions: Array? + ): MethodVisitor { + return object : MethodVisitor( + Opcodes.ASM9, super.visitMethod( + access, + name, + descriptor, + signature, + exceptions + ) + ) { + override fun visitVarInsn(opcode: Int, `var`: Int) { + } + + override fun visitInsn(opcode: Int) { + if (opcode != Opcodes.ACONST_NULL) { + super.visitInsn(opcode) + } + } + + override fun visitMaxs(maxStack: Int, maxLocals: Int) { + super.visitMaxs( + if (maxLocals > maxStack) maxLocals else maxStack, + maxLocals + ) + } + + override fun visitMethodInsn( + opcode: Int, + owner: String?, + name: String?, + instDescriptor: String?, + isInterface: Boolean + ) { + if (opcode == Opcodes.INVOKESPECIAL) { + for (i in 0 .. Type.getMethodType(descriptor).argumentTypes.size) { + println("load param $i") + super.visitVarInsn(Opcodes.ALOAD, i) + } + val newOwner = + "xposed/dummy/X${owner?.substringAfterLast('/')}SuperClass" + println("replace method call of $owner.$name$instDescriptor to $newOwner.$name$descriptor") + super.visitMethodInsn( + opcode, + newOwner, + name, + descriptor, + isInterface + ) + } else { + super.visitMethodInsn( + opcode, + owner, + name, + instDescriptor, + isInterface + ) + } + } + } + } + } + } + + override fun isInstrumentable(classData: ClassData): Boolean { + return classData.className.startsWith("android.content.res.Xposed") + } +} + + +androidComponents.onVariants { variant -> + variant.instrumentation.transformClassesWith( + ExampleClassVisitorFactory::class.java, InstrumentationScope.PROJECT + ) {} + variant.instrumentation.setAsmFramesComputationMode(FramesComputationMode.COPY_FRAMES) +} + dependencies { implementation("org.apache.commons:commons-lang3:3.12.0") implementation("de.upb.cs.swt:axml:2.1.3") diff --git a/core/src/main/java/android/content/res/XResources.java b/core/src/main/java/android/content/res/XResources.java index 75fd3ccf..d9ae8fd7 100644 --- a/core/src/main/java/android/content/res/XResources.java +++ b/core/src/main/java/android/content/res/XResources.java @@ -66,7 +66,6 @@ import de.robv.android.xposed.XposedInit; import de.robv.android.xposed.callbacks.XC_LayoutInflated; import de.robv.android.xposed.callbacks.XC_LayoutInflated.LayoutInflatedParam; import de.robv.android.xposed.callbacks.XCallback; -import io.github.libxposed.XposedResources; import xposed.dummy.XTypedArraySuperClass; /** diff --git a/core/src/main/java/android/content/res/XposedResources.java b/core/src/main/java/android/content/res/XposedResources.java new file mode 100644 index 00000000..60a29118 --- /dev/null +++ b/core/src/main/java/android/content/res/XposedResources.java @@ -0,0 +1,14 @@ +package android.content.res; + +import android.util.DisplayMetrics; + +public abstract class XposedResources extends Resources { + @SuppressWarnings("deprecation") + public XposedResources(AssetManager assets, DisplayMetrics metrics, Configuration config) { + super(assets, metrics, config); + } + + public XposedResources(ClassLoader classLoader) { + super(null, null, null); + } +} diff --git a/core/src/main/java/android/content/res/XposedTypedArray.java b/core/src/main/java/android/content/res/XposedTypedArray.java new file mode 100644 index 00000000..1309a845 --- /dev/null +++ b/core/src/main/java/android/content/res/XposedTypedArray.java @@ -0,0 +1,7 @@ +package android.content.res; + +public class XposedTypedArray extends TypedArray { + public XposedTypedArray(Resources resources) { + super(); + } +} diff --git a/core/src/main/java/io/github/libxposed/XposedModuleInterface.java b/core/src/main/java/io/github/libxposed/XposedModuleInterface.java index 6eafa329..32bf8b24 100644 --- a/core/src/main/java/io/github/libxposed/XposedModuleInterface.java +++ b/core/src/main/java/io/github/libxposed/XposedModuleInterface.java @@ -1,6 +1,7 @@ package io.github.libxposed; import android.content.pm.ApplicationInfo; +import android.content.res.XposedResources; import android.os.Bundle; import androidx.annotation.NonNull; diff --git a/core/src/main/java/io/github/libxposed/XposedResources.java b/core/src/main/java/io/github/libxposed/XposedResources.java deleted file mode 100644 index 5e3cf5a6..00000000 --- a/core/src/main/java/io/github/libxposed/XposedResources.java +++ /dev/null @@ -1,16 +0,0 @@ -package io.github.libxposed; - -import xposed.dummy.XResourcesSuperClass; - -public abstract class XposedResources extends XResourcesSuperClass { - /** Dummy, will never be called (objects are transferred to this class only). */ - protected XposedResources() { - super(); - throw new UnsupportedOperationException(); - } - - protected XposedResources(ClassLoader classLoader) { - super(classLoader); - throw new UnsupportedOperationException(); - } -}