開(kāi)發(fā)軟件的人都知道這個(gè)世界上沒(méi)有破解不了的軟件,只有不值得破解的軟件。換而言之,只有軟件的破解成本超過(guò)Hacker收益,軟件資產(chǎn)才是相對(duì)安全的。Android平臺(tái)以其免費(fèi)和開(kāi)源的特性占據(jù)了移動(dòng)應(yīng)用領(lǐng)域半壁江山,但也因其應(yīng)用很容易被逆向破解獲取源碼,導(dǎo)致它成為Hacker最喜歡攻擊的一個(gè)“靶子”。
那么如何才能保護(hù)自己開(kāi)發(fā)APP不被逆向破解呢?在道高一尺魔高一丈的網(wǎng)絡(luò)安全攻防對(duì)抗中,防逆向保護(hù)技術(shù)也在不停更新演進(jìn),筆者在這里梳理了幾個(gè)關(guān)鍵時(shí)期的防逆向保護(hù)技術(shù),讓大家對(duì)APP防護(hù)有一個(gè)更好理解。
啟蒙階段——防逆向保護(hù)始于代碼混淆技術(shù)
這個(gè)時(shí)期最大特點(diǎn)是,從未能登上大雅之堂的代碼混淆技術(shù),搖身一變成為了防逆向保護(hù)唯一有效的技術(shù)。這要從1995年JAVA語(yǔ)言橫空出世說(shuō)起,它讓人們?cè)谙硎芸缙脚_(tái)便利運(yùn)行的同時(shí),由于其天生易反編譯特性,也讓傳統(tǒng)針對(duì)機(jī)器碼的安全保護(hù)一夜之間變得毫無(wú)用處。
從此,那個(gè)曾經(jīng)被唾棄的代碼混淆技術(shù)開(kāi)始逐漸被人所重視。從Android 2.3開(kāi)始,Google在SDK中加入了一款叫ProGuard代碼混淆工具,通過(guò)它可混淆JAVA代碼。
ProGuard混淆后DEX文件截圖
從上圖就可以看到,代碼混淆之后左側(cè)的類(lèi)名大多都變成了a、b等自定義字母,雖然機(jī)器執(zhí)行起來(lái)的邏輯是一樣的,但增加了黑客人為分析的難度和時(shí)間成本。從某種程度上來(lái)說(shuō),代碼混淆技術(shù)很好的保護(hù)JAVA源代碼,但這種方式也只是簡(jiǎn)單的改變類(lèi)名或者變量名,黑客只要找到DEX文件,反編譯也就是時(shí)間問(wèn)題了,就看時(shí)間成本是否超過(guò)黑客收益。
發(fā)展階段——DEX加密技術(shù)成為應(yīng)用防護(hù)中流砥柱
隨著Android反編譯技術(shù)越來(lái)越純熟,即便代碼混淆技術(shù)做到native層,也是治標(biāo)不治本。為了解決代碼混淆技術(shù)存在弊端,越來(lái)越多的人采用DEX整體隱藏和DEX函數(shù)抽取加密來(lái)保護(hù)自己代碼安全,例如梆梆安全等廠商早期加固產(chǎn)品用的就是這個(gè)技術(shù)。
1. DEX文件整體加密
對(duì)DEX文件進(jìn)行整體加密,與殼APK進(jìn)行合并得到新的DEX文件,然后替換殼程序中的DEX文件即可得到新的APK。新APK運(yùn)行時(shí)將加密后DEX 文件在內(nèi)存中解密,并讓 Dalvik虛擬機(jī)動(dòng)態(tài)加載執(zhí)行。
DEX文件整體加密能夠?qū)轨o態(tài)分析,但也存在一定缺陷。該技術(shù)對(duì)DEX文件進(jìn)行整體加密、解密操作,運(yùn)行時(shí)在內(nèi)存中存在連續(xù)完整的代碼。通過(guò)修改Dalvik虛擬機(jī)就有可能通過(guò)內(nèi)存Dump的方式獲得解密后的代碼。雖然開(kāi)發(fā)者可以采取一些 patch 的方法來(lái)增加破解難度,例如類(lèi)加載結(jié)束后,抹掉或者混淆內(nèi)存中 DEX 文件的頭部或尾部信息,但這些方法也無(wú)法從根本上解決內(nèi)存 Dump 的問(wèn)題。
2. DEX函數(shù)抽取加密
為解決DEX文件整體加密可以被內(nèi)存 Dump這個(gè)弱點(diǎn),DEX函數(shù)抽取加密技術(shù)對(duì)代碼中每個(gè)方法抽取進(jìn)行單獨(dú)加密。JAVA 虛擬機(jī)在第一次執(zhí)行某個(gè)方法前,才開(kāi)始加載這個(gè)方法的代碼。利用這個(gè)機(jī)制將解密操作延遲到某個(gè)方法在執(zhí)行之前才對(duì)該方法進(jìn)行解密,并且解密后代碼在內(nèi)存中是不連續(xù)存放。例如通過(guò)抽取Dalvik虛擬機(jī)運(yùn)行一個(gè)DEX必不可缺少DEXCode中的部分,然后對(duì)字節(jié)碼指令添加nop,這種方式大大增加代碼安全性。
加密前后DEX 文件中的代碼對(duì)比
這種加固技術(shù)的主要優(yōu)點(diǎn)在于:
加密粒度變小,加密粒度從DEX 文件級(jí)別變?yōu)榉椒?jí)別;
按需解密,解密操作延遲到某個(gè)方法在確實(shí)要執(zhí)行之前才觸發(fā),如果方法不被執(zhí)行,則不被解密;
內(nèi)存不連續(xù),避免了內(nèi)存 Dump的問(wèn)題,極大提高安全性。
巔峰階段——VMP加固成為防逆向保護(hù)“終極大招”
DEX函數(shù)抽取加密解決了內(nèi)存被Dump問(wèn)題,但是本質(zhì)上這也是一種代碼隱藏技術(shù),最終代碼還是通過(guò)Dalvik或者ART 虛擬機(jī)進(jìn)行執(zhí)行。因此,破解者可以構(gòu)建一個(gè)自己修改過(guò)的虛擬機(jī)來(lái)脫殼。這就需要尋求更加強(qiáng)大、安全的防逆向技術(shù)來(lái)保證 APK 的安全。虛擬機(jī)軟件保護(hù)技術(shù)(VMP)成為了當(dāng)下最前沿移動(dòng)應(yīng)用安全加固技術(shù)。
VMP首先會(huì)對(duì)被保護(hù)的目標(biāo)程序核心代碼進(jìn)行“編譯”,將由編譯器生成的本機(jī)代碼(Native code)轉(zhuǎn)換成效果等價(jià)的byte-code,然后將控制權(quán)交虛擬機(jī),由虛擬機(jī)來(lái)執(zhí)行控制。VMP最關(guān)鍵技術(shù)是需要自定義一套虛擬機(jī)指令和與之對(duì)應(yīng)解釋器,然后將標(biāo)準(zhǔn)指令轉(zhuǎn)換成自己指令,由自定義解釋器解釋執(zhí)行指令。
這樣即使破解者拿到自定義的字節(jié)碼也毫無(wú)意義,除非能夠逆向破解自定義的虛擬機(jī)解釋引擎。除此之外,VMP 還可以構(gòu)建多個(gè)不同虛擬化解釋引擎,不同的JAVA方法采用不同的虛擬化執(zhí)行引擎,這就進(jìn)一步提高了應(yīng)用的安全性。
雖然現(xiàn)在市場(chǎng)上有相當(dāng)一部分廠商都發(fā)布了針對(duì)移動(dòng)應(yīng)用VMP保護(hù)方案,但其實(shí)有很多廠商采用都是代碼混淆或者代碼隱藏技術(shù)。筆者認(rèn)為擁有一套高質(zhì)量的自定義指令集和解釋器是判斷VMP技術(shù)真?zhèn)挝ㄒ粯?biāo)準(zhǔn)。而了解,目前在國(guó)內(nèi)安全廠商中只有梆梆安全等公司在VMP技術(shù)上發(fā)展相對(duì)成熟。
寫(xiě)在最后:
任何安全技術(shù)變遷都是一部歷史,移動(dòng)應(yīng)用安全發(fā)展也是如此。從某種程度上來(lái)看,Android應(yīng)用防逆向技術(shù)演化史基本等于移動(dòng)應(yīng)用安全進(jìn)化史。例如國(guó)內(nèi)首個(gè)提出“應(yīng)用加固”概念的梆梆安全,其加固技術(shù)也是從早期代碼混淆技術(shù)演化到當(dāng)前最先進(jìn)虛擬機(jī)保護(hù)技術(shù)。
安全的攻與防是一個(gè)永恒話題,也是一個(gè)動(dòng)態(tài)螺旋式發(fā)展過(guò)程,開(kāi)發(fā)者需要不斷提高自己安全意識(shí)和安全技能,才能更好應(yīng)對(duì)各種層出不窮安全問(wèn)題。