天天酷跑APK修改反編譯簽名?

Tags: 酷跑, 反編譯,

Android apk反編譯學習【天天酷跑】

微信遊戲出來之後,網上出現很多破解教程和攻略,修改最多的有無敵打飛機,無限彈藥,刷分數,天天酷跑刷金幣等。看了下破解方法不外乎以下兩種:

1、反編譯遊戲apk包,修改smali位元組碼,重新打包。

2、暫停執行時軟體,在記憶體中查詢關鍵遊戲數值,直接修改記憶體資料。

(此外聽朋友說起其他破解方式,如修改本地cache檔案中的程式資料,但前提得是資料沒有儲存於服務端)

工作時長期疲於應對應用層開發,早該學習一些基礎的破解和防破解技術,也有助於保護自己開發的應用,且最近痴迷《天天酷跑》,天天努力趕超小夥伴,遂嘗試將其作為“破解”物件娛樂一下(這可比玩出高分再向小夥伴炫耀有趣多啦),由於之前沒有任何破解經驗,並不知道能破解到什麼程度,抱著學習的態度一步步嘗試之。

動手之前先學習前輩經驗,這裡有一篇打飛機破解文章,講解詳細清晰:

歸納一下文章內容,微信客戶端和其遊戲是平臺與外掛關係,整個打飛機遊戲是一個jar包,位於微信apk的assets目錄下,微信通過動態載入的方式執行,其中包含classex.dex,res,so庫(用JD-GUI開啟這個jar包可以看到)。動態載入時會拷貝該jar包到data目錄,解壓後將其中的資源釋放出來。拷貝之前將進行一次簽名校驗,如果jar包被修改過,簽名校驗將無法通過,想要破解遊戲,必須對jar包中的程式碼進行修改,那就得找到繞過簽名校驗的方法。

開始之前先學習一下簽名校驗的原理和如何繞過簽名校驗。

Android簽名生成步驟和原理:

我們在App開發完成後將其編譯為apk包,這個時候包中沒有簽名信息,如果直接通過adb install安裝到手機上,將會報錯:[INSTALL_PARSE_FAILED_NO_CERTIFICATES]

解壓apk包可以發現未簽名的apk中不包含META-INF目錄,該目錄在簽名後生成,其中包含簽名信息相關的3個檔案CERT.RSA,CERT.SF,MANIFEST.MF,簽名過程就是這3個檔案的生成過程。

簽名第一步:遍歷apk中所有檔案(entry),逐一生成SHA-1數字簽名,然後通過Base64編碼,寫入MANIFEST.MF檔案。

vim檢視MANIFEST.MF檔案內容如下:

Manifest-Version: 1.0Created-By: 1.0 (Android)Name: res/drawable-hdpi/m03_0.pngSHA1-Digest: Odo4l7R6YcmMl9HtbhLpb8hChts=

Name: res/layout/shop_fav_item.xmlSHA1-Digest: CVvGtpAo1cLWo7OQfR3tZQwYOY4=......

第二步:使用SHA1-RSA演算法,用私鑰對MANIFEST.MF摘要檔案簽名,並對其中每個檔案摘要簽名,生成CERT.SF檔案

vim檢視其內容如下:

Signature-Version: 1.0Created-By: 1.0 (Android)SHA1-Digest-Manifest: 4pIv24erc5QG+i/kLOOhG6n+EdY=Name: res/drawable-hdpi/m03_0.pngSHA1-Digest: 9ZYIfLFplSPcDEIxLJl0JUzmJLs=Name: res/layout/shop_fav_item.xmlSHA1-Digest: nqQ+nd6yZn3sB5LfHltWOYlXJMA=

......

(SHA1-Digest-Manifest:是對MANIFEST.MF檔案的摘要簽名後的值)

第三步:生成CERT.RSA檔案,其中記錄了RSA公鑰,加密演算法等資訊用於簽名校驗,該檔案是二進位制格式,有興趣可以研究下。

插入學習一下RSA加密和簽名原理:

RSA有2種應用方式,加密和驗證,這裡只用到了驗證,為了使整個實現過程更加清晰明瞭,先學習下其原理,這裡我們可以假定加密和驗證過程無法被破解,通過私鑰加密的資訊唯有公鑰才能解密。

RSA加密過程(以客戶端A傳送一條訊息給客戶端B為例,其中A持有公鑰,B持有私鑰):

客戶端A訊息原文:msg

將msg對映為整數(實際上分為很多段整數):Int(msg)

用公鑰進行加密:En( Int(msg) ) )

————傳送加密後的資訊————

客戶端B收到加密資訊:En( Int(msg) )

用私鑰解密:De( En( Int( msg) ) ) = Int(msg)

還原msg:UnInt( Int(msg) ) = msg

(通過私鑰加密的資訊唯有公鑰才能解密,可以確保資訊不會洩漏)

RSA簽名與驗證過程(客戶端A傳送一條簽名後訊息給客戶端B,B驗證該訊息是否為A發出或者未被篡改,其中A持有私鑰,B持有公鑰):

客戶端A訊息原文:msg

對msg提取摘要:Dig(msg)

對摘要Base64編碼:Base64( Dig(msg) )

用私鑰進行簽名(把摘要當作已經加密後的內容,用私鑰解密):Sign( Base64( Dig(msg) ) )

————傳送訊息和簽名————

客戶端B收到資訊和簽名:msg 和 Sign( Base64( Dig(msg) ) )

對msg提取摘要:Dig(msg)

對摘要Base64編碼:Base64( Dig(msg) )

將摘要當作未加密過的內容,用公鑰加密:En( Base64( Dig(msg) ) )

簽名驗證,即判斷En( Base64( Dig(msg) ) ) 和Sign( Base64( Dig(msg) ) )是否相等。(這裡的Sign跟上面的De一模一樣)

(通過私鑰加密的資訊唯有公鑰才能解密,可以驗證這條訊息肯定是A發出來的)

在Android裡面簽名驗證的實現:

覆蓋安裝時用舊版本的公鑰對新安裝apk包中MANIFEST.MF進行加密,生成新的MANIFEST.MF'檔案,再和原始的MANIFEST.MF檔案對比所有的摘要資訊是否一致,以此確保是否為同一個機構釋出的升級app。(實際當然不是生成新的MANIFEST.MF'檔案,可以這麼理解)

瞭解簽名原理之後,再結合一下簽名機制的應用場景:

1、個人開發者或機構想要通過Android Market釋出app,必須使用官方提供的keystore證書為程式簽名,作用是防止你的app被惡意覆蓋安裝。(app升級時若簽名不一致將不能覆蓋安裝)。

2、執行時程式自檢簽名(如果簽名不符可以直接crash,強行退出,外掛呼叫不起來等)。

回到如何繞過打飛機外掛簽名驗證問題,首先破解微信之後不可能用私鑰重新簽名,所以覆蓋安裝不考慮,解除安裝正版微信即可。其次則是考慮如何繞過打飛機外掛載入時的簽名校驗,作者嘗試利用ANDROID-8219321漏洞(修改外掛包內容而簽名校驗時計算出的校驗值保持不變),但利用該漏洞將會在外掛包中產生2個classex.dex檔案,導致檔案改動,而打飛機外掛包的檔名中巧妙的包含了該jar包的md5值,任何jar包的改動均將導致md5值發生改變,微信外掛載入時將進行簽名+外掛md5值雙重校驗,要想繞過只有修改微信的smali code,找到md5校驗方法然後遮蔽掉(利用漏洞的話簽名就不用遮蔽)。作者因為沒找到md5校驗程式碼,最終採用了系統app+遮蔽簽名校驗的方法(系統app簽名校驗時只會校驗mainfest.xml檔案,但是必須安裝在system/app目錄下,手機需要root然後將system分割槽mount為可寫),也即jar包可以修改,修改後計算出新的md5並且重新命名即可,"安裝時微信的簽名校驗依舊可以通過",同時遮蔽微信對外掛的簽名校驗,大功告成!接來下就是對打飛機外掛的smali code一頓狂改了。

仔細分析了好久發現作者在繞過簽名這裡有些多餘,既然不可能使用私鑰簽名破解後的app,繞過簽名的意義就在於可以覆蓋安裝正版微信(簽名保持“不變”,利用ANDROID-8219321漏洞,或者安裝到system/app目錄下作為系統應用,然而既然決定安裝到system/app目錄下,考慮"安裝時微信的簽名校驗依舊可以通過"這個問題純屬多餘)。我們完全可以使用自簽名,給破解後的微信app和外掛用自己的證書籤名。這樣微信app和外掛均可以隨意修改之。

從簽名的驗證和一系列繞過辦法可以發現比較靠譜的安全策略是程式執行時使用navite程式碼進行簽名自檢,比如將1.0版本apk中MANIFEST.MF檔案的簽名值儲存在雲端,程式執行時通過native程式碼將用公鑰解密後的值傳送至雲端進行對比,只有這種方法破解難度較大。

搞清楚了打飛機的破解原理,接下來嘗試破解天天酷跑,然而實際情況卻有很多不一樣。

首先天天酷跑和打飛機兩者的外掛機制不一樣,天天酷跑是一個獨立應用,和微信屬於app間相互跳轉關係。此外天天酷跑的遊戲程式碼幾乎全在native層實現(NPEEngine),基本上無法修改,令人沮喪,剛開始的時候並沒有意識到這一點,但是無論無何還是要玩一玩的。

使用apktool反編譯之後,可以修改其中的res資源,ogg聲音,配置檔案,smali code。

然後重新打包,使用自簽名,重新安裝。執行之後通過微信好友連線玩不了-_-!,應該是簽名校驗或者其他的什麼校驗沒通過(沒有進一步研究),但是可以連線qq好友,qq使用sso登入,校驗竟然通過了,也算是發現個漏洞。

遊戲大部分資源都在assets目錄中,其中的圖片,配置,地圖等都是二進位制格式的無法修改。只有少量幾個json和xml的配置檔案可以改改,但都涉及不到核心,只能簡單修改下預設角色的重力,彈跳速度等,動態性做得太好,很多資源都是執行時從服務端load,比如新增的角色,升級資訊,寵物,坐騎等。

其次學習了下smali code,這個簡單又好玩,最後附上修改的截圖,只能拿去逗一下小夥伴...

(另外換了下icon,惡搞的聲音,角色彈跳屬性)

啟動時加個對話方塊:

邀請或分享給好友時,修改展示文案,並把下載連結替換為破解app的下載地址

相關問題答案