Java字节码插桩修改HiBeaver(结合ASM,实现Hook需求、轻量级AOP、无埋点统计上报等),Javassist

Java汇编指令- https://segmentfault.com/a/1190000008606277
一次Android字节码插桩实战- https://segmentfault.com/a/1190000008658815
Android字节码修改神器HiBeaver:黑掉你的SDK- https://segmentfault.com/a/1190000008491823
黑掉你的SDK,字节码插桩,插入指令,hook代码,甚至建立一些简单的AOP框架- https://github.com/BryanSharp/hiBeaverDemo
HiBeaver是一个用于进行Java字节码插桩的Gradle插件- https://github.com/BryanSharp/hibeaver
  HiBeaver is an gradle plugin for java byte code manipulation and AOP design by modifying project byte code during build of the package, or modifying bytecode within Jar independently.
  Android gradle编译插件hibeaver结合Java AOP编程中对于大名鼎鼎的ASM.jar的应用,和Android gradle 插件提供的最新的Transform API,在Apk编译环节中、class打包成dex之前,插入了中间环节,依据开发者的配置调用ASM API对项目所依赖的jar进行相应的修改,从而可以比较高效地实现上面的Hook需求。 
  HiBeaver 是目前这方面比较完善的字节码插桩Gradle插件,目前最新的1.2.4版本支持通过通配符或正则表达式的方法来匹配目标类和目标方法,进行方法的批量插桩注入和
修改。

字节码的修改可以使用Javassist或者ASM-http://jboss-javassist.github.io/javassist/ , https://asm.ow2.io/

-- HiBeaver的几个应用场景:
1.修改引用SDK中的一些bug或者提高其效率;
2.获得必要的SDK的一些关键调用时机,通过hook建立回调;
3.欺骗SDK、关闭或减少SDK中不受控制的网络传输。
4.对指定Jar/Aar文件进行修改。
5.Android字节码插桩技术:如无埋点统计上报、轻量级AOP

-- 传入组件的实例对象,来对组件的相关状态进行监测,一般的思路有两种:
  1.通过Java继承体系,为我们实现的四大组件分别建立基类,在基类父方法里对监测方法进行调用。
  2.通过Android API Hook技术,即通过动态代理等方法替换关键节点,抓住组件的节点方法并调用我们的监测方法。

-- Javassist动态编程- https://nickid.cn/2017/02/Javassist%E5%8A%A8%E6%80%81%E7%BC%96%E7%A8%8B/
Javassist是一个开源的分析、编辑和创建Java字节码的类库。它已加入了开放源代码JBoss 应用服务器项目,通过使用Javassist对字节码操作为JBoss实现动态”AOP”框架。https://github.com/jboss-javassist/javassist
对于第二种策略,实际上已经有诸多比较成熟的开源项目提供支持,如CGLib、ASM、Javassist等。这些开源项目通常都具备两方面的功能:
  动态创建新类或新接口的二进制字节码
  动态扩展现有类或接口的二进制字节码
我们常用到的动态特性主要是反射,在运行时查找对象属性、方法,修改作用域,通过方法名称调用方法等。在线的应用不会频繁使用反射,因为反射的性能开销较大。其实还有一种和反射一样强大的特性,但是开销却很低,它就是Javassit。

  类似字节码操作方法还有ASM。几种动态编程方法相比较,在性能上Javassist高于反射,但低于ASM,因为Javassist增加了一层抽象。在实现成本上Javassist和反射都很低,而ASM由于直接操作字节码,相比Javassist源码级别的api实现成本高很多。几个方法有自己的应用场景,比如Kryo使用的是ASM,追求性能的最大化。而NBeanCopyUtil采用的是Javassist,在对象拷贝的性能上也已经明显高于其他的库,并保持高易用性。实际项目中推荐先用Javassist实现原型,若在性能测试中发现Javassist成为了性能瓶颈,再考虑使用其他字节码操作方法做优化。
  总结:CGLib的底层基于ASM实现,是一个高效高性能的生成库;而ASM是一个轻量级的类库,但需要涉及到JVM的操作和指令;相比而言,Javassist要简单的多,完全是基于Java的API,但其性能相比前二者要差一些。在性能要求相对低的场合,Javassist仍然十分有用,如JBoss中就调用了Javassist。

  Dubbo使用Javassist来代替反射很巧妙的使用了Javassist动态通过字节码在消费者中创建了类并实例化,然后放入jvm内存中缓存起来,也就是ProxyCacheMap对象中,在第一次使用的时候通过Javassist动态创建然后放入缓存中,后续就直接从缓存中拿来用了,so~~~除了第一次慢,再使用当然快了,对于这个设计膜拜了!这才符合阿里的特点啊!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值