说说编译插桩

1.什么是编译插桩?

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


Java-字节码-dex

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

  • Java 文件。类似 APT、AndroidAnnotation 这些代码生成的场景,它们生成的都是 Java 文件,是在编译的最开始介入。
  • 字节码(Bytecode)。这是一般情况下讨论最多的操作字节码的方式。可以操作“.class”的 Java 字节码,也可以操作“.dex”的 Dalvik 字节码,这取决于我们使用的插桩方法。
    相对于 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,以基于对象的形式来表示类。

  • 核心 API
    在采用基于事件的模型时,类是用一系列事件来表示的,每个事件表示类的一个元素,比如它的一个标头、一个字段、一个方法声明、一条指令,等等。基于事件的 API 定义了一组可能事件,以及这些事件必须遵循的发生顺序,还提供了一个类分析器,为每个被分析元素生成一个事件,还提供一个类写入器,由这些事件的序列生成经过编译的类。核心的类是ClassVisitor和ClassReader。
    特点:使用者可以不用关心字节码的格式,只需要在每个 Visitor 的位置关心自己所修改的结构即可。但是这种模式的缺点是,一般只能在一些简单场景里实现字节码的处理。
  • 树 API
    而在采用基于对象的模型时,类用一个对象树表示,每个对象表示类的一部分,比如类本身、一个字段、一个方法、一条指令,等等,每个对象都有一些引用,指向表示其组成部分的对象。基于对象的 API 提供了一种方法,可以将表示一个类的事件序列转换为表示同一个类的对象树,也可以反过来,将对象树表示为等价的事件序列。换言之,基于对象的 API 构建在基于事件的 API 之上。核心是ClassNode,可以在此基础上增加或者删除属性,成员之类的,当然还有更高级的。缺点是:如果使用者对字节码不熟悉的话不好操作

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

  • (1)熟练掌握字节码相关技术。之前提到过
  • (2)groovy语言和Gradle自定义插件,可以直接参考官网
  • (3)如果你想运用在Android项目中,那么还需要掌握Transform API
    这是android在将class转成dex之前给我们预留的一个接口,在该接口中我们可以通过插件形式来修改class文件。共两步,第一步继承Transform接口,第二步register
  • (4)字节码修改工具。如AspectJ,ASM

4.插桩实践

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

  • (1)继承Transform实现字节码的修改(其中就有asm的应用,对ASM有所了解的话基本能看懂第一篇文章里面的modifyClass这个函数是干嘛的。文章中用的是对象API,其实用核心API应该也可以)
  • (2)注册并且对外使用插件

5.总结

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容