天天看點

Android反編譯與Xposed所必須了解的事情(一)

一、内容的由來

最近做了一些反編譯的工作,對反編譯的了解從模糊到入門,再到感到敬畏。到現在我竟然不确定我是在門外還是在門内,但我對這件事感到興趣濃厚,是以準備寫幾篇入門文章記錄一下,也順便梳理一下最近做的事情。

二、反編譯的目的

  • 學習對方的架構、研究實作邏輯
  • 找到想要的資料,爬對方的資料
  • hook特殊的方法,進行app的功能拓展
  • 快速熟悉新工程,找到對應的Activity或方法調用棧
  • 研究對方的加強及加密方案,提高自身的安全性等級

三、需要準備的工具

1、apk-tools

主要作用:

  1. 将apk包解開,檢視資源檔案、manifest檔案等
  2. 将解開的apk修改内容後再進行打包,此時需要加一步簽名apk

下載下傳位址:https://ibotpeaches.github.io/Apktool/

2、d2j-dex2jar

主要作用:将dex檔案翻譯為jar檔案,其中會有smali檔案轉成.class檔案的過程

下載下傳位址:https://github.com/pxb1988/dex2jar

3、JD-GUI

主要作用:檢視dex2jar生成的jar檔案的内容,查找需要的代碼邏輯

下載下傳位址:https://github.com/java-decompiler/jd-gui

4、Xposed

主要作用:hook住對應方法。通過動态代理或者反射調用來實作自己想做的事情。這裡classloader的擷取當然是最關鍵的。

下載下傳位址:https://forum.xda-developers.com/showthread.php?t=3034811

注意事項:一定要找到手機對應版本的apk,否則是不能運作的

四、做些有意思的事情

1、簡單的事:打開某個APP的LOG開關?

*為了避免不必要的麻煩,我随機選了一個APP,并全程打碼,隻是示意,沒有惡意。

主要步驟:

1、通過apk-tools确定包名等相關資訊。

指令為:java -jar apktool_2.4.0.jar d xxx.apk

結果圖:

Android反編譯與Xposed所必須了解的事情(一)

打開AndroidManifest.xml,檢視其中内容:

Android反編譯與Xposed所必須了解的事情(一)

輕松得到包名和主入口之類的東西。

在<Application>标簽裡面會有android:debuggable的屬性值,可以修改為true,然後進行重新打包。就相當于打開的debuggable的開關。

重新打包的指令為:

java -jar apktool_2.4.0.jar b 需要編譯的檔案夾名 -o 輸出的對應apk檔案名(xxx.apk)

此時就生成了一個沒有簽名的,debuggable是true的apk包了。因為沒有簽名是以安裝不上,接下來就需要給apk簽名。

指令為:

jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore keystore檔案 -storepass 密碼 對應的apk(xxx.apk) key名(key0)

然後裝機運作,如果沒有sign驗證的apk現在你已經成功打開debug開關了,不過一般是不行的。?

我使用apktools一般就隻是進行包名和結構的檢視...

2、剛才的apk我們通過dex2jar和JD-GUI進行檢視,找到LOG的管理類

(1)解壓apk檔案,找到對應的dex檔案

(2)用dex2jar将dex檔案反編為jar

指令為:

sh d2j-dex2jar.sh dex檔案的路徑

生成出來一個dex.jar檔案

Android反編譯與Xposed所必須了解的事情(一)

用JD-GUI打開對應的jar檔案,這時會兩種情況。

  • 加強
Android反編譯與Xposed所必須了解的事情(一)
  • 未加強
Android反編譯與Xposed所必須了解的事情(一)

現在先隻讨論未加強狀态的輸出,加強的在之後介紹。

3、接下來就是看源碼咯~

這時候你可能需要的一些工具,我基本都是自己用Xposed寫的工具,主要有:

(1)檢視Activity、Fragment的調用棧(當然有些人喜歡看方法的調用棧,但是我覺得有點亂...)

(2)網絡請求的抓包工具

(3)OkHttp的LoggingInterceptor的HOOK

還有一些你需要知道的指令知識,因為JD-GUI并不一定能都給你翻譯的明明白白(有内部類,内部類又不在同一個dex包中時就不會給你翻譯),掌握一點指令知識也是應該的,你主要需要的指令有:

aload_0 将this壓入棧,每個目前類方法調用前都得壓入一個this才能調用
aload_1 将位置為1的對象引用局部變量壓入棧
astore_1 從棧中彈出對象引用,然後将其存到位置為1的局部變量中
其他的 猜一下,猜不出來查一下

然後舉個例子:

//   34: aload_3
    //   35: aload_1
    //   36: invokevirtual handleState : (Lcom/package/bean/Message;)V
           

這個意思就是aload_3出來的對象的handleState方法,參數是aload_1的内容,傳回值是個com/package/bean/Message。然後找對應的astore_3是什麼類的對象就可以看懂了。

這不是smali的指令,smali的指令是這樣的

.local v0, args:Landroid/os/Message;
const/4 v1, 0x12
iput v1, v0, Landroid/os/Message;->what:I
           

相當于:args.what = 18;

4、這時候找到了對應的LOGGER檔案了,檢視一下邏輯,然後看看打開開關需要把什麼參數給改掉,例如enable啥的

5、Xposed登場,進行hook,修改enable的值

這一步内容比較多,在下一篇文章中進行詳細介紹吧~