第一次嘗試反編譯繞過 apk 簡單的 jni 簽名校驗

第一次嘗試反向操做繞過 apk 簡單的 jni 簽名校驗


1. 現象

修改了應用的內容以後,搜索 smali 沒發現有作應用的簽名校驗,但重打包以後應用打開直接出現閃退。查看日誌,肯定是 jni 方法作了簽名校驗。java

JNI日誌

Caused by: java.lang.UnsatisfiedLinkError: JNI_ERR returned from JNI_OnLoad in "/data/app/pkgpath/lib/arm64/libencryption.so"

錯誤出如今JniUtils去 load libencryption.so 的過程當中,查看 java 代碼,發現這個庫是用來作 aes 加密的,每個網絡請求都會用到這個方法,把簽名校驗放到這裏的JNI_Onload能夠防止直接從java層去掉LoadLibrary緩存

打開(下載安裝) IDA 看代碼。安全

2. 定位

因爲第一次下載 IDA ,最開始下的 IDA Free 不支持 arm,又從新去搞 IDA Pro。網絡

第一次用了 ida64 去加載 armeabi-v7a 的文件,才直到須要區分64位,用不一樣的 exe。app

終於成功加載了,直接搜索Signature,找到了一個checkSignature方法,而後在右邊看不懂的界面裏看到了熟悉的字符串,這個應該就是用來比較的本地簽名緩存了。學習

簽名

由於是簡單的簽名校驗,只要把這個值改爲咱們重簽名以後的 MD5 值,應該就能夠了。最簡單粗暴的方法,直接改數據。。。測試

粗暴改法

在 Hex View 中找到字符串,按 F2 編輯,能夠看到直接改16進制的值,就能夠生效了。把這一段替換好後,保存重打包,就能夠正常運行了。加密

但這樣改實在是太Low了,也沒有學到任何知識。仍是須要找到錯誤的出處,嘗試去繞過校驗,不是簡單的修改簽名設計

第一次用 IDA,邊查教程邊操做。先用Ctrl+F5讓 IDA 反編譯一個 C 的僞代碼出來,IDA-View 裏面全是指令,徹底看不懂。指針

200KB 的 lib 直接導出了一個三萬多行的 C 文件,看的讓人頭大。不過總算是能理一理邏輯了,先看出現錯誤的 JNI_OnLoad 方法。能夠看到在判斷簽名非空和checkSignature的結果的地方,return -1或版本號。

簽名

定位到問題,接下來就要解決怎麼改了。

3. 修改

做爲只能看得懂一點點 smali 的菜雞,對於 IDA 裏面顯示的內容沒有一處能看得懂。

人菜癮大

找到了對應的方法位置,要是 smali 代碼,真的是隨便就改掉了。這個第一次搞,徹底無從下手。

迫於人菜癮還大,不會改if(!checkSignature()),也不會直接改return 65542,最終決定從checkSignature方法的返回值下手,讓他不管如何都return true就行了。依靠Copy to assembly,把反編譯後的代碼放到天書裏面,至少讓我看到了哪是哪。

開始修改

能夠看到這裏調用了strcmp方法,比較 s1 與 s2 ,直接把這裏改爲 s1 比較 s1 就行了。

改

想法是美好的,改這個參數花了很久,最後用key-patch實現了,直接改這裏的調用

修改內容

修改後從新看反編譯的代碼,實現了繞過簽名校驗的功能。

結果

4. 測試

64和32位的庫都對應修改好以後,從新打包簽名,運行正常。

5. 總結

比較笨方法直接改存儲的簽名信息,後面更多的是嘗試修改 lib 庫的代碼。

理代碼邏輯,修改內容可比繞過簽名校驗自己有意思多了,後面仍是要多學習。

6. PS

我本身寫的第一個 jni 的代碼,就是從網上扒來的簽名校驗,實現幾乎和這個如出一轍,在Application:onCreate中調用 JNI 方法,而後方法內和寫死的簽名比較,錯誤的話直接killProcess。從安全性上還不如這個放在必須調用的加密庫裏面,我當時寫的直接不去調用就能夠繞過。

作這個嘗試的時候好幾回徹底看不懂想放棄,想着直接用笨方法也能實現需求就算了。

但總想看看,如何能完全把本身之前寫過的垃圾代碼幹掉,就一點點的查和改。

後面能夠經過這個去學習別的應用更好的簽名校驗作法。以前遇到過一個有意思的設計,簽名校驗成功以後去初始化一個靜態的單例,而後在其它地方直接調用這個單例的方法。若是簽名校驗失敗,這裏的調用只會拋出空指針錯誤致使應用 crash,一開始不會聯想到是由於重簽名致使的應用錯誤。。。

固然一看 traces 就找到了問題,也可能只是設計的時候沒考慮到這裏會致使空指針,畢竟沒什麼人會無聊到閒着沒事去重簽名別人 apk。

相關文章
相關標籤/搜索