原文地址:http://www.zhaoxiaodan.com/android/Android-Hook(1)-dexposed%E5%8E%9F%E7%90%86.html

dexposed 这个项目相当不错, 之前就想着怎么动态替换jvm中的代码, 一直没有思路; 现在好好学习一下

准备源码库

因为dexposed其实是用了dvm和art调用class的方式来做的, 而dvm和art的头文件什么的在android源码中, 所以下一份源码, 具体办法见上一个博文: 准备android源码库

最简单的hook

Demo1中有个test函数, 在调用hook之前正常返回”11111”; 调用hook之后, 却返回”newTestMethod”, 被我们给修改

public class Demo1
{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];elseparam1 = (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);// 找不到有可能是个staticif(nullptr == methodIDToHook){env->ExceptionClear();methodIDToHook = env->GetStaticMethodID((jclass) clazzToHook,methodName,methodSig);}if(methodIDToHook != nullptr){//主要在这里替换//jmethodID 在dvm里实际上就是个Method 结构体Method* method = (Method*) methodIDToHook;//看看method的各个属性都是啥:showMethodInfo(method);//设置Method 的 accessFlags 为 枚举型// ACC_NATIVE 表示 这个method 切换成了一个native 方法// 这个枚举 在 dalvik/libdex/DexFile.h// 类似:// ACC_PUBLIC       = 0x00000001,       // class, field, method, ic// ACC_PRIVATE      = 0x00000002,       // field, method, ic// ACC_PROTECTED    = 0x00000004,       // field, method, icSET_METHOD_FLAG(method, ACC_NATIVE);//既然是一个native方法, 那就把 nativeFunc 指针指向我们的hook, 用来替换test的新方法method->nativeFunc = &newTestMethod;// registersSize是函数栈大小, insSize是参数占用大小// 如果是native方法, 就没有额外开销了// 所有开销就是参数占用, 所以把它设置成跟参数占用空间method->registersSize=method->insSize;//未知method->outsSize=0;}env->ReleaseStringUTFChars(methodName_, methodName);env->ReleaseStringUTFChars(methodSig_, methodSig);
}

运行之后得到:

/===[hookdemo]===﹕ ===========before hook test:11111
/[---hookdemo---]﹕ accessFlags:1
/[---hookdemo---]﹕ clazz->descriptor:Lcom/zhaoxiaodan/hookdemo/MainActivity;
/[---hookdemo---]﹕ clazz->sourceFile:MainActivity.java
/[---hookdemo---]﹕ methodIndex:334
/[---hookdemo---]﹕ name:test
/[---hookdemo---]﹕ shorty:LL
/[---hookdemo---]﹕ param1:param1
/===[hookdemo]===﹕ ===========after hook test:newTestMethod
/===[hookdemo]===﹕ ===========before hook staticTest:staticTest
/dalvikvm﹕ GetMethodID: not returning static method Lcom/zhaoxiaodan/hookdemo/MainActivity;.staticTest (Ljava/lang/String;)Ljava/lang/String;
/[---hookdemo---]﹕ accessFlags:9
/[---hookdemo---]﹕ clazz->descriptor:Lcom/zhaoxiaodan/hookdemo/MainActivity;
/[---hookdemo---]﹕ clazz->sourceFile:MainActivity.java
/[---hookdemo---]﹕ methodIndex:0
/[---hookdemo---]﹕ name:staticTest
/[---hookdemo---]﹕ shorty:LL
/[---hookdemo---]﹕ param1:param1
/===[hookdemo]===﹕ ===========after hook staticTest:newTestMethod

原理就是, Method结构体表示了一个java层函数, 而其中的accessFlags属性如果是ACC_NATIVE , dvm在call 原java层函数的时候, 则会转向调用 属性nativeFunc 所指向的函数

所以我们把不是native的java层函数的accessFlags强制改为ACC_NATIVE, 然后把nativeFunc 指向我们的新函数, 则完成了方法的修改

只不过, 这里使用native方法替换了java层的原方法

参考文章

  • 编译屏障和内存屏障 : 需要设置的 ANDROID_SMP 是啥 ?
  • Dalvik虚拟机JNI方法的注册过程分析

Android Hook (1) Dexposed原理相关推荐

  1. 【Android 插件化】Hook 插件化框架 ( hook 插件化原理 | 插件包管理 )

    Android 插件化系列文章目录 [Android 插件化]插件化简介 ( 组件化与插件化 ) [Android 插件化]插件化原理 ( JVM 内存数据 | 类加载流程 ) [Android 插件 ...

  2. xposed hook java_[原创]Android Hook 系列教程(一) Xposed Hook 原理分析

    章节内容 一. Android Hook 系列教程(一) Xposed Hook 原理分析 二. Android Hook 系列教程(二) 自己写APK实现Hook Java层函数 三. Androi ...

  3. 深入解析阿里Android热修复技术原理

    前言:本文框架 什么是热修复? 热修复框架分类 技术原理及特点 Tinker框架解析 各框架对比图 总结 通过阅读本文,你会对热修复技术有更深的认知,本文会列出各类框架的优缺点以及技术原理,文章末尾简 ...

  4. Android热修复技术原理详解(最新最全版本)

    本文框架 什么是热修复? 热修复框架分类 技术原理及特点 Tinker框架解析 各框架对比图 总结   通过阅读本文,你会对热修复技术有更深的认知,本文会列出各类框架的优缺点以及技术原理,文章末尾简单 ...

  5. [读书笔记] 深入探索Android热修复技术原理 (手淘技术团队)

    热修复技术介绍 探索之路 最开始,手淘是基于Xposed进行了改进,产生了针对Android Dalvik虚拟机运行时的Java Method Hook技术--Dexposed. 但该方案对于底层Da ...

  6. android动画的实现原理,Android动画的实现原理 .

    1.动画运行模式 独行模式 中断模式 2.Animation类 每个动画都重载了父类的applyTransformation方法这个方法的主要作用是把一些属性组装成一个Transformation类, ...

  7. 浅谈android hook技术

    前言 在测试android过程中,能对函数进行hook能帮助更加深入的进行测试,本文简单介绍了hook框架xposed和frida,从简单的小例子做了简单的演示,算是自己的学习的过程,是个入门的过程. ...

  8. android hook截取其他程序的按钮事件_Hook技术

    概述 Hook,英文直译是"钩子"的意思.在程序中将其理解为"劫持"可能会更好理解,我们可以通过hook技术来劫持某个对象,从而控制它与其他对象的交互. Hoo ...

  9. android hook 第三方app_基于 VirtualApp 结合 whale hook框架实现hook第三方应用

    要点 1. whale hook framework 使用示例: 2. 参考项目:VirtualHook: 3. 按照 VirtualHook 修改 VirtualApp: 4. 编写 hook pl ...

最新文章

  1. check的用法java,Java ValueRange checkValidValue()用法及代码示例
  2. lda主题模型应用java_主题模型LDA及在推荐系统中的应用
  3. jmeter对乱码如何处理_JMeter中文乱码的解决
  4. android代码设置全屏
  5. sklearn API 文档
  6. vc如何打开plt图像_图像基本操作-open cv
  7. ASP.NET Core 源码学习之 Options[2]:IOptions
  8. jquery中prop()方法和attr()方法的区别
  9. Jquery选择器大全汇总
  10. android下实现4分屏播放4路高清h264格式的rtsp流
  11. Stamps 邮票问题 详解(C++)
  12. 每日一问 --信源编码的过程?
  13. java 背单词系统_5分钟用两个App打造你自己的背单词体系
  14. filebeat7.7.0相关详细配置预览- processors - add_fields
  15. 完美解决idea Maven Cannot reconnect
  16. Ubuntu下wps英文界面切换成中文界面的方法
  17. 产品如何取得WFA的WiFi认证(一)总览
  18. PHP大数据量(大于50万)导出到Excel解决方案
  19. 【笔记】编译Android版的Chrome手册
  20. mysql 烂泥,烂泥:学习mysql的binlog配置

热门文章

  1. Python学习笔记:Day 7 编写MVC
  2. Python学习笔记:web开发1
  3. 【算法】梯度消失与梯度爆炸
  4. 【算法】一个简单的线性判别分析(LDA)原理
  5. Fill in blank -Thermal experiment theory and technology2018-01-06
  6. VisualStudioCode 中设置中文语言【图文教程】
  7. python zipfile 模块下中文乱码 '╡┌╥╗╒┬_╒╨▒Ω╣½╕µ.docx'
  8. 各向异性扩散滤波_原理与算法
  9. 在C#中利用Keep-Alive处理Socket网络异常断开的方法
  10. SQL Server数据库管理常用SQL和T-SQL语句