原理分析見《利用動(dòng)態(tài)加載技術(shù)加固APK原理解析》
源代碼地址:https://github.com/mars-ma/ApkSecure/
bin目錄下是直接可用的工具康嘉,注意readme.txt的說明门扇,需要配置好java運(yùn)行環(huán)境。
config.xml注意這里需要安裝WinRAR對APK壓縮帮掉,需要給出安裝好的WinRAR的路徑寺渗。簽名和密碼的配置也在這里丽惭。
dex/apksecure下是殼dex的源碼
java_tool/ApkSecure下是java工具類的源碼
加固技術(shù)實(shí)現(xiàn)(基礎(chǔ))
Java加殼工具的實(shí)現(xiàn)
實(shí)現(xiàn)Java加殼程序需要?dú)lasses.dex,以及相關(guān)so庫岗仑。Java加固工具的工作流程如下:
反編譯原APK定欧,將AndroidManifest.xml中的Application Name改為殼中的Application Name。
在<application>標(biāo)簽下增加<meta-data>怒竿,存入原Application Name砍鸠,以便在解殼后恢復(fù)原始Application。
將反編譯的APK再次編譯得到新的Apk耕驰。
將新的Apk解壓爷辱,將原Classes.dex(可能是多個(gè))拷貝到assets下,并用加密算法加密為新的文件朦肘,再用zip壓縮托嚣。
用殼classes.dex替換新APK中的classes.dex。
將解壓的新的Apk用壓縮工具壓縮成zip厚骗,更改后綴名為.apk,用jarsigner簽名兢哭。
殼DEX的實(shí)現(xiàn)
殼dex負(fù)責(zé)逆向解密出dex领舰,上述加固思路已經(jīng)詳細(xì)說明,通過構(gòu)造DexClassLoader迟螺,并用反射技術(shù)替換調(diào)默認(rèn)的ClassLoader冲秽。執(zhí)行流程如下:
將assets下加密的.dex文件拷貝至自己的數(shù)據(jù)目錄,先用java.util.zip解壓文件并用解密算法解密出原.dex文件矩父。
以解密出的原.dex為路徑锉桑,構(gòu)造DexClassLoader,并用反射技術(shù)替換調(diào)默認(rèn)的PathClassLoader窍株。
將ActivityThread中ApplicantsInfo的Class Name替換為存在下中的應(yīng)用名民轴,并用新的ClassLoader加載原Application替換調(diào)現(xiàn)有Application,最后執(zhí)行原Application對象的onCreate函數(shù)球订。
最初版本遇到的問題:
殼dex中不能包含和原dex相同的全限定類名
java.util.zip壓縮的apk無法被系統(tǒng)識(shí)別資源,后續(xù)使用了zip4j可以正常工作后裸。
JNI反射內(nèi)部類的簽名格式是"a/b/C$D"
壓縮后apk明顯大于原始apk,因?yàn)樵黾恿私饷苡玫膕o文件冒滩。
Android4.4及以下使用HashMap類微驶,以上使用ArrayMap類,反射時(shí)要適配不同的API版本开睡。
2017.5.19?
支持multidex因苹,但是未做ART虛擬機(jī)下DexClassLoader加載.dex時(shí)跳過編譯.oat的優(yōu)化,對于使用ART虛擬機(jī),且體積較大的dex存在加載緩慢的問題篇恒。
待優(yōu)化:
繞過ART虛擬機(jī)編譯OAT文件
防止so的動(dòng)態(tài)調(diào)試
防止dump dex