0x00 序
第一次嘗試做一些簡單的逆向分析,內容比較簡單,高手們莫見笑。
“貪吃蛇大作戰”這個
遊戲最近玩的人挺多,我也在玩。5分鐘限時版,最好成績也就3000多。
我分析的版本是v2.0.1:
經過修改,玩了一把5分鐘限時賽:長度69224,擊殺1456。
0x01 反調試和簽名校驗
將原包重新簽名,安裝到
手機上,一直提示網路無法連接,原包沒有問題。這裡很明顯是將簽名資訊上傳到了伺服器端,在伺服器端進行了簽名校驗,校驗失敗則斷開與此用戶端的連接。
寫一個小程式進行注入(利用ptrace),對一些關鍵函數進行hook,比如libc.so的fopen函數。
在hook_entry中,對libc.so的fopen作inline hook,監測一下程式都打開了哪些檔。
我本意是想看看,它是否會在運行時直接去讀取apk包,自己解析其中的與簽名資訊相關的檔。結果是沒有,但發現它一直在讀cmdline檔,猜測可能是在作反調試(未去證實,因為後面的分析和修改並未借助動態調試)。
這裡說一下,假設它是自己打開apk檔,從中讀取與簽名相關的檔,提取簽名資訊。那麼我們可以在某個位置放一個原包,然後hook關鍵函數,將其讀取的檔路徑修改為原包位置,即可繞過這種簽名校驗。
舉一反三,這種方式也可以繞過大部分反調試措施。比如常見的檢測traceid是否非0的反調方式,我們可以hook fopen/open,然後在它要讀取該檔之前先讀取該檔,並將其traceid重新修改為0,並將其寫到sd卡某個目錄下,再將打開檔的位置重定向到該檔,那它就檢測不到ptrace了。
還有一些anti-hook機制,大概思路是校驗本地檔的資料和載入到記憶體中的資料是否一致。通過類似方式也可以輕鬆繞過,一句話,因為我們可以先注入,先完成hook,先做各種Anti-anti。
0x02 破解簽名校驗
因為它沒有在運行時直接fopen/open apk檔,所以考慮應該還是通過調用系統api讀取的簽名資訊。
將原包解壓,發現只有兩個so,其中libweibosdkcore.so看起來是微博sdk。將另一個libJustATest.so拖到
IDA中看一下,沒加殼,並且只看到xxx_getATestString這麼一個有用的匯出函數,從名字上看,很可能就是獲取上傳到伺服器端的校驗字串。
跳轉到該方法,f5,進行一些簡單的參數名和參數類型以及函式呼叫的修正。發現它裡面進行了一大通的各種字串的拼接,最後將該字串返回(根據之前的猜測,該字串可能就是發送給服務端的校驗字串)。
發現裡面調用了java層com.wepie.snake.helper.update.QiniuEtagUtil類的getSignString函數。用
Androidkiller反編譯一下APK包(該APK沒有作任何防反編譯的措施,dex也沒加殼),找到getSignString函數。
沒錯,就是在這裡調用系統API獲取的簽名(其實,我們可以一開始就全域搜索某些關鍵API,來定位獲取簽名的位置)。
借助xposedhook getSignString方法,將正確的簽名字串通過日誌列印出來。
正確的簽名字串是(作了MD5計算後的結果):678a930b9829b54a44f92a840916f7d1
剩下的工作就簡單了,修改smali,將getSignString的返回結果固定為上面的這個正確的簽名字串。
重新編譯、打包、簽名、安裝,發現用新簽名的APK包已經可以正常使用了。
0x03 後序
其實破解簽名校驗之後,基本上是想改什麼改什麼了,因為原包沒有做任何的加殼和混淆的工作。比如,看看下面這個類,應該知道怎麼下手了吧(修改的時候注意一下,它裡面好像有一些簡單的資料合理性校驗之類的東西,我沒細看)。
最後,大家學習就好,別做什麼破壞,也別釋放出什麼
破解版之類的東西。初次嘗試一點簡單的逆向分析,大牛們繞過吧。
附:我認為現在so端最有用的加固措施是llvm混淆,因為普通加解密殼從機制上來說比較容易脫掉。dex端已經出現了解譯器殼(偽vmp),純粹的類抽取的話,通過自訂rom(定制dalvik或art,遍歷class_def載入並初始化,然後dump…)也可以脫掉大部分的。