增加了api说明
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user