Android Hook (1) Dexposed原理
原文地址: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原理相关推荐
- 【Android 插件化】Hook 插件化框架 ( hook 插件化原理 | 插件包管理 )
Android 插件化系列文章目录 [Android 插件化]插件化简介 ( 组件化与插件化 ) [Android 插件化]插件化原理 ( JVM 内存数据 | 类加载流程 ) [Android 插件 ...
- xposed hook java_[原创]Android Hook 系列教程(一) Xposed Hook 原理分析
章节内容 一. Android Hook 系列教程(一) Xposed Hook 原理分析 二. Android Hook 系列教程(二) 自己写APK实现Hook Java层函数 三. Androi ...
- 深入解析阿里Android热修复技术原理
前言:本文框架 什么是热修复? 热修复框架分类 技术原理及特点 Tinker框架解析 各框架对比图 总结 通过阅读本文,你会对热修复技术有更深的认知,本文会列出各类框架的优缺点以及技术原理,文章末尾简 ...
- Android热修复技术原理详解(最新最全版本)
本文框架 什么是热修复? 热修复框架分类 技术原理及特点 Tinker框架解析 各框架对比图 总结 通过阅读本文,你会对热修复技术有更深的认知,本文会列出各类框架的优缺点以及技术原理,文章末尾简单 ...
- [读书笔记] 深入探索Android热修复技术原理 (手淘技术团队)
热修复技术介绍 探索之路 最开始,手淘是基于Xposed进行了改进,产生了针对Android Dalvik虚拟机运行时的Java Method Hook技术--Dexposed. 但该方案对于底层Da ...
- android动画的实现原理,Android动画的实现原理 .
1.动画运行模式 独行模式 中断模式 2.Animation类 每个动画都重载了父类的applyTransformation方法这个方法的主要作用是把一些属性组装成一个Transformation类, ...
- 浅谈android hook技术
前言 在测试android过程中,能对函数进行hook能帮助更加深入的进行测试,本文简单介绍了hook框架xposed和frida,从简单的小例子做了简单的演示,算是自己的学习的过程,是个入门的过程. ...
- android hook截取其他程序的按钮事件_Hook技术
概述 Hook,英文直译是"钩子"的意思.在程序中将其理解为"劫持"可能会更好理解,我们可以通过hook技术来劫持某个对象,从而控制它与其他对象的交互. Hoo ...
- android hook 第三方app_基于 VirtualApp 结合 whale hook框架实现hook第三方应用
要点 1. whale hook framework 使用示例: 2. 参考项目:VirtualHook: 3. 按照 VirtualHook 修改 VirtualApp: 4. 编写 hook pl ...
最新文章
- check的用法java,Java ValueRange checkValidValue()用法及代码示例
- lda主题模型应用java_主题模型LDA及在推荐系统中的应用
- jmeter对乱码如何处理_JMeter中文乱码的解决
- android代码设置全屏
- sklearn API 文档
- vc如何打开plt图像_图像基本操作-open cv
- ASP.NET Core 源码学习之 Options[2]:IOptions
- jquery中prop()方法和attr()方法的区别
- Jquery选择器大全汇总
- android下实现4分屏播放4路高清h264格式的rtsp流
- Stamps 邮票问题 详解(C++)
- 每日一问 --信源编码的过程?
- java 背单词系统_5分钟用两个App打造你自己的背单词体系
- filebeat7.7.0相关详细配置预览- processors - add_fields
- 完美解决idea Maven Cannot reconnect
- Ubuntu下wps英文界面切换成中文界面的方法
- 产品如何取得WFA的WiFi认证(一)总览
- PHP大数据量(大于50万)导出到Excel解决方案
- 【笔记】编译Android版的Chrome手册
- mysql 烂泥,烂泥:学习mysql的binlog配置
热门文章
- Python学习笔记:Day 7 编写MVC
- Python学习笔记:web开发1
- 【算法】梯度消失与梯度爆炸
- 【算法】一个简单的线性判别分析(LDA)原理
- Fill in blank -Thermal experiment theory and technology2018-01-06
- VisualStudioCode 中设置中文语言【图文教程】
- python zipfile 模块下中文乱码 '╡┌╥╗╒┬_╒╨▒Ω╣½╕µ.docx'
- 各向异性扩散滤波_原理与算法
- 在C#中利用Keep-Alive处理Socket网络异常断开的方法
- SQL Server数据库管理常用SQL和T-SQL语句