Android相比iOS,安全問題往往比較突出,各種漏洞和破解層出不窮。對破解方法的了解,能在開發中進行預防,加強應用的安全性。本系列文章會對Android應用的破解和保護兩方面做個探討,給開發的同學一些借鑒。Andoid開發的同學可能會遇到需要做競品分析的情況,APK加固常常會成為分析的障礙。360渠道做為Android應用分發的最大渠道,很多apk都使用了360加固。本文就來聊聊如何過掉這個坑。360加固後的apk,在arm設備上首先會將assets目錄下的libjiagu.so拷貝到files目錄下,然後通過libjiagu.so動態解密並加載原始dex

要對apk脫殼,首先要分析libjiagu.so實現。而該so做了二進制加殼。那麼現在首先要做的事就是先把so的殼給脫了。通過010Editor查看libjiagu.so結構可知,其init_proc和init_array都無實質功能,真正的解密放在JNI_OnLoad裡面。

JNI_OnLoad函數裡有非常多的垃圾跳轉指令干擾分析,後面還會有動態解密的函數運行,如果檢測到調試器,會把動態函數置成非法代碼,使程序CRASH

1b0c404這個位置就會跑飛。這樣分析比較累人。換個思路,對一些關鍵函數進行hook,進行hook log分析Hook dlopen和dlsym LOG打印出libjiagu.so的加載基址和大小
可以看到JNI_OnLoad的地址還是在libjiasu.so內存范圍內的
Hook RegisterNatives函數,打印如下LOG

這個LOG可以看到RegisterNatives有被調用,注冊了一個interface7函數,函數地址是51e2f211,仔細看這個地址發現,這個地址已經是thumb指令集了,跟libjiagu.so使用的arm指令集不太相符,而且可以看到函數地址已經超出了libjiagu.so內存范圍了.libjiagu.so的基址是51b3b000,大小是46000,最大內存地址是51B81000那麼,基本可以確定,它在內存中加載了另一個so從/proc/%pid%/maps裡找到函數地址所在的內存塊,把周圍連續的內存一起dump出來在這片內存裡找到如下一塊內存

這其實就是elf heaer了,不過一些elf結構信息已經被抹掉了。除了基本的結構信息還缺失如下三個數據:0x20 e_shoff0x30 e_shnum0x32 e_shtrndx接下來的工作就是對這個殘缺的內存進行修復了,通過分析上面三個數據,dlopen其實都沒有用到,其值對elf運行沒有影響。經過修復後的文件可以替換掉原來的libjiagu.so,重新簽名後使apk正常運行,用於IDA動態調試分析。下面是經過修復後的libjiagu.so用ida分析的流程圖片段

360在dex加載的時候,並沒有調用dvmDexFileOpenPartial,而是自實現了此函數的功能,因此直接在這個函數上下斷點是不能脫殼的。它的實現方式基本是照抄了bionic源碼

如上面源碼所示,使用dex所在內存的時候都會使用memcmp校驗MAGIC是否為dex,所以只要hook memcmp,然後在過濾函數裡校驗是否為dex,然後dump出來即是原始的dex。把hook框架搭好,實現如下的memcmp過濾函數,就可自動將原始dex dump下來。

前面的都搞定後,整個脫殼過程就可以自動化了。APK啟動瞬間即會自動脫殼。點擊啟動APK,會輸出如下LOG
LOG裡的第3個dmp即為原始dex,已經自動寫入到指定目錄。
該脫殼器可應用於目前所有360加固,只需指定APK包名即可在啟動時秒脫