说说编译插桩

2019-12-04  本文已影响0人  勇敢地追

1.什么是编译插桩?

顾名思义,所谓的编译插桩就是在代码编译期间修改已有的代码或者生成新代码。


Java-字节码-dex

如图,这是Java代码的编译流程。从图中可以看出,编译插桩可以从两个方面着手

说到这里,有必要说一下Java字节码和Dalvik 字节码
java字节码可以参考这篇文章作为了解一文让你明白Java字节码,里面演示了如何将字节码反过来解析出对应的class文件。我自己也按照他的方法解析了一次class文件字节码解析
Dalvik 字节码可以看这篇dex文件字节码解析这篇文章开头还有对应的参考链接,本人按照这两个链接做的
总的来说,dex文件比class文件要复杂得多.一方面是小端排列,另一方面需要寻址.最重要的一点是,class文件的类索引里面所有的信息都是直接排进去的,但是dex文件里面的类都是存的索引,dex文件更为紧凑.也就是意味着,如果需要修改dex文件,那么他的成本会比修改class文件难得多

2.编译插桩的两种方法

(1)AspectJ

AspectJ是 Java 中流行的 AOP(aspect-oriented programming)编程扩展框架,它内部也是通过字节码处理技术实现的代码注入。本人也做了大略的了解,具体文章在这里简单聊聊AspectJ
从使用上来看,AspectJ 的框架的确有自己的一些优势,比如成熟稳定,使用简单。但它也有劣势,比如切入点固定等。如果想要做更细致的修改,它就无能为力了。
具体的实现可以参看《AspectJ程序设计指南》这本书

(2)ASM

如果说 AspectJ 只能满足 50% 的字节码处理场景,那ASM就是一个可以实现 100% 场景的 Java 字节码操作框架,它的功能也非常强大。
使用 ASM 操作字节码主要的特点有:操作灵活,可以根据需求自定义修改、插入、删除。上手比较难,需要对 Java 字节码有比较深入的了解。
下面简单介绍一下ASM
ASM 库提供了两个用于生成和转换已编译类的 API,一个是核心 API,以基于事件的形式来表示类,另一个是树 API,以基于对象的形式来表示类。

3.掌握插桩应该具备的基础知识

4.插桩实践

字节码插桩--你也可以轻松掌握,Android字节码插桩——详细讲解 附带Demo
其实这两篇文章我只是大致理解了,并没有运行。第一篇是因为一直没要到demo。第二篇是因为gradle要5.1.1,据说AS必须要3.4.1.升级了我的其他的程序大概率受影响,就没决定升级.但是gradle也没办法降下去(会提示最低支持5.1.1),所以就放弃了。不过也大致理解了具体的流程

5.总结

要想实现编译插桩,就必须要了解字节码,了解ASM,了解groovy。(本人对后面两个都不熟,只算基本了解。看来还有很长的路要走。这篇文章仅仅作为入门的了解)

上一篇 下一篇

猜你喜欢

热点阅读