本發(fā)明涉及移動終端應(yīng)用安全領(lǐng)域,具體涉及基于內(nèi)存加載的dalvik字節(jié)碼優(yōu)化方法。
背景技術(shù):
據(jù)最新智能終端銷量統(tǒng)計,中國的Android系統(tǒng)目前已占據(jù)移動端73%以上的市場份額,各種Android應(yīng)用程序也在成級數(shù)式增長且涉及的業(yè)務(wù)越來越廣,涵蓋娛樂、支付、生活等各個領(lǐng)域。由于android平臺軟件使用的語言是JAVA,而JAVA源代碼編譯后的二進制代碼極易被反編譯,導(dǎo)致android應(yīng)用程序易被黑客通過二次打包、篡改、惡意注入等手段進行惡意破壞。因此應(yīng)用安全問題已經(jīng)成為開發(fā)者/發(fā)布者/使用者關(guān)注的熱點。
目前市場上比較主流的應(yīng)用軟件加固措施可分為加殼和脫殼兩個過程。其中,加殼技術(shù)主要是通過用一個新的classes.dex文件替換掉APP中的核心代碼文件,將原dex文件通過加密技術(shù)處理,生成加密文件另行存儲,最后修改應(yīng)用配置文件,并加入對應(yīng)解密算法庫,形成加固后的APP安裝包。加殼后APK中的dex文件便是殼dex。該方法可防止破解者還原真實代碼邏輯。
脫殼技術(shù)則是指程序在運行過程中將原APK的dex文件解密出來并加載到內(nèi)存中,讓該APK正常運行起來。APK的脫殼過程需要利用殼dex來完成?,F(xiàn)有的脫殼方法多是通過Android API提供的DexClassLoader類加載原dex文件中的核心代碼,并通過反射將Android默認(rèn)的類加載器android.app.ActivityThread中的mClassLoader置換為為DexClassLoader,這樣既保證加載了源程序又沒有放棄原先加載的資源與系統(tǒng)代碼。這種做法中解密之后的dex會端在存放在/data/data/包名/cache目錄下,然后再用DexClassLoader加載dex,運行程序。這種做法雖然可行但仍舊存在一些問題。首先,解密之后的dex文件需要存放在特定目錄下,增大了被破解的風(fēng)險。其次,先解密得到源程序的dex,然后再用DexClassLoader進行加載,相當(dāng)于在解密時和加載原dex時兩次把dex加載到內(nèi)存中,大大降低了程序的啟動效率。
技術(shù)實現(xiàn)要素:
本發(fā)明克服了現(xiàn)有技術(shù)的不足,提供一種基于內(nèi)存加載的dalvik字節(jié)碼優(yōu)化方法。
為解決上述的技術(shù)問題,本發(fā)明采用以下技術(shù)方案:
一種基于內(nèi)存加載的dalvik字節(jié)碼優(yōu)化方法,它包括以下步驟:
步驟1,讀取加密的DEX文件進行解密解壓,并將解密解壓后的DEX文件以字節(jié)碼的形式保存到棧內(nèi)存中;
步驟2,采用反射調(diào)用DexFile的openDexFile方法,解析步驟1中的DEX文件字節(jié)碼得到一個DexOrJar結(jié)構(gòu)體,將DexOrJar結(jié)構(gòu)體的內(nèi)容加載到gDvm中的userDexFile結(jié)構(gòu)的hash表中,最后返回存儲DEX文件信息的DexOrJar結(jié)構(gòu)體指針,記為cookie值;
步驟3,定義本地方法loadDex,傳遞DEX文件的字節(jié)數(shù)組和字節(jié)大小;
步驟4,重寫類加載器加載指定的類。
更進一步的技術(shù)方案是,所述步驟1中是在java層調(diào)用本地方法對DEX文件進行解密解壓。
更進一步的技術(shù)方案是,所述步驟2具體包括:
步驟2.1,采用dlopen函數(shù)打開動態(tài)鏈接庫libdvm.so,返回一個句柄和符號;
步驟2.2,采用dlsym函數(shù)根據(jù)步驟2.1中返回的句柄和符號,拿到動態(tài)鏈接庫libdvm.so中內(nèi)存加載DEX文件;
步驟2.3,調(diào)用native方法,得到并保存返回的cookie值。
更進一步的技術(shù)方案是,所述步驟2.2得到的native方法位于源碼:
dalvik/vm/native/dalvik_system_DexFile.cpp類中,方法名稱是Dalvik_dalvik_system_DexFile_openDexFile_bytearray。
更進一步的技術(shù)方案是,所述步驟3還包括定義一個Common.h類,所述Common.h類用于定義本地方法中用到的各個變量類型。
更進一步的技術(shù)方案是,所述步驟4采用重寫類加載器的findClass方法,具體包括:
步驟4.1,采用反射調(diào)用DexFile的getClassNameList方法,傳遞步驟2中的cookie值得到DEX文件中的所有類;
步驟4.2,采用反射調(diào)用defineClass方法獲取Class對象。
更進一步的技術(shù)方案是,所述步驟4中直接調(diào)用父類加載器的loadClass方法返回一個Class對象。
本技術(shù)方案在native層對加密壓縮的DEX文件進行解密解壓縮,并重寫了內(nèi)存直接加載DEX文件的字節(jié)碼的方法,在該方法中對解密的DEX文件字節(jié)碼進行解析,從而得到存儲DEX文件信息的DexOrJar結(jié)構(gòu)體指針,并將解析后的DexOrJar類型對象的指針添加到gDvm.userDexFiles的HashTable中,直接加載到系統(tǒng)gDvm中。本發(fā)明對加密DEX文件信息的解密,傳輸,保存,加載等過程都是以字節(jié)碼的形式在內(nèi)存中進行的,繞過了dexopt的過程并且避免了新建DexClassLoader的耗時操作,在極大程度的提高DEX文件加載安全性的同時提高了應(yīng)用啟動速度。
與現(xiàn)有技術(shù)相比,本發(fā)明的有益效果是:
1,本發(fā)明在讀取加密壓縮DEX文件后,便一直在內(nèi)存中利用字節(jié)碼的形式進行DEX文件的解密解壓、存儲和加載,極大程度的保護了DEX文件,提高了加固后APK的抗攻擊性。
2,本發(fā)明利用反射重寫了底層加載DEX文件字節(jié)碼的方法,繞過了dalvik系統(tǒng)加載時dexopt的過程并且避免了一次新建DexClassLoader的耗時操作,使得該方法可以提升應(yīng)用的啟動效率。
附圖說明
圖1為本發(fā)明一種實施例基于內(nèi)存加載的dalvik字節(jié)碼優(yōu)化方法的流程圖。
圖2為本發(fā)明一種實施例基于內(nèi)存加載的dalvik字節(jié)碼優(yōu)化方法中DEX文件在內(nèi)存中的傳輸流程。
具體實施方式
下面結(jié)合附圖對本發(fā)明作進一步闡述。
基于內(nèi)存加載的dalvik字節(jié)碼優(yōu)化方法,它包括以下步驟:
步驟1,讀取加密的DEX文件進行解密解壓后,并將解密解壓后的DEX文件以字節(jié)碼的形式保存到棧內(nèi)存中;
步驟1中是在java層調(diào)用本地方法對DEX文件進行解密解壓。
步驟2,采用反射調(diào)用DexFile的openDexFile方法,解析步驟1中的DEX文件字節(jié)碼得到一個DexOrJar結(jié)構(gòu)體,將DexOrJar結(jié)構(gòu)體的內(nèi)容加載到gDvm中的userDexFile結(jié)構(gòu)的hash表中,最后返回存儲DEX文件信息的DexOrJar結(jié)構(gòu)體指針,記為cookie值;
步驟2中得到的cookie值就是對應(yīng)加載dex的值,后續(xù)可使用這個cookie值訪問這個DEX文件附屬的所有對象,步驟2中DexFile包含兩個openDexFile方法,一個參數(shù)變量為文件路徑,一個為文件字節(jié)碼,同時這兩個方法都是native層函數(shù),作用是解析dex文件。本發(fā)明調(diào)用的是參數(shù)為字節(jié)碼的openDexFile方法。達(dá)到了在native層利用字節(jié)碼的形式對dex文件進行傳輸加載的目的,有效的提高了加載過程的安全性;
步驟2中調(diào)用的opneDexFIle方法所對應(yīng)的native方法并沒有被虛擬機導(dǎo)出,所以需要利用反射獲得該native方法,具體步驟如下:
步驟2.1,采用dlopen函數(shù)打開動態(tài)鏈接庫libdvm.so,返回一個句柄和符號;
步驟2.2,采用dlsym函數(shù)根據(jù)步驟2.1中返回的句柄和符號,拿到動態(tài)鏈接庫libdvm.so中內(nèi)存加載DEX文件;步驟2.2得到的native方法位于源碼:
dalvik/vm/native/dalvik_system_DexFile.cpp類中,方法名稱是Dalvik_dalvik_system_DexFile_openDexFile_bytearray
步驟2.3,調(diào)用native方法,得到并保存返回的cookie值。
步驟3,定義本地方法loadDex,傳遞DEX文件的字節(jié)數(shù)組和字節(jié)大??;
步驟3還包括定義一個Common.h類,所述Common.h類用于定義本地方法中用到的各個變量類型。
步驟4,重寫類加載器加載指定的類;所述步驟4采用重寫類加載器的findClass方法,具體包括:
步驟4.1,采用反射調(diào)用DexFile的getClassNameList方法,傳遞步驟2中的cookie值得到DEX文件中的所有類;
步驟4.2,采用反射調(diào)用defineClass方法獲取Class對象。
調(diào)用類加載器的loadClass方法,加載指定的類。
根據(jù)本發(fā)明的一個實施例,步驟1中對DEX文件解密解壓縮方式為任意已知的解密方式。
以上具體實施方式對本發(fā)明的實質(zhì)進行詳細(xì)說明,但并不能對本發(fā)明的保護范圍進行限制,顯而易見地,在本發(fā)明的啟示下,本技術(shù)領(lǐng)域普通技術(shù)人員還可以進行許多改進和修飾,需要注意的是,這些改進和修飾都落在本發(fā)明的權(quán)利要求保護范圍之內(nèi)。