Android编译插桩

背景:这一次分享一下关于android编译插桩这个话题,在正常编写代码实现程序的逻辑外,还要使用一点点黑科技,拿起操做代码无所不能的武器。html


1、Android经常使用的能动态改变代码逻辑的方法有两种

  1. Java hook(反射,动态代理) android是基于java,同时也就有了反射的概念,动态去加载代码,同时动态代理也能够实现,但比较难理解,网络上讲得也不少了,这里就不讲。
  2. 插桩(编译插桩,插件化插桩) 若是是按照插桩时机,在编译时候的就是编译插桩,然而,有些时候须要在程序运行的时候动态加载一些东西。我理解的差别性是插桩的代码是跟原来程序是分开的,在一个特定的时机与原有程序合二为一。

2、从xposed框架到编译插桩

记得去年曾经分享过xposed框架的使用,那是在系统层面去hook住方法,不足之处是系统要先刷入框架包,优势是能够对该系统里面全部的app进行hookjava

是否能够对咱们本身的应用进行代码的修改?好比上面提到的有java hook,还有编译插桩:下面是比较流行的框架android

  1. aspectJ (面向切面框架) 跟普通代码同样,理解容易
  2. Asm (操做字节码框架)须要使用asm字节码,相对复杂

而插桩的应用场景:apm,无埋点git

3、比较一下aspectJ 与asm分别插桩后的代码

1. aspectJgithub

2. asm网络

经过上面两个图能够看出插桩后的代码仍是有所区别,aspectJ采用插入方法的方式,这种代码混淆的时候必定要注意,否则会出现找不到方法名。而asm采用直接把差别代码嵌入原有的方法里,显然执行起来更加高效。app

asm实现的插桩

1. 原代码框架

2. 字节码ide

3. asm代码工具

能够看出代码相对来讲是比较复杂的,可能须要工具才能正确去编写asm代码,好比idea插件bytecode outline

asm在编译打包的哪一个步骤插桩呢

如图所示:在编译成.class文件后,执行asm步骤,对class文件进行处理。然后就把各类编译后的文件打包进dex文件的过程。

demo-采用asm为某个方法插入代码

一个简单的demo,对一个方法进行asm插桩

github.com/ydpzg/TestP…


附录

自定义gradle plugin

guides.gradle.org/writing-gra…

docs.gradle.org/current/use…

Asm 字节码插件: Asm Bytecode Outline

java字节码: javac Apple.java javap -verbose Apple.class

相关文章
相关标签/搜索