dexposed是阿里巴巴在xposed框架上面开发的hotpatch一套框架
当然hotpatch的方式有很多,这里先介绍下dexposed原理
Demo中有个test函数, 在调用hook之前正常返回”11111”; 调用hook之后, 却返回”newTestMethod”, 被我们给修改
了
public class Demo
{
String TAG = "===[hookdemo]==="; public static String staticTest(String param1) { return "staticTest"; } public String test(String param1) { return "11111"; } public void demo() { String param1 = "param1"; Log.d(TAG, "===========before hook test:" + this.test(param1)); hook(Demo1.class, "test", "(Ljava/lang/String;)Ljava/lang/String;"); Log.d(TAG, "===========after hook test:" + this.test(param1)); Log.d(TAG, "===========before hook staticTest:" + this.staticTest(param1)); hook(Demo1.class, "staticTest", "(Ljava/lang/String;)Ljava/lang/String;"); Log.d(TAG, "===========after hook staticTest:" + this.staticTest(param1)); } private native void hook(Class<?> clazzToHook, String methodName, String methodSig); }
ndk 中的部分
#include <jni.h>
#include "log.h"
#include "Dalvik.h"
static void showMethodInfo(const Method* method) { //看看method的各个属性都是啥: LOGD("accessFlags:%d",method->accessFlags); LOGD("clazz->descriptor:%s",method->clazz->descriptor); LOGD("clazz->sourceFile:%s",method->clazz->sourceFile); LOGD("methodIndex:%d",method->methodIndex); LOGD("name:%s",method->name); LOGD("shorty:%s",method->shorty); } /** * 使用jni GetMethodID 方法获取jmethodID 强制转为 Method 的hook 方法 示例 */ static void newTestMethod(const u4* args, JValue* pResult, const Method* method, struct Thread* self) { // args 是原来函数的参数数组, 原来test函数只有一个String型参数 // 并且要注意, 如果是不是static函数, 下标0 是函数所在类的实例obj // 在dvm中Object, jni 中的jobject 和 java 中的 Object类 都不是同一个东西 // String类对应StringObject // 取出参数打印出来看看 StringObject* param1 = NULL; if(dvmIsStaticMethod(method)) param1 = (StringObject*)args[0]; else param1 = (StringObject*)args[1]; LOGD("param1:%s",dvmCreateCstrFromString(param1)); //JValue 是个union ,要返回int 就 pResult->i=1; 返回Object对象就 pResult->l = ojb; // 但是, 在dvm中的Object, jni 中的jobject 和 java 中的 Object类 都不是同一个东西 // 所以, 我们这里使用dvm的函数来创建一个StringObject* pResult->l = dvmCreateStringFromCstr("newTestMethod"); // 一般情况应该使用宏 : RETURN_XXX(result); return; } extern "C" JNIEXPORT void JNICALL Java_com_zhaoxiaodan_hookdemo_Demo1_hook(JNIEnv *env, jobject instance, jobject clazzToHook, jstring methodName_, jstring methodSig_) { const char *methodName = env->GetStringUTFChars(methodName_, 0); const char *methodSig = env->GetStringUTFChars(methodSig_, 0); jmethodID methodIDToHook = env->GetMethodID((jclass) clazzToHook,methodName,methodSig); // 找不到有可能是个static if(nullptr == methodIDToHook){ env->ExceptionClear(); methodIDToHook = env->GetStaticMethodID((jclass) clazzToHook,methodName