修改了應用的內容以後,搜索 smali 沒發現有作應用的簽名校驗,但重打包以後應用打開直接出現閃退。查看日誌,肯定是 jni 方法作了簽名校驗。java
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 看代碼。安全
因爲第一次下載 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
或版本號。
定位到問題,接下來就要解決怎麼改了。
做爲只能看得懂一點點 smali 的菜雞,對於 IDA 裏面顯示的內容沒有一處能看得懂。
找到了對應的方法位置,要是 smali 代碼,真的是隨便就改掉了。這個第一次搞,徹底無從下手。
迫於人菜癮還大,不會改if(!checkSignature())
,也不會直接改return 65542
,最終決定從checkSignature
方法的返回值下手,讓他不管如何都return true
就行了。依靠Copy to assembly
,把反編譯後的代碼放到天書裏面,至少讓我看到了哪是哪。
能夠看到這裏調用了strcmp
方法,比較 s1 與 s2 ,直接把這裏改爲 s1 比較 s1 就行了。
想法是美好的,改這個參數花了很久,最後用key-patch
實現了,直接改這裏的調用
修改後從新看反編譯的代碼,實現了繞過簽名校驗的功能。
64和32位的庫都對應修改好以後,從新打包簽名,運行正常。
比較笨方法直接改存儲的簽名信息,後面更多的是嘗試修改 lib 庫的代碼。
理代碼邏輯,修改內容可比繞過簽名校驗自己有意思多了,後面仍是要多學習。
我本身寫的第一個 jni 的代碼,就是從網上扒來的簽名校驗,實現幾乎和這個如出一轍,在Application:onCreate
中調用 JNI 方法,而後方法內和寫死的簽名比較,錯誤的話直接killProcess
。從安全性上還不如這個放在必須調用的加密庫裏面,我當時寫的直接不去調用就能夠繞過。
作這個嘗試的時候好幾回徹底看不懂想放棄,想着直接用笨方法也能實現需求就算了。
但總想看看,如何能完全把本身之前寫過的垃圾代碼幹掉,就一點點的查和改。
後面能夠經過這個去學習別的應用更好的簽名校驗作法。以前遇到過一個有意思的設計,簽名校驗成功以後去初始化一個靜態的單例,而後在其它地方直接調用這個單例的方法。若是簽名校驗失敗,這裏的調用只會拋出空指針錯誤致使應用 crash,一開始不會聯想到是由於重簽名致使的應用錯誤。。。
固然一看 traces 就找到了問題,也可能只是設計的時候沒考慮到這裏會致使空指針,畢竟沒什麼人會無聊到閒着沒事去重簽名別人 apk。