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

相關文章
相關標籤/搜索