这是一个 android 方法hook的插件,在方法进入和方法退出时,将当前运行的所有参数回调到固定的接口中,利用这一点,可以进行方法切片式开发,也可以进行一些耗时统计等性能优化相关的统计。
原始代码:
@HookMethod
public int add(int num1, int num2) throws InterruptedException {
int a = num1 + num2;
Thread.sleep(a);
return a;
}
实际编译插桩后代码:
public int add(int num1, int num2) throws InterruptedException {
MethodHookHandler.enter(this,"com.miqt.plugindemo.Hello","add","[int, int]","int",i,i1);
int a = num1 + num2;
Thread.sleep(a);
MethodHookHandler.exit(a,this,"com.miqt.plugindemo.Hello","add","[int, int]","int",i,i1);
return a;
}
稍作开发就可以实现一个方法出入日志打印功能:
2020-05-08 16:16:31.385 25969-26027/com.miqt.plugindemo W/MethodHookHandler:
╔======================================================================================
║[Thread]:Thread-3
║[Class]:com.miqt.plugindemo.Hello
║[Method]:add
║[This]:com.miqt.plugindemo.Hello@c65e5c0
║[ArgsType]:[int, int]
║[ArgsValue]:[100,200]
║[Return]:300
║[ReturnType]:int
║[Time]:301 ms
╚======================================================================================
可以看出,这样的话方法名,运行线程,当前对象,入/出参数和耗时情况就都一目了然啦。当然还可以做一些别的事情,例如hook点击事件等等。
项目根目录:build.gradle 添加以下代码
dependencies {
classpath 'me.miqt.plugin.tools:pluginSrc:0.2.2'
}
对应 module 中启用插件,可以是application
也可以是library
apply plugin: 'miqt.plugin.tools'
methodhook {
enable = true //是否启用
//项目中的class true:全部插桩 false:只有注解插桩
all = true
// 下面是非必要配置,无特殊需求可直接删除
//指定插桩那些外部引用的jar,默认空,表示只对项目中的class插桩
jarRegexs = [".*androidx.*"]
//指定插桩那些类文件,默认空
classRegexs = [".*view.*"]
//所有包含 on 的方法,所有构造方法
methodRegexs = [".*on.*", ".*init.*"]
//编译时是否打印log
log = true
//是否用插桩后的jar包替换项目中的jar包,慎用
replaceJar = false
//是否生成详细mapping文件
mapping = true
//自定义方法统计实现类,不指定默认使用自带实现方式
//impl = "com.miqt.plugindemo.MyTimeP"
}
添加类库依赖:
dependencies {
implementation 'me.miqt.plugin.tools:pluginlib:0.2.2'
}
这个插件是借鉴了很多大佬的代码,并结合自己的想法进行了一些调整,在此感谢他们付出的努力。
https://github.com/novoda/bintray-release
https://github.com/JeasonWong/CostTime
https://github.com/MegatronKing/StringFog
- 在对jar进行方法hook的时候,如果这个jar经历过混淆,则插入代码后会因为jar2dex转换失败而编译不通过。--已解决
- No such property: ASM6 for class: org.objectweb.asm.Opcodes 升级gradle版本可以解决。--已解决
- 给子module插桩编译异常。--已解决