"**遊"強制更新破解

很久沒有更新博客了,由於一些特操蛋的事情,一直沒有心思寫。上兩週終於把《Android 軟件安全與逆向分析》 看完了,而後就總是想找個 apk 練練手,可是水平太差,稍微加密就啃不動了。恰好遇到了這個 apk 習慣性逆向分析。java

傳送門:"**遊"強制更新破解android

0x00 前言

前幾天客戶有提到一個做弊工具,因此就想下載體驗一下。結果下載的應該是一個較早的版本須要強制更新到最新版本,否則不能運行。
更新提示:
1.png
因此就想破解一下他的強制更新練練手,由於感受不難。json

0x01 分析Java代碼

利用 jadx-gui 反編譯 apk,jadx-gui 這個工具仍是挺好用的。一條命令就能夠看到反編譯後的 Java 代碼,還有資源文件。安全

AndroidManifest.xml分析

Application 是 Android 程序的主入口,也是分析 apk 的開始點。並且經過運行程序也能夠發現。跳出的升級的 Dialog 是在程序運行後第二個頁面跳出的,第一個頁面爲啓動頁面。因此重點分析對象就是 Application 到第二個頁面。
AndroidManifest 查找 application 標籤看有沒有自定義 Application
2.png網絡

過濾 android.intent.action.MAIN 查找第一個頁面。
3.pngapp

Activity分析

自定義的 Application 中沒有什麼信息,只是作了一些配置的初始化和第三方 SDK 初始化的。函數

SplashActivity

SplashActivity 是 apk 的第一個頁面也就是啓動頁面,由於代碼沒有作混淆處理,其中咱們仍是能夠發現一些關鍵的代碼。
4.png
5.png
變量 isUpdate 是關鍵點,也能夠發現這個頁面停了100ms後會跳轉到 MainActivity 頁面。可是這個頁面只是對變量 isUpdate 進行了判斷賦值沒有進行升級的處理。工具

MainActivity

MainActivity 真正的主頁面,查看 onCreate方法。
6.png
當時只看到了第二個標註的代碼,心想這不是改下 if-else 的事嗎。(下面會將第一個標註)ui

0x02 修改Smali代碼

apktool 反編譯 APK,沒有作過加固處理直接。定位到 MainActivity.onCreate 方法,修改if-else邏輯,將if-eqz v3, :cond_3改成如下代碼:
7.png
本來爲 isUpdatetrue時,執行 isUpdateAlert() 方法。改成 false時執行。 順便還加了一個 Log,回編安裝運行。
8.png
結果發現本身仍是太年輕,沒有繞過升級。雖然Log是有打印了,證實代碼是沒有問題的,可是在升級的 Dialog 仍是出現了,而且以前還有一個 Dialog。
9.png
那天研究太晚了就睡覺去了。this

0x03 從新分析代碼邏輯

次日想一想確定是本身哪裏分析錯了,又從新看了一遍代碼。首先看下以前認爲是改變邏輯後執行的函數 isUpdateAlert():
10.png
能夠看到當用戶點擊肯定的時候只改變了 SplashActivity.isUpdate 的值,沒有其餘操做了。再查找一下 R.string.str_reminder 的值在目錄 res/values-zh/strings.xml:
11.png
好吧事實證實本身還太年輕啊。

分析變量 isUpdate 的做用

因此能夠先回到 SplashActivity 看看變量是怎麼賦值的。
12.png
能夠看到 isUpate 的值是根據 Initialized 文件中保存的值跟當前APK的版本作比較獲得的值。
13.png
方法 setInitFlag 則是將當前版本寫入 Initialized。這樣看來貌似 isUpdate 不可能爲 true了。 再看下什麼地方調用了這兩個函數:
14.png
到這裏能夠明白了,Initialized 文件是寫入當前版本號,可是當apk更新後版本號變了,跟 Initialized 中的版本號就不同了。因此 isUpdate 記錄的是當前 APK 是否是已經更新過了而且第一次打開,而不是當前 APK 是否是須要更新。

0x04 burp抓包分析

經過從新分析能夠判定以前的修改是錯誤的了,可是既然 APK 須要判斷是否須要更新那麼就必須有網絡請求,burp 該上場了,掛上代理打開APK:
15.png
這裏請求成功的只有三個 HTTP 請求(百度地圖的忽略),HTTP 還省了導入證書了。一個一個分析請求的 response 。抓包這個技能仍是必須掌握的:
16.png
知道了哪一個接口調用的那就簡單了,直接找出這個接口的類:
17.png
用的友盟的更新模塊,因此我上面忽略的纔是真正的更新代碼。

UmengUpdateAgent.setUpdateOnlyWifi(false);
UmengUpdateAgent.forceUpdate(this);

再看 com.umeng.update.UpdateResponse 這個類的 a(JSONObject) 方法:
18.png
對比返回的 response (burp複製出來中文亂碼了,看key就好)

{
  "update": "Yes",
  "version": "12.1.2",
  "path": "http://au.apk.umeng.com/uploads/apps/5386ea3b6c738f0de0000025/_umeng_%40_188_%40_09e2ea839754f61d4fb24ddb96a638bf.apk",
  "origin": "",
  "update_log": "天下游12.1.2\r\n1.修复小米5不能使用的问题\r\n2.降低电量消耗、提高稳定性和兼容性\r\n3.更新会清除12.0以前版本数据\r\n4.更新完成后请重启手机,以使更新生效!!!\r\n5.如遇到不能使用的情况,请到“问题反馈”中描述问题并留下您的联系方式",
  "proto_ver": "1.4",
  "delta": false,
  "new_md5": "09e2ea839754f61d4fb24ddb96a638bf",
  "size": "18278969",
  "patch_md5": "",
  "target_size": "18278969",
  "display_ads": false
}

因此這個類就是處理返回值的地方了。這不是修改一下 Yes字符串就完了,哈哈哈哈哈哈。

0x05 再次修改Smali

添加了Log 將 Yes 改成 No:

19.png

回編 安裝 運行,終於再也不提示更新了。。。。。。。

0x06 總結

逆向分析真是一個細緻活啊,稍微有點忽略就走了彎路。另外對於 release 的版本的APK 最好能夠進行 proguard 混淆和加固,如今有不少第三方加固都提供免費的服務了,作了這兩步我想就能擋住不少像我這樣的菜鳥了。 好久沒更新博客,這篇也寫了好幾天才寫好。。。。。。。。。

相關文章
相關標籤/搜索