Move libxposed to a standalone gradle module
This commit is contained in:
parent
439537fd89
commit
53d75bd10e
|
|
@ -0,0 +1 @@
|
||||||
|
/build
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
plugins {
|
||||||
|
id("java-library")
|
||||||
|
}
|
||||||
|
|
||||||
|
java {
|
||||||
|
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||||
|
targetCompatibility = JavaVersion.VERSION_1_8
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compileOnly("androidx.annotation:annotation:1.5.0")
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package android.content;
|
||||||
|
|
||||||
|
public abstract class Context {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
package android.content;
|
||||||
|
|
||||||
|
public class ContextWrapper extends Context {
|
||||||
|
public ContextWrapper(Context base) {
|
||||||
|
throw new UnsupportedOperationException("STUB");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void attachBaseContext(Context base) {
|
||||||
|
throw new UnsupportedOperationException("STUB");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Context getBaseContext() {
|
||||||
|
throw new UnsupportedOperationException("SUTB");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package android.content.pm;
|
||||||
|
|
||||||
|
public class ApplicationInfo {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package android.content.res;
|
||||||
|
|
||||||
|
public class AssetManager {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package android.content.res;
|
||||||
|
|
||||||
|
public class Configuration {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
package android.content.res;
|
||||||
|
|
||||||
|
import android.util.DisplayMetrics;
|
||||||
|
|
||||||
|
public class Resources {
|
||||||
|
protected Resources(ClassLoader classLoader) {
|
||||||
|
throw new UnsupportedOperationException("STUB");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Resources(AssetManager assets, DisplayMetrics metrics, Configuration config) {
|
||||||
|
throw new UnsupportedOperationException("STUB");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
package android.content.res;
|
||||||
|
|
||||||
|
public class TypedArray {
|
||||||
|
protected TypedArray(Resources resources) {
|
||||||
|
throw new UnsupportedOperationException("STUB");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package android.os;
|
||||||
|
|
||||||
|
public class Bundle {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
package android.util;
|
||||||
|
|
||||||
|
public class DisplayMetrics {
|
||||||
|
}
|
||||||
|
|
@ -110,7 +110,8 @@ public interface XposedInterface {
|
||||||
|
|
||||||
<T> boolean deoptimize(@Nullable Constructor<T> constructor);
|
<T> boolean deoptimize(@Nullable Constructor<T> constructor);
|
||||||
|
|
||||||
@Nullable XposedUtils getUtils();
|
@Nullable
|
||||||
|
XposedUtils getUtils();
|
||||||
|
|
||||||
void log(@NonNull String message);
|
void log(@NonNull String message);
|
||||||
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
package io.github.libxposed;
|
package io.github.libxposed;
|
||||||
|
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.content.res.XposedResources;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
@ -1,14 +1,16 @@
|
||||||
package android.content.res;
|
package io.github.libxposed;
|
||||||
|
|
||||||
|
import android.content.res.AssetManager;
|
||||||
|
import android.content.res.Configuration;
|
||||||
|
import android.content.res.Resources;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
|
|
||||||
public abstract class XposedResources extends Resources {
|
public abstract class XposedResources extends Resources {
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public XposedResources(AssetManager assets, DisplayMetrics metrics, Configuration config) {
|
public XposedResources(AssetManager assets, DisplayMetrics metrics, Configuration config) {
|
||||||
super(assets, metrics, config);
|
super(assets, metrics, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
public XposedResources(ClassLoader classLoader) {
|
public XposedResources(ClassLoader classLoader) {
|
||||||
super(null, null, null);
|
super(classLoader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
package io.github.libxposed;
|
||||||
|
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.content.res.TypedArray;
|
||||||
|
|
||||||
|
public class XposedTypedArray extends TypedArray {
|
||||||
|
public XposedTypedArray(Resources resources) {
|
||||||
|
super(resources);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -17,17 +17,6 @@
|
||||||
* Copyright (C) 2021 - 2022 LSPosed Contributors
|
* 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 apiCode: Int by rootProject.extra
|
||||||
val verName: String by rootProject.extra
|
val verName: String by rootProject.extra
|
||||||
val verCode: Int by rootProject.extra
|
val verCode: Int by rootProject.extra
|
||||||
|
|
@ -64,112 +53,6 @@ copy {
|
||||||
into("src/main/jni/src/")
|
into("src/main/jni/src/")
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class ExampleClassVisitorFactory : AsmClassVisitorFactory<InstrumentationParameters.None> {
|
|
||||||
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<out String>?
|
|
||||||
) {
|
|
||||||
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<out String>?
|
|
||||||
): 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) {
|
|
||||||
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 {
|
dependencies {
|
||||||
implementation("org.apache.commons:commons-lang3:3.12.0")
|
implementation("org.apache.commons:commons-lang3:3.12.0")
|
||||||
implementation("de.upb.cs.swt:axml:2.1.3")
|
implementation("de.upb.cs.swt:axml:2.1.3")
|
||||||
|
|
@ -178,4 +61,5 @@ dependencies {
|
||||||
implementation(projects.hiddenapi.bridge)
|
implementation(projects.hiddenapi.bridge)
|
||||||
implementation(projects.services.daemonService)
|
implementation(projects.services.daemonService)
|
||||||
implementation(projects.services.managerService)
|
implementation(projects.services.managerService)
|
||||||
|
implementation(projects.api)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,8 @@ import de.robv.android.xposed.XposedInit;
|
||||||
import de.robv.android.xposed.callbacks.XC_LayoutInflated;
|
import de.robv.android.xposed.callbacks.XC_LayoutInflated;
|
||||||
import de.robv.android.xposed.callbacks.XC_LayoutInflated.LayoutInflatedParam;
|
import de.robv.android.xposed.callbacks.XC_LayoutInflated.LayoutInflatedParam;
|
||||||
import de.robv.android.xposed.callbacks.XCallback;
|
import de.robv.android.xposed.callbacks.XCallback;
|
||||||
import xposed.dummy.XTypedArraySuperClass;
|
import io.github.libxposed.XposedResources;
|
||||||
|
import io.github.libxposed.XposedTypedArray;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link android.content.res.Resources} subclass that allows replacing individual resources.
|
* {@link android.content.res.Resources} subclass that allows replacing individual resources.
|
||||||
|
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
package android.content.res;
|
|
||||||
|
|
||||||
public class XposedTypedArray extends TypedArray {
|
|
||||||
public XposedTypedArray(Resources resources) {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -21,7 +21,6 @@
|
||||||
package de.robv.android.xposed.callbacks;
|
package de.robv.android.xposed.callbacks;
|
||||||
|
|
||||||
import android.content.res.XResources;
|
import android.content.res.XResources;
|
||||||
import android.content.res.XposedResources;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
@ -31,6 +30,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
|
|
||||||
import de.robv.android.xposed.IXposedHookInitPackageResources;
|
import de.robv.android.xposed.IXposedHookInitPackageResources;
|
||||||
import io.github.libxposed.XposedModuleInterface;
|
import io.github.libxposed.XposedModuleInterface;
|
||||||
|
import io.github.libxposed.XposedResources;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is only used for internal purposes, except for the {@link InitPackageResourcesParam}
|
* This class is only used for internal purposes, except for the {@link InitPackageResourcesParam}
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,15 @@ import org.apache.tools.ant.filters.ReplaceTokens
|
||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
import java.security.MessageDigest
|
import java.security.MessageDigest
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
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
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("com.android.application")
|
id("com.android.application")
|
||||||
|
|
@ -321,5 +330,94 @@ task<Exec>("reRunApp") {
|
||||||
finalizedBy(reRunDaemon)
|
finalizedBy(reRunDaemon)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class ExampleClassVisitorFactory :
|
||||||
|
AsmClassVisitorFactory<InstrumentationParameters.None> {
|
||||||
|
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<out String>?
|
||||||
|
) {
|
||||||
|
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<out String>?
|
||||||
|
): MethodVisitor {
|
||||||
|
return object : MethodVisitor(
|
||||||
|
Opcodes.ASM9, super.visitMethod(
|
||||||
|
access,
|
||||||
|
name,
|
||||||
|
descriptor,
|
||||||
|
signature,
|
||||||
|
exceptions
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
override fun visitMethodInsn(
|
||||||
|
opcode: Int,
|
||||||
|
owner: String?,
|
||||||
|
name: String?,
|
||||||
|
instDescriptor: String?,
|
||||||
|
isInterface: Boolean
|
||||||
|
) {
|
||||||
|
if (opcode == Opcodes.INVOKESPECIAL) {
|
||||||
|
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 == "io.github.libxposed.XposedResources" || classData.className == "io.github.libxposed.XposedTypedArray"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
androidComponents.onVariants { variant ->
|
||||||
|
variant.instrumentation.transformClassesWith(
|
||||||
|
ExampleClassVisitorFactory::class.java, InstrumentationScope.ALL
|
||||||
|
) {}
|
||||||
|
variant.instrumentation.setAsmFramesComputationMode(FramesComputationMode.COPY_FRAMES)
|
||||||
|
}
|
||||||
|
|
||||||
evaluationDependsOn(":app")
|
evaluationDependsOn(":app")
|
||||||
evaluationDependsOn(":daemon")
|
evaluationDependsOn(":daemon")
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ dependencyResolutionManagement {
|
||||||
rootProject.name = "LSPosed"
|
rootProject.name = "LSPosed"
|
||||||
include(
|
include(
|
||||||
":app",
|
":app",
|
||||||
|
":api",
|
||||||
":core",
|
":core",
|
||||||
":daemon",
|
":daemon",
|
||||||
":dex2oat",
|
":dex2oat",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue