将hook单独作为库引入
This commit is contained in:
1
.idea/gradle.xml
generated
1
.idea/gradle.xml
generated
@@ -85,7 +85,6 @@
|
||||
</set>
|
||||
</option>
|
||||
<option name="resolveModulePerSourceSet" value="false" />
|
||||
<option name="useQualifiedModuleNames" value="true" />
|
||||
</GradleProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
|
||||
@@ -99,8 +99,14 @@ class CustomMapApiBuilder implements IMogoMapApiBuilder {
|
||||
.setZoom( 16 )
|
||||
.setPointToCenter( 0.734375f, 0.5f )
|
||||
.setStyleMode( MapParams.MAP_STYLE_NIGHT ), NavParams.Companion.init() );
|
||||
MapAutoView mapAutoView = new MapAutoView( context );
|
||||
IMogoMapView mapView = new AMapViewWrapper( mapAutoView );
|
||||
MapAutoView mapAutoView = new MapAutoView(context);
|
||||
Logger.w(TAG, "mapAutoView==" + mapAutoView);
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
IMogoMapView mapView = new AMapViewWrapper(mapAutoView);
|
||||
return mapView;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
# 更多关于在Android Studio中使用CMake的信息,请阅读文档
|
||||
# https://d.android.com/studio/projects/add-native-code.html
|
||||
|
||||
# 设置构建本机库所需的CMake的最小版本。
|
||||
cmake_minimum_required(VERSION 3.4.1)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -frtti -fexceptions")
|
||||
|
||||
# 指定的源文件生成链接文件,然后添加到工程中去
|
||||
add_library(
|
||||
# 设置库的名称。对应 System.loadLibrary("native-lib"); 使用的名称
|
||||
method-hook-lib
|
||||
# 将库设置为共享库。
|
||||
SHARED
|
||||
# 提供了到源文件的相对路径。
|
||||
src/main/cpp/method-hook-lib.cpp)
|
||||
|
||||
# 搜索指定的预构建库并将路径存储为变量。
|
||||
# 因为CMake在搜索路径中默认包含系统库,
|
||||
# 所以你只需要指定你想要添加的公共NDK库的名称,
|
||||
# CMake在完成它的构建之前会验证这个库是否存在。
|
||||
find_library(
|
||||
# 设置path变量的名称。
|
||||
log-lib
|
||||
# 指定你想要CMake定位的NDK库的名称。
|
||||
log)
|
||||
|
||||
# 为native-lib添加ffmpeg编译连接库
|
||||
target_link_libraries(
|
||||
# 指定目标库。
|
||||
method-hook-lib
|
||||
# 将目标库链接到包含在NDK中的日志库。
|
||||
${log-lib})
|
||||
@@ -11,17 +11,6 @@ android {
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
consumerProguardFiles 'consumer-rules.pro'
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
cppFlags ""
|
||||
}
|
||||
}
|
||||
}
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
path "CMakeLists.txt"
|
||||
}
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
@@ -44,6 +33,7 @@ dependencies {
|
||||
implementation rootProject.ext.dependencies.androidxconstraintlayout
|
||||
implementation rootProject.ext.dependencies.arouter
|
||||
implementation rootProject.ext.dependencies.callchatprovider
|
||||
api "com.mogo.libs:hook:1.0"
|
||||
if (Boolean.valueOf(RELEASE)) {
|
||||
api rootProject.ext.dependencies.mogomap
|
||||
api rootProject.ext.dependencies.mogomapapi
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
//
|
||||
// Created by on 2020-05-08.
|
||||
//
|
||||
|
||||
#ifndef API_H
|
||||
#define API_H
|
||||
|
||||
#include <android/log.h>
|
||||
|
||||
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,"Native_RtmpPusher",__VA_ARGS__)
|
||||
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,"Native_RtmpPusher",__VA_ARGS__)
|
||||
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN,"Native_RtmpPusher",__VA_ARGS__)
|
||||
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,"Native_RtmpPusher",__VA_ARGS__)
|
||||
|
||||
|
||||
#endif //API_H
|
||||
@@ -1,108 +0,0 @@
|
||||
#include <jni.h>
|
||||
#include <string.h>
|
||||
#include "Api.h"
|
||||
|
||||
// Created by donghongyu on 12/10/20 1:34 PM.
|
||||
// 源码地址 https://github.com/pqpo/methodhook
|
||||
// 方法hook jni类
|
||||
static const char *kClassMethodHookChar = "com/mogo/module/common/hook/MethodHook";
|
||||
|
||||
static struct {
|
||||
jmethodID m1;
|
||||
jmethodID m2;
|
||||
size_t methodSize;
|
||||
} methodHookClassInfo;
|
||||
|
||||
|
||||
/**
|
||||
* 替换指定类中的方法
|
||||
* @param env
|
||||
* @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
|
||||
* @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",
|
||||
"(Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;)J",
|
||||
(void *) methodHook
|
||||
},
|
||||
{
|
||||
"restore_native",
|
||||
"(Ljava/lang/reflect/Method;J)Ljava/lang/reflect/Method;",
|
||||
(void *) methodRestore
|
||||
}
|
||||
};
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT jint JNICALL
|
||||
/**
|
||||
* 在jni加载的时候进行方法参数获取
|
||||
* @param vm
|
||||
* @param reserved
|
||||
* @return
|
||||
*/
|
||||
JNI_OnLoad(JavaVM *vm, void *reserved) {
|
||||
JNIEnv *env = nullptr;
|
||||
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;
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,8 +14,8 @@ import androidx.fragment.app.Fragment;
|
||||
import com.alibaba.android.arouter.facade.annotation.Route;
|
||||
import com.amap.api.col.n3.lg;
|
||||
import com.amap.api.col.n3.lg2;
|
||||
import com.mogo.hook.HookManager;
|
||||
import com.mogo.module.common.MogoApisHandler;
|
||||
import com.mogo.module.common.hook.HookManager;
|
||||
import com.mogo.module.common.wm.WindowManagerView;
|
||||
import com.mogo.service.MogoServicePaths;
|
||||
import com.mogo.service.map.IMogoSmallMapProvider;
|
||||
|
||||
Reference in New Issue
Block a user