增加了api说明

This commit is contained in:
董宏宇
2020-12-29 19:50:33 +08:00
parent cab2517b1c
commit 01afc151d9
2 changed files with 55 additions and 4 deletions

View File

@@ -17,37 +17,48 @@ static struct {
/**
* 替换指定类中的方法
* @param env
* @param type 要替换方法的目标 class
* @param type
* @param srcMethodObj 目标方法对象
* @param destMethodObj 替换的方法对象
* @return
*/
static jlong methodHook(JNIEnv *env, jclass type, jobject srcMethodObj, jobject destMethodObj) {
// 反射获取了Java对象的在native层的 ArtMethod指针
void *srcMethod = reinterpret_cast<void *>(env->FromReflectedMethod(srcMethodObj));
void *destMethod = reinterpret_cast<void *>(env->FromReflectedMethod(destMethodObj));
// 定义存储方法ID的数组
int *backupMethod = new int[methodHookClassInfo.methodSize];
// 使用的内存拷贝函数
// 将旧方法ID拷贝到数组中
memcpy(backupMethod, srcMethod, methodHookClassInfo.methodSize);
// 将新方法替换到旧方法地址上
memcpy(srcMethod, destMethod, methodHookClassInfo.methodSize);
// 将旧方法ID返回给java层用来做方法还原使用
return reinterpret_cast<long>(backupMethod);
}
/**
* 恢复指定类中的方法
* @param env
* @param type 要恢复方法的目标 class
* @param type
* @param srcMethod 目标方法对象
* @param methodPtr
* @return
*/
static jobject methodRestore(JNIEnv *env, jclass type, jobject srcMethod, jlong methodPtr) {
// 要还原的旧方法 指针
int *backupMethod = reinterpret_cast<int *>(methodPtr);
// 获取了Java对象的在native层的 ArtMethod指针
void *artMethodSrc = reinterpret_cast<void *>(env->FromReflectedMethod(srcMethod));
// 将旧方法指针,替换到 artMethodSrc 中
memcpy(artMethodSrc, backupMethod, methodHookClassInfo.methodSize);
// 删除旧方法备份指针
delete[]backupMethod;
// 返回旧方法
return srcMethod;
}
// 定义要注册的方法
static JNINativeMethod gMethods[] = {
{
"hook_native",
@@ -74,13 +85,17 @@ JNI_OnLoad(JavaVM *vm, void *reserved) {
if (vm->GetEnv((void **) &env, JNI_VERSION_1_4) != JNI_OK) {
return JNI_FALSE;
}
// 加载指定java class
jclass classEvaluateUtil = env->FindClass(kClassMethodHookChar);
// 注册
if (env->RegisterNatives(classEvaluateUtil, gMethods, sizeof(gMethods) / sizeof(gMethods[0])) <
0) {
return JNI_FALSE;
}
// 获取 MethodHook m1、m2 的方法ID
methodHookClassInfo.m1 = env->GetStaticMethodID(classEvaluateUtil, "m1", "()V");
methodHookClassInfo.m2 = env->GetStaticMethodID(classEvaluateUtil, "m2", "()V");
// 获取artMethod的大小
methodHookClassInfo.methodSize = reinterpret_cast<size_t>(methodHookClassInfo.m2) -
reinterpret_cast<size_t>(methodHookClassInfo.m1);
return JNI_VERSION_1_4;

View File

@@ -23,6 +23,12 @@ public class MethodHook {
// 备份目标替换方法ID
private long backupMethodPtr;
/**
* hook方法
*
* @param src 要替换的方法对象
* @param dest 被替换的方法对象
*/
public MethodHook(Method src, Method dest) {
srcMethod = src;
hookMethod = dest;
@@ -30,12 +36,18 @@ public class MethodHook {
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);
@@ -43,7 +55,16 @@ public class MethodHook {
}
}
public void callOrigin(Object receiver, Object... args) throws InvocationTargetException, IllegalAccessException {
/**
* 调用原来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);
@@ -53,11 +74,26 @@ public class MethodHook {
}
}
/**
* 调用 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");
}