Fix method "hook" not being called while methods replacement and backup have succeeded

This commit is contained in:
solohsu 2019-01-21 00:28:44 +08:00
parent 9435e9867b
commit fb4bdfcd56
3 changed files with 111 additions and 6 deletions

View File

@ -82,6 +82,7 @@ public class HookMain {
}
public static void backupAndHook(Object target, Method hook, Method backup) {
Utils.logD(String.format("target=%s, hook=%s, backup=%s", target, hook, backup));
if (target == null) {
throw new IllegalArgumentException("null target method");
}
@ -108,7 +109,7 @@ public class HookMain {
}
}
private static Object findMethod(Class cls, String methodName, String methodSig) {
public static Object findMethod(Class cls, String methodName, String methodSig) {
if (cls == null) {
throw new IllegalArgumentException("null class");
}

View File

@ -0,0 +1,92 @@
package com.elderdrivers.riru.xposed.dexmaker;
import java.lang.reflect.Constructor;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
public class MethodInfo {
public String className;
public String classDesc;
public String methodName;
public String methodSig;
public Method method;
public Constructor constructor;
public boolean isConstructor;
public ClassLoader classLoader;
public MethodInfo(Member member) {
if (member instanceof Method) {
method = (Method) member;
isConstructor = false;
classLoader = member.getDeclaringClass().getClassLoader();
generateMethodInfo();
} else if (member instanceof Constructor) {
constructor = (Constructor) member;
isConstructor = true;
classLoader = member.getDeclaringClass().getClassLoader();
generateConstructorInfo();
} else {
throw new IllegalArgumentException("member should be Method or Constructor");
}
}
private void generateConstructorInfo() {
methodName = "<init>";
className = constructor.getDeclaringClass().getName();
generateCommonInfo(constructor.getParameterTypes(), void.class);
}
private void generateMethodInfo() {
methodName = method.getName();
className = method.getDeclaringClass().getName();
generateCommonInfo(method.getParameterTypes(), method.getReturnType());
}
private void generateCommonInfo(Class[] parameterTypes, Class returnType) {
classDesc = "L" + className.replace(".", "/") + ";";
StringBuilder builder = new StringBuilder();
builder.append("(");
for (Class parameterType : parameterTypes) {
builder.append(getDescStr(parameterType));
}
builder.append(")");
builder.append(getDescStr(returnType));
methodSig = builder.toString();
}
public Class getClassForSure() {
try {
return Class.forName(className, true, classLoader);
} catch (Throwable throwable) {
return null;
}
}
public static String getDescStr(Class clazz) {
if (clazz.equals(boolean.class)) {
return "Z";
} else if (clazz.equals(byte.class)) {
return "B";
} else if (clazz.equals(char.class)) {
return "C";
} else if (clazz.equals(double.class)) {
return "D";
} else if (clazz.equals(float.class)) {
return "F";
} else if (clazz.equals(int.class)) {
return "I";
} else if (clazz.equals(long.class)) {
return "J";
} else if (clazz.equals(short.class)) {
return "S";
} else if (clazz.equals(void.class)) {
return "V";
} else {
String prefix = clazz.isArray() ? "" : "L";
String suffix = clazz.isArray() ? "" : ";";
return prefix + clazz.getName().replace(".", "/") + suffix;
}
}
}

View File

@ -3,6 +3,10 @@ package de.robv.android.xposed;
import android.annotation.SuppressLint;
import android.util.Log;
import com.elderdrivers.riru.xposed.core.HookMain;
import com.elderdrivers.riru.xposed.dexmaker.DynamicBridge;
import com.elderdrivers.riru.xposed.dexmaker.MethodInfo;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.AccessibleObject;
@ -17,7 +21,6 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import com.elderdrivers.riru.xposed.dexmaker.DynamicBridge;
import de.robv.android.xposed.XC_MethodHook.MethodHookParam;
import de.robv.android.xposed.callbacks.XC_InitPackageResources;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
@ -194,11 +197,20 @@ public final class XposedBridge {
returnType = null;
}
AdditionalHookInfo additionalInfo = new AdditionalHookInfo(callbacks, parameterTypes, returnType);
hookMethodNative(hookMethod, declaringClass, slot, additionalInfo);
}
AdditionalHookInfo additionalInfo = new AdditionalHookInfo(callbacks, parameterTypes, returnType);
MethodInfo methodInfo = new MethodInfo(hookMethod);
declaringClass = methodInfo.getClassForSure();
Member reflectMethod = (Member) HookMain.findMethod(
declaringClass, methodInfo.methodName, methodInfo.methodSig);
if (reflectMethod == null) {
Log.e(TAG, "method not found: name="
+ methodInfo.methodName + ", sig=" + methodInfo.methodSig);
reflectMethod = hookMethod;
}
hookMethodNative(reflectMethod, declaringClass, slot, additionalInfo);
}
return callback.new Unhook(hookMethod);
return callback.new Unhook(hookMethod);
}
/**