Hook startActivity()函数追加一条日志
来源:互联网 发布:视频压缩的常用算法是 编辑:程序博客网 时间:2024/06/04 23:12
目的
希望程序员每次调用startActivity()的时候,可以多打印一条日志。
实现原理
startActivity() 执行过程中,会调用到ActivityThread的成员对象mInstrumentation的 execStartActivity()函数,于是我们可以自定义一个EvilInstrumentation(extends Instrumentation )类,重写execStartActivity()函数,追加实现自己的逻辑,然后通过反射把ActivityThread的成员对象mInstrumentation替换为我们自己写的EvilInstrumentation的对象,达到偷梁换柱的目的。
代码实现
App.java
package com.qunar.yuzhiyun.hook;import android.app.Application;import android.app.Instrumentation;import android.content.Context;import java.lang.reflect.Field;/** * Created by yuzhiyun on 17/8/11. */public class App extends Application { @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); // 先获取到当前的ActivityThread对象 Class activityThreadClass = null; try { activityThreadClass = Class.forName("android.app.ActivityThread"); Field currentActivityThreadField = activityThreadClass.getDeclaredField("sCurrentActivityThread"); currentActivityThreadField.setAccessible(true); //传给get和set方法的参数必须是拥有该字段的实例。如果字段是静态字段(public static …),则传null作为get和set方法的参数 Object currentActivityThread = currentActivityThreadField.get(null); // 拿到原始的 mInstrumentation字段 Field mInstrumentationField = activityThreadClass.getDeclaredField("mInstrumentation"); mInstrumentationField.setAccessible(true); Instrumentation mInstrumentation = (Instrumentation) mInstrumentationField.get(currentActivityThread); // 创建代理对象 Instrumentation evilInstrumentation = new EvilInstrumentation(mInstrumentation); // 偷梁换柱 mInstrumentationField.set(currentActivityThread, evilInstrumentation); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } }}
EvilInstrumentation.java
package com.qunar.yuzhiyun.hook;import android.app.Activity;import android.app.Instrumentation;import android.content.Context;import android.content.Intent;import android.os.Bundle;import android.os.IBinder;import android.util.Log;import java.lang.reflect.Method;/** * Created by yuzhiyun on 17/8/11. */public class EvilInstrumentation extends Instrumentation { private static final String TAG = "EvilInstrumentation"; // ActivityThread中原始的对象, 保存起来 Instrumentation mBase; public EvilInstrumentation(Instrumentation base) { mBase = base; } public ActivityResult execStartActivity( Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) { // Hook之前, XXX到此一游! Log.d(TAG, "\n执行了startActivity, 参数如下: \n" + "who = [" + who + "], " + "\ncontextThread = [" + contextThread + "], \ntoken = [" + token + "], " + "\ntarget = [" + target + "], \nintent = [" + intent + "], \nrequestCode = [" + requestCode + "], \noptions = [" + options + "]"); // 开始调用原始的方法, 调不调用随你,但是不调用的话, 所有的startActivity都失效了. // 由于这个方法是隐藏的,因此需要使用反射调用;首先找到这个方法 try { Method execStartActivity = Instrumentation.class.getDeclaredMethod( "execStartActivity", Context.class, IBinder.class, IBinder.class, Activity.class, Intent.class, int.class, Bundle.class); execStartActivity.setAccessible(true); return (ActivityResult) execStartActivity.invoke(mBase, who, contextThread, token, target, intent, requestCode, options); } catch (Exception e) { // 某该死的rom修改了 需要手动适配 throw new RuntimeException("do not support!!! pls adapt it"); } }}
参考自http://www.jianshu.com/p/b30ea19c444b 非常感谢,楼主讲解的非常清晰!
阅读全文
0 0
- Hook startActivity()函数追加一条日志
- Hook(钩子)函数
- 一、Hook(抽象)函数
- 怎么给从数据库得到list<>追加一条记录(下拉框添加全部)
- HOOK函数
- Android插件化开发之Hook StartActivity方法
- Android插件化开发之Hook StartActivity方法
- 动态代理hook自己进程的startActivity方法
- Android插件化开发之Hook StartActivity方法
- StartActivity
- StartActivity
- startActivity
- Logminer使用(追加日志模式)
- PHP指定文件追加日志
- window.onload追加函数
- window.onload追加函数
- 函数中追加文本
- Java 字符串(一条日志信息)解析实例
- thinkphp5中的分层控制器及其使用/tp5分层控制器
- linux vim 去掉 bomb
- bzoj1060 [ZJOI2007]时态同步
- Golang的Mysql操作
- windows 下cmake的安装+使用 教程
- Hook startActivity()函数追加一条日志
- 奥威Power-BI系统之人力资源分析应用-人员薪酬分析
- 过拟合问题及解决办法
- [Zigbee]绑定操作的时间
- 英语学习得不到想要的效果找原因
- ViewParge(普通滑动)
- MYSQL-通配符与正则表达式的使用
- 支持向量机实例
- problem: ERROR cluster.YarnClientSchedulerBackend: Yarn application has already exited with state