将hook单独作为库引入

This commit is contained in:
董宏宇
2020-12-31 16:43:05 +08:00
parent 789d983021
commit d582bc3c41
9 changed files with 10 additions and 339 deletions

View File

@@ -1,67 +0,0 @@
package com.mogo.module.common.hook;
import android.util.Pair;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 替换管理
* Created by donghongyu on 12/29/20 1:34 PM
*/
public final class HookManager {
private HookManager() {
}
public static HookManager get() {
return InstanceHolder.sInstance;
}
private static class InstanceHolder {
private static HookManager sInstance = new HookManager();
}
private Map<Pair<String, String>, MethodHook> methodHookMap = new ConcurrentHashMap<>();
/**
* 替换方法
*
* @param originMethod 原始方法
* @param hookMethod 替换方法
*/
public void hookMethod(Method originMethod, Method hookMethod) {
if (originMethod == null || hookMethod == null) {
throw new IllegalArgumentException("argument cannot be null");
}
Pair<String, String> key = Pair.create(hookMethod.getDeclaringClass().getName(), hookMethod.getName());
if (methodHookMap.containsKey(key)) {
MethodHook methodHook = methodHookMap.get(key);
methodHook.restore();
}
MethodHook methodHook = new MethodHook(originMethod, hookMethod);
methodHookMap.put(key, methodHook);
methodHook.hook();
}
public void callOrigin(Object receiver, Object... args) {
StackTraceElement stackTrace = Thread.currentThread().getStackTrace()[3];
String className = stackTrace.getClassName();
String methodName = stackTrace.getMethodName();
MethodHook methodHook = methodHookMap.get(Pair.create(className, methodName));
if (methodHook != null) {
try {
methodHook.callOrigin(receiver, args);
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}

View File

@@ -1,100 +0,0 @@
package com.mogo.module.common.hook;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* 替换类与c++代码对应
* Created by donghongyu on 12/29/20 1:34 PM
*/
public class MethodHook {
public static void m1() {
}
public static void m2() {
}
// 目标方法
private Method srcMethod;
// 要替换的方法
private Method hookMethod;
// 备份目标替换方法ID
private long backupMethodPtr;
/**
* hook方法
*
* @param src 要替换的方法对象
* @param dest 被替换的方法对象
*/
public MethodHook(Method src, Method dest) {
srcMethod = src;
hookMethod = dest;
srcMethod.setAccessible(true);
hookMethod.setAccessible(true);
}
/**
* 调用 native 层,完成替换
*/
public void hook() {
if (backupMethodPtr == 0) {
backupMethodPtr = hook_native(srcMethod, hookMethod);
}
}
/**
* 调用 native 层,完成方法还原
*/
public void restore() {
if (backupMethodPtr != 0) {
restore_native(srcMethod, backupMethodPtr);
backupMethodPtr = 0;
}
}
/**
* 调用原来class 对象中的方法
*
* @param receiver 接受对象
* @param args 方法列表
* @throws InvocationTargetException
* @throws IllegalAccessException
*/
public void callOrigin(Object receiver, Object... args)
throws InvocationTargetException, IllegalAccessException {
if (backupMethodPtr != 0) {
restore();
srcMethod.invoke(receiver, args);
hook();
} else {
srcMethod.invoke(receiver, args);
}
}
/**
* 调用 native 方法完成 方法替换
*
* @param src 旧方法
* @param dest 新方法
* @return 就方法ID
*/
private static native long hook_native(Method src, Method dest);
/**
* 调用 native 方法完成 方法还原
*
* @param src
* @param methodPtr
* @return
*/
private static native Method restore_native(Method src, long methodPtr);
static {
// 加载本地方法 so
System.loadLibrary("method-hook-lib");
}
}