Implement some xposed utils

This commit is contained in:
LoveSy 2023-01-04 10:56:34 +08:00 committed by LoveSy
parent c77617c3e1
commit 58665b3105
6 changed files with 92 additions and 25 deletions

View File

@ -103,7 +103,7 @@ public abstract class XC_MethodHook extends XCallback {
/**
* Wraps information about the method call and allows to influence it.
*/
public static final class MethodHookParam <T> extends XCallback.Param implements XposedInterface.BeforeHookCallback<T>, XposedInterface.AfterHookCallback<T> {
public static final class MethodHookParam <T extends Executable> extends XCallback.Param implements XposedInterface.BeforeHookCallback<T>, XposedInterface.AfterHookCallback<T> {
/**
* @hide
*/
@ -115,7 +115,7 @@ public abstract class XC_MethodHook extends XCallback {
/**
* The hooked method/constructor.
*/
public Member method;
public T method;
/**
* The {@code this} reference for an instance method, or {@code null} for static methods.
@ -193,7 +193,7 @@ public abstract class XC_MethodHook extends XCallback {
@NonNull
@Override
public T getOrigin() {
return (T) method;
return method;
}
@Nullable
@ -208,6 +208,17 @@ public abstract class XC_MethodHook extends XCallback {
return args;
}
@Nullable
@Override
public <U> U getArg(int index) {
return (U) args[index];
}
@Override
public <U> void setArg(int index, U value) {
args[index] = value;
}
@Override
public void returnAndSkip(@Nullable Object returnValue) {
setResult(returnValue);
@ -221,7 +232,13 @@ public abstract class XC_MethodHook extends XCallback {
@Nullable
@Override
public Object invokeOrigin(@Nullable Object thisObject, Object[] args) throws InvocationTargetException, IllegalAccessException {
return HookBridge.invokeOriginalMethod((Executable) method, thisObject, args);
return HookBridge.invokeOriginalMethod(method, thisObject, args);
}
@Nullable
@Override
public Object invokeOrigin() throws InvocationTargetException, IllegalAccessException {
return HookBridge.invokeOriginalMethod(method, thisObject, args);
}
@Nullable

View File

@ -396,7 +396,7 @@ public final class XposedBridge {
}
}
public static class AdditionalHookInfo<T> {
public static class AdditionalHookInfo<T extends Executable> {
private final Object params;
private AdditionalHookInfo(Executable method) {
@ -421,7 +421,7 @@ public final class XposedBridge {
var array = ((Object[]) params);
var method = (Executable) array[0];
var method = (T) array[0];
var returnType = (Class<?>) array[1];
var isStatic = (Boolean) array[2];

View File

@ -51,7 +51,6 @@ import java.io.FileOutputStream;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Executable;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
@ -59,7 +58,6 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.XposedInit;
@ -762,14 +760,14 @@ public class LSPosedContext extends XposedContext {
private <T, U extends Executable> MethodUnhooker<T, U> doHook(U hookMethod, int priority, T callback) {
if (Modifier.isAbstract(hookMethod.getModifiers())) {
throw new IllegalArgumentException("Cannot hook abstract methods: " + hookMethod);
} else if (hookMethod.getDeclaringClass().getClassLoader() == XposedBridge.class.getClassLoader()) {
} else if (hookMethod.getDeclaringClass().getClassLoader() == LSPosedContext.class.getClassLoader()) {
throw new IllegalArgumentException("Do not allow hooking inner methods");
} else if (hookMethod.getDeclaringClass() == Method.class && hookMethod.getName().equals("invoke")) {
throw new IllegalArgumentException("Cannot hook Method.invoke");
}
if (callback == null) {
throw new IllegalArgumentException("callback should not be null!");
throw new IllegalArgumentException("hooker should not be null!");
}
if (HookBridge.hookMethod(hookMethod, XposedBridge.AdditionalHookInfo.class, priority, callback)) {
@ -857,7 +855,7 @@ public class LSPosedContext extends XposedContext {
return doHook(origin, priority, hooker);
}
private static boolean deoptimize(@NonNull Executable method) {
private static boolean doDeoptimize(@NonNull Executable method) {
if (Modifier.isAbstract(method.getModifiers())) {
throw new IllegalArgumentException("Cannot deoptimize abstract methods: " + method);
} else if (Proxy.isProxyClass(method.getDeclaringClass())) {
@ -868,12 +866,12 @@ public class LSPosedContext extends XposedContext {
@Override
public boolean deoptimize(@NonNull Method method) {
return deoptimize((Executable) method);
return doDeoptimize(method);
}
@Override
public <T> boolean deoptimize(@NonNull Constructor<T> constructor) {
return deoptimize((Executable) constructor);
return doDeoptimize(constructor);
}
@Nullable

View File

@ -3,6 +3,11 @@ package org.lsposed.lspd.impl;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.apache.commons.lang3.ClassUtils;
import java.lang.reflect.Field;
import de.robv.android.xposed.XposedHelpers;
import io.github.libxposed.XposedUtils;
public class LSPosedUtils implements XposedUtils {
@ -14,25 +19,53 @@ public class LSPosedUtils implements XposedUtils {
@NonNull
@Override
public <T> Class<T> classByName(@NonNull String className, @Nullable ClassLoader classLoader) throws ClassNotFoundException {
throw new AbstractMethodError();
public <T> Class<T> findClass(@NonNull String className, @Nullable ClassLoader classLoader) throws ClassNotFoundException {
return (Class<T>) ClassUtils.getClass(classLoader, className.replace('/', '.'), false);
}
@Nullable
@Override
public <T> Class<T> classOrNullByName(@NonNull String className, @Nullable ClassLoader classLoader) {
throw new AbstractMethodError();
public <T> Class<T> findClassOrNull(@NonNull String className, @Nullable ClassLoader classLoader) {
try {
return findClass(className, classLoader);
} catch (ClassNotFoundException e) {
return null;
}
}
@NonNull
@Override
public <T> Class<T> classByBinaryName(@NonNull String binaryClassName, @Nullable ClassLoader classLoader) throws ClassNotFoundException {
throw new AbstractMethodError();
public Field findField(@NonNull Class<?> clazz, @NonNull String fieldName) throws NoSuchFieldException {
try {
return XposedHelpers.findField(clazz, fieldName);
} catch (NoSuchFieldError e) {
throw new NoSuchFieldException(e.getMessage());
}
}
@Override
public Field findFieldOrNull(@NonNull Class<?> clazz, @NonNull String fieldName) {
try {
return findField(clazz, fieldName);
} catch (NoSuchFieldException e) {
return null;
}
}
@NonNull
@Override
public Field findField(@NonNull String className, @NonNull String fieldName, @Nullable ClassLoader classLoader) throws ClassNotFoundException, NoSuchFieldException {
var clazz = findClass(className, classLoader);
return findField(clazz, fieldName);
}
@Nullable
@Override
public <T> Class<T> classOrNullByBinaryName(@NonNull String binaryClassName, @Nullable ClassLoader classLoader) {
throw new AbstractMethodError();
public Field findFieldOrNull(@NonNull String className, @NonNull String fieldName, @Nullable ClassLoader classLoader) {
try {
return findField(className, fieldName, classLoader);
} catch (ClassNotFoundException | NoSuchFieldException e) {
return null;
}
}
}

View File

@ -21,6 +21,11 @@ public interface XposedInterface {
@NonNull
Object[] getArgs();
@Nullable
<U> U getArg(int index);
<U> void setArg(int index, U value);
void returnAndSkip(@Nullable Object returnValue);
void throwAndSkip(@Nullable Throwable throwable);
@ -28,6 +33,9 @@ public interface XposedInterface {
@Nullable
Object invokeOrigin(@Nullable Object thisObject, Object[] args) throws InvocationTargetException, IllegalAccessException;
@Nullable
Object invokeOrigin() throws InvocationTargetException, IllegalAccessException;
<U> void setExtra(@NonNull String key, @Nullable U value) throws ConcurrentModificationException;
}
@ -56,6 +64,9 @@ public interface XposedInterface {
@Nullable
Object invokeOrigin(@Nullable Object thisObject, Object[] args) throws InvocationTargetException, IllegalAccessException;
@Nullable
Object invokeOrigin() throws InvocationTargetException, IllegalAccessException;
@Nullable
<U> U getExtra(@NonNull String key);
}

View File

@ -3,16 +3,24 @@ package io.github.libxposed;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.lang.reflect.Field;
public interface XposedUtils {
@NonNull
<T> Class<T> classByName(@NonNull String className, @Nullable ClassLoader classLoader) throws ClassNotFoundException;
<T> Class<T> findClass(@NonNull String className, @Nullable ClassLoader classLoader) throws ClassNotFoundException;
@Nullable
<T> Class<T> classOrNullByName(@NonNull String className, @Nullable ClassLoader classLoader);
<T> Class<T> findClassOrNull(@NonNull String className, @Nullable ClassLoader classLoader);
@NonNull
<T> Class<T> classByBinaryName(@NonNull String binaryClassName, @Nullable ClassLoader classLoader) throws ClassNotFoundException;
Field findField(@NonNull Class<?> clazz, @NonNull String fieldName) throws NoSuchFieldException;
@Nullable
<T> Class<T> classOrNullByBinaryName(@NonNull String binaryClassName, @Nullable ClassLoader classLoader);
Field findFieldOrNull(@NonNull Class<?> clazz, @NonNull String fieldName);
@NonNull
Field findField(@NonNull String className, @NonNull String fieldName, @Nullable ClassLoader classLoader) throws ClassNotFoundException, NoSuchFieldException;
@Nullable
Field findFieldOrNull(@NonNull String className, @NonNull String fieldName, @Nullable ClassLoader classLoader);
}