背景
字符串加密是一個(gè)非常傳統(tǒng)的代碼保護(hù)方案,在Android的逆向過程中會(huì)涉及到Java代碼和CC++代碼,通常在對(duì)APP做逆向過程中第一步一般就是反編譯后查看代碼中是否有包含一些可以作為突破口分析的字符串信息。
作為開發(fā)者一般應(yīng)用中的字符串信息都是保存相對(duì)敏感的信息,字符串一般信息會(huì)保存著如客戶端和服務(wù)端通信信息,操作文件相關(guān)信息。
(so部分的字符串加密)
(java部分的字符串加密)
由于字符串信息中存儲(chǔ)著很多關(guān)鍵的信息,因此在做逆向的過程中從字符串入手可以猜測(cè)、分析定位出一些關(guān)鍵的加解密算法、關(guān)鍵的邏輯結(jié)構(gòu)。因此字符串也是一種提高被靜態(tài)逆向分析的一個(gè)很重要的門檻。
字符串信息的加密的影響只到靜態(tài)的逆向分析這一步,字符串信息信息在實(shí)際業(yè)務(wù)運(yùn)行過程中必然需要進(jìn)行對(duì)字符串的操作,那這個(gè)就涉及到了對(duì)加密字符串的解密過程。這個(gè)運(yùn)行態(tài)也就是在對(duì)app進(jìn)行利用動(dòng)態(tài)調(diào)試分析過程中都是赤裸裸的展現(xiàn)出來。這是時(shí)候字符串的加密就顯得蒼白無力了。因此可以通過反調(diào)試和字符串加密這兩者的入門的動(dòng)態(tài)和靜態(tài)方式結(jié)合,稍微提高代碼的安全性。
字符串加密算法基礎(chǔ)
所謂字符串加密技術(shù)是指將一個(gè)信息(或稱明文)經(jīng)過加密鑰匙及加密函數(shù)轉(zhuǎn)換,變成無意義的密文,而接收方則將此密文經(jīng)過解密函數(shù)、解密鑰匙還原成原字符串。
字符串加密免不了采用加解密的算法,加解密算法的加解密方式和加解密強(qiáng)度直接決定了被攻破的時(shí)間成本。
字符串加密算法有簡(jiǎn)單的異或方式;通用的AES、DES、RSA、Base64、MD5散列函數(shù)等等;相對(duì)有難度的自實(shí)現(xiàn)加解密算法、冷門的加解密算法。
不過一般情況下,作為開發(fā)者一般不太可能自己去造輪子寫加解密算法,一般都是直接就套用網(wǎng)絡(luò)上穩(wěn)定的、標(biāo)準(zhǔn)的加解密算法。其實(shí)如果從相對(duì)安全性來說,可以找那些冷門的加解密算法用于保護(hù)字符串。這樣相對(duì)網(wǎng)絡(luò)公開資料比較少,并且分析的人相對(duì)比較少,分析起來時(shí)間成本就相對(duì)比較高。
下面就分析下so文件加密用的比較多的字符串加密是怎么實(shí)現(xiàn)的。
ollvm字符串加密原理
Ollvm中字符串加密的公開版本有很多個(gè)版本,并且每個(gè)版本功能實(shí)現(xiàn)雖然大同小異,但是各個(gè)版本也各有缺點(diǎn)。
這些缺點(diǎn)有:
1.無法加密字符串?dāng)?shù)組;
2.無法加密unicode編碼和非const的字符串?dāng)?shù)組;
3.無法加密全局char和wchar字符串常量和結(jié)構(gòu)體變量。
基于以上原因,實(shí)現(xiàn)自己定制修改字符串加密功能代碼就顯得很重要了。
下面就分析下ollvm中基于某版本字符串加密的實(shí)現(xiàn)和調(diào)用
Ollvm項(xiàng)目中,字符串加密實(shí)現(xiàn)主要功能在項(xiàng)目存儲(chǔ)在如下的路徑中
聲明和實(shí)現(xiàn)的代碼
ollvmincludellvmTransformsObfuscationStringObfuscation.h
ollvmlibTransformsObfuscationStringObfuscation.cpp
初始化隨機(jī)數(shù)因子和調(diào)用字符串加密
ollvmlibTransformsIPOPassManagerBuilder.cpp
添加編譯StringObfuscation.cpp文件
ollvmlibTransformsObfuscationCMakeLists.txt
CMakeLists.txt配置要編譯的StringObfuscation.cpp文件
下面的聲明的靜態(tài)全局變量,主要是為了實(shí)現(xiàn)編譯時(shí)候識(shí)別 -mllvm -sobf指令的標(biāo)識(shí),全局開關(guān)通過參數(shù)來判斷是否要開啟字符串加密。
隨機(jī)數(shù)因子的初始化。
在populateModulePassManager 函數(shù)中,新增掛載新的pass代碼,這樣就可以根據(jù)全局開關(guān)來判斷是否啟用當(dāng)前pass。
StringObfuscation.h文件分析
這個(gè)函數(shù)就聲明了createStringObfuscation函數(shù),看起來非常簡(jiǎn)單,這個(gè)函數(shù)也就是這個(gè)字符串加密的關(guān)鍵函數(shù)。
StringObfuscation.cpp文件分析(基于Armariris版本的字符串加密)
這個(gè)版本的加密效果:可加密所有類型的ANSI, UNICODE字符串常量, 但是無法加密字符串?dāng)?shù)組, 因?yàn)樽址當(dāng)?shù)組的全局符號(hào)名不是.str開頭。
這個(gè)文件中主要有字符串加密函數(shù)和字符串解密函數(shù)2個(gè)函數(shù)組成的。
上文截圖代碼根據(jù).str和.str.名稱判斷是否為字符串,并且過濾掉特定區(qū)段:Llvm.metadata,__objec_methname不進(jìn)行字符串加密。
上面截圖中的代碼,可以看到字符串加密的就是進(jìn)行簡(jiǎn)單的字符串異或加密。
用于往字符串加密的程序插入以“.datadiv_decode+隨機(jī)數(shù)”為結(jié)構(gòu)的加密函數(shù),用于實(shí)現(xiàn)對(duì)字符串進(jìn)行加密處理。
防止破解者能夠快速識(shí)別是基于ollvm實(shí)現(xiàn)的字符串加密,可以重點(diǎn)修改下這個(gè)函數(shù)的實(shí)現(xiàn)和“.datadiv_decode+隨機(jī)數(shù)”的特征。
有了以上的關(guān)鍵調(diào)用和流程,那么就可以基于以上的流程和規(guī)則進(jìn)行做字符串加密功能的定制實(shí)現(xiàn)了,可以通過添加一些邏輯代碼加強(qiáng)字符串加密的強(qiáng)度。
ollvm字符串加密后表現(xiàn)
1.直接用標(biāo)準(zhǔn)的ollvm的字符串加密,在字符串信息和導(dǎo)出函數(shù)中和init_arrayq區(qū)段會(huì)存在.datadiv_decode,這種采用的是一個(gè)字節(jié)和一個(gè)字節(jié)進(jìn)行隨機(jī)異或的加密方式。
數(shù)據(jù)都存儲(chǔ)在數(shù)據(jù)段中,程序運(yùn)行前就是初始化的時(shí)候就將加密的字符串全部解密出來,等待著使用。
2.通過基于ollvm的源代碼,簡(jiǎn)單修改定制olllvm的源碼,將解密函數(shù)名字修改成為非標(biāo)準(zhǔn)的,但是這種的字符串加密在init_array區(qū)段中依然會(huì)有展示,只不過展示的是非標(biāo)準(zhǔn)的函數(shù)信息。這種加密也是通過疑惑的方式進(jìn)行加密。
字符串?dāng)?shù)據(jù)都存儲(chǔ)在數(shù)據(jù)段中,程序運(yùn)行起來后就是初始化時(shí)候,就一次性全部將字符串解密。
3.通過基于ollvm的源代碼進(jìn)行定制,字符串信息都存儲(chǔ)在.bss區(qū)段中,程序運(yùn)行初始化的時(shí)候并沒有進(jìn)行做解密,只有在程序運(yùn)行使用到那里才會(huì)解密到那里。其它的沒使用的字符串是沒有進(jìn)行解密的。
小結(jié)
從字符串成為破解者第一道門檻的的痛點(diǎn),在到字符串加密僅是為了提高破解者靜態(tài)分析的成本的大背景下進(jìn)行,全文大篇幅的主要是以ollvm這個(gè)項(xiàng)目中的字符串加密為主線進(jìn)行展開的,展開的方向主要以加密的實(shí)現(xiàn)原理和加密后的表現(xiàn)形式。
對(duì)ollvm字符串的解密相信是對(duì)大家來說比字符串加密是更感興趣,篇幅有限先以字符串加密進(jìn)行簡(jiǎn)單做下原理性的分析,后面再分享ollvm字符串解密。
審核編輯:湯梓紅
-
Android
+關(guān)注
關(guān)注
12文章
3903瀏覽量
126615 -
JAVA
+關(guān)注
關(guān)注
19文章
2943瀏覽量
104096 -
字符串
+關(guān)注
關(guān)注
1文章
566瀏覽量
20384
原文標(biāo)題:ollvm|Android字符串加密淺析
文章出處:【微信號(hào):哆啦安全,微信公眾號(hào):哆啦安全】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論