1. 程式人生 > >爬蟲工程師分享:三步就搞定 Android 逆向

爬蟲工程師分享:三步就搞定 Android 逆向

本文源於我近期的一次公司內部分享,通過逆向某款 APP 來介紹逆向過程。由於僅作為學習用途,APP 的相關資訊會被遮蓋,敬請理解。

關於逆向

逆向——包括但不限於通過反編譯、Hook 等手段,來解析一些功能的實現過程。

逆向在很多領域都有應用,比如如今爬蟲技術已經遍地走,甚至不用寫程式碼都可以爬取資料,導致前端開發的反爬意識也逐步提升。因此 JS、Android 等領域的逆向,已經成為爬蟲開發者必備的技能之一。

本文介紹的是最典型常見的傳參加密,在很多應用介面都能見到,如果我們逆向解析出加密過程,就可以模擬出相同的密文,得到後端介面的“認可”。

逆向的準備

這裡介紹下關於 Android 的逆向準備:

  • Android 真機或模擬器(最好是真機)
  • 安裝 Android 5.0 或 6.0 版本
  • Fiddler、Charles 等抓包工具
  • Jadx、ApkTool 等反編譯工具
  • dumpDex、FDex2 等脫殼工具
  • Java、Android 開發基礎知識
  • Xposed 框架開發基礎知識

    逆向步驟

介紹一下本文逆向的步驟:

當然,用三步概括,看上去像“把大象塞進冰箱分為幾步”。逆向作為一項與應用開發者對抗的網路安全技術,其手段花樣多端,有時甚至不需要程式碼也可以完成逆向,所以這個概括僅對應文中的遇到情況。

定位目標

本次逆向是針對某款 APP 的訂單介面,首先我們使用抓包工具捕獲訂單列表請求,下圖為 Charles 介面:

可以看到引數裡的 data 欄位是密文,我們就使用這個 API 作為目標切入點。

反編譯 APK

這裡使用的反編譯工具是 Jadx,它可以將 APK 直接反編譯成 Java 程式碼,並且具有 GUI 介面方便操作,如下圖所示:

通過包名和一些程式碼分析,確定是被 360 加固後,接下來需要嘗試脫殼。

脫殼使用的是 FDex2,這是一款基於 Xposed 框架的 Hook 外掛,對 360 加固比較有效。它的原理是 Hook ClassLoader,然後通過反射呼叫 getDex 方法獲取 Dex 物件並匯出,這裡的 Dex 就是 APP 真正執行的部分。當然並不是所有加固都可以被 Hook 到,更多脫殼手段還需要進階研究。

FDex2 使用方式很簡單,在 Xposed 框架裡啟用後,選擇目標 APP,然後重新開啟 APP 後,被捕獲的 Dex 檔案會被儲存下來,如下圖所示:

Dex 是什麼?簡單地說,在 APK 構建過程中,Java 程式碼編譯後產生的 class 檔案,需要再轉化成 Dex 檔案,才能被 Android 虛擬機器執行。

因此我們得到的 Dex 檔案,就可以再次反編譯成 Java 程式碼,我們還是使用 Jadx,它同樣支援 Dex 格式。

由於 Dex 有體積限制,會被分包,如上圖我們匯出了不止一個檔案,可以依次載入它們,通過搜尋目標 API 的關鍵詞,來找到目的碼塊,如下圖所示:

程式碼一般都會被反混淆,變數和方法名都是 a b c d 這樣,然後搜尋一個方法名,會發現有一萬個同名的變數。還好 Jadx 內建了反混淆,開啟後變數和方法被重新命名為唯一編號,這樣搜尋時就不會有重名的情況了。

之後我們通過 Jadx 將程式碼匯出成 Gradle 專案,藉助 IDEA 的強大功能開始進行程式碼分析。

分析程式碼

由於大部分方法都是被重新命名的,導致可讀性嚴重下降,無法推測每個方法到底是什麼功能,如下圖這些程式碼:

第一眼你除了知道它是 Google 開發包之外,無法再獲得更多資訊。

所以分析程式碼這個步驟,完全是考驗你的 Java 基本功 + 耐心,二者缺一不可。

不過不要退縮,我們只要遵循一些技巧,就可以大幅減少工作量。由於分析過程比較繁瑣,這裡就不結合具體程式碼了,只做一些理論總結:

  1. 從目標 API 開始入手,跟蹤執行流程: 比如我們剛才已經搜尋到關鍵詞程式碼,那就從那一行開始,通過 IDEA 檢視方法功能,可以一路向下點選。
  2. 只分析涉及程式碼塊,縮小分析範圍: 請求過程通常會構建 Request 物件,那引數加密一定就在構建物件之前,我們只要找到構建 Request 物件的程式碼,然後檢視加密引數被傳入之前都經過了怎樣的處理,其他程式碼全部無視。
  3. 將部分程式碼塊複製出來進行執行: 雖然反編譯的專案程式碼無法被整體執行,但對於冗長難懂的方法程式碼,我們可以連同相關程式碼一起復制到一個新專案中,進行編譯執行,方便我們除錯。
  4. 嘗試搜尋一些關鍵詞: 程式碼並不會所有都被混淆,可以嘗試全域性搜尋一些關鍵詞。比如 Java 常用的加密演算法,我們可以搜尋 RSA、AES、MD5、Encrypt、public_*key 這些關鍵詞和正則匹配,能搜到再好不過了。

當你找到了加密方法,那麼可以複製出來獨立執行,然後自己構建引數傳入加密,通過模擬請求,看介面是否正常返回。

需要注意,如果不能正常請求,並不一定是你找錯了地方,也有可能程式碼本身有誤,反編譯的程式碼是有機率會出現這種情況的,導致你執行的和 APK 執行的結果不同。遇到這種情況,只能通過其他手段來修正程式碼,如閱讀 Smali 程式碼、通過 Hook 等手段,這種情況比較複雜,後續會有文章單獨介紹。

逆向之後

完成程式碼分析後,恭喜你已經成功完成一次逆向,接下來就可以實現一些功能,比如模擬登入請求。建議直接使用 Java 程式碼,因為大部分加密用的是 Java 內建的 RSA / AES 加密演算法,其他語言的第三方庫實現並不充分。


至此本次逆向分享結束,逆向是一個大課題,本文由於篇幅原因,也只能將常見套路的大致流程介紹一下,後續一定追加更多細節部分的文章。

本文首發自我的微信公眾號:面向人生程式設計

關注後回覆以下資訊獲取更多資源
回覆【資料】獲取 Python / Java 等學習資源
回覆【外掛】獲取爬蟲常用的 Chrome 外掛
回覆【知乎】獲取最新知乎模擬登