Obfuscator-LLVM在iOS中的實(shí)踐

原文鏈接:http://fighting300.com....

OLLVM簡介

OLLVM(Obfuscator-LLVM)是瑞士西北應(yīng)用科技大學(xué)安全實(shí)驗(yàn)室于2010年6月份發(fā)起的一個(gè)項(xiàng)目,該項(xiàng)目旨在提供一套開源的針對(duì)LLVM的代碼混淆工具庭敦,以增加對(duì)逆向工程的難度唧取。后期轉(zhuǎn)向商業(yè)項(xiàng)目strong.protect平酿。目前氧吐,OLLVM已經(jīng)支持LLVM-4.0版本雪情。

LLVM是一個(gè)優(yōu)秀的編譯器框架剧蚣,它也采用經(jīng)典的三段式設(shè)計(jì)趁窃。前端可以使用不同的編譯工具對(duì)代碼文件做詞法分析以形成抽象語法樹AST崇渗,然后將分析好的代碼轉(zhuǎn)換成LLVM的中間表示IR(intermediate representation)字逗;中間部分的優(yōu)化器只對(duì)中間表示IR操作,通過一系列的Pass對(duì)IR做優(yōu)化宅广;后端負(fù)責(zé)將優(yōu)化好的IR解釋成對(duì)應(yīng)平臺(tái)的機(jī)器碼葫掉。LLVM的優(yōu)點(diǎn)在于,中間表示IR代碼編寫良好跟狱,而且不同的前端語言最終都轉(zhuǎn)換成同一種的IR挖息。

LLVM IR 是LLVM的中間表示,優(yōu)化器就是對(duì)IR進(jìn)行操作的兽肤,具體的優(yōu)化操作由一些列的Pass來完成套腹,當(dāng)前端生成初級(jí)IR后,Pass會(huì)依次對(duì)IR進(jìn)行處理资铡,最終生成后端可用的IR电禀。下圖可以說明這個(gè)過程:


OLLVM的混淆操作就是在中間表示IR層,通過編寫Pass來混淆IR笤休,然后后端依據(jù)IR來生成的目標(biāo)代碼也就被混淆了尖飞。得益于LLVM的設(shè)計(jì),OLLVM適用LLVM支持的所有語言(C,C++,Objective-C,Ada,Fortran)和目標(biāo)平臺(tái)(x86,x86-64,PowerPC,PowerPC-64, ARM, Thumb, SPARC, Alpha, CellSPU, MIPS, MSP430, SystemZ, 和 XCore)

OLLVM iOS編譯環(huán)境搭建

以下店雅,介紹OLLVM iOS環(huán)境的插件創(chuàng)建過程政基。
首先下載源碼,編譯OLLVM混淆器闹啦,這里采用LLVM的版本是4.0沮明。下載編譯過程如下:

$ git clone -b llvm-4.0 https://github.com/obfuscator-llvm/obfuscator.git  
$ mkdir build  
$ cd build  
$ cmake -DCMAKE_BUILD_TYPE=Release ../obfuscator/  
$ make -j7  

下載的源碼里已經(jīng)包含了LLVM和Clang,編譯完成后窍奋,編譯好的二進(jìn)制程序都存在在build/bin目錄下荐健。

依據(jù)github上的wiki,bin目錄下編譯好的工具鏈可以直接用來編譯混淆linux下的程序琳袄,就像我們常用的gcc那樣江场。若想使用OLLVM來混淆iOS程序,還需將bin目錄下的工具鏈整合進(jìn)Xcode插件中窖逗,具體步驟如下址否。

配置Xcode--新建Obfuscator插件

$ cd /Applications/Xcode.app/Contents/PlugIns/Xcode3Core.ideplugin/Contents/SharedSupport/Developer/Library/Xcode/Plug-ins/  
$ sudo cp -r Clang\ LLVM\ 1.0.xcplugin/ Obfuscator.xcplugin  
$ cd Obfuscator.xcplugin/Contents/  
$ sudo plutil -convert xml1 Info.plist  
$ sudo vim Info.plist  

修改Info.plist中的對(duì)應(yīng)內(nèi)容:

<string>com.apple.compilers.clang</string> -> <string>com.apple.compilers.obfuscator</string>  
<string>Clang LLVM 1.0 Compiler Xcode Plug-in</string> -> <string>Obfuscator Xcode Plug-in</string>  

修改Obfuscator.xcspec文件

$ sudo plutil -convert binary1 Info.plist  
$ cd Resources/  
$ sudo mv Clang\ LLVM\ 1.0.xcspec Obfuscator.xcspec  
$ sudo vim Obfuscator.xcspec  

修改ExecPath的地址為當(dāng)前build/bin的地址(!重點(diǎn))

Identifier = "com.apple.compilers.llvm.clang.1_0"; -> Identifier = "com.apple.compilers.llvm.obfuscator.4_0";  
Name = "Apple LLVM 8.0"; -> Name = "Obfuscator 4.0";  
Description = "Apple LLVM 8.0 compiler"; -> Description = "Obfuscator 4.0";  
Vendor = Apple; -> Vendor = HEIG-VD;  
Version = "7.0"; -> Version = "4.0";  
ExecPath = "clang"; -> ExecPath = "/path/to/obfuscator_bin/clang";  

修改 Obfuscator 4.0 Strings

$ cd English.lproj/  
$ sudo mv Apple\ LLVM\ 8.0.strings "Obfuscator 4.0.strings"  
$ sudo plutil -convert xml1 Obfuscator\ 4.0.strings  
$ sudo vim Obfuscator\ 4.0.strings  
"Description" = "Apple LLVM 8.0 Compiler"; -> "Description" = "Obfuscator 4.0";  
"Name" = "Apple LLVM 8.0"; -> "Name" = "Obfuscator 4.0";  
"Vendor" = "Apple"; -> "Vendor" = "HEIG-VD";  
"Version" = "8.0"; -> "Version" = "4.0";  

sudo plutil -convert binary1 Obfuscator\ 4.0.strings

現(xiàn)在,你可以打開Xcode在項(xiàng)目配置里來選擇新的編譯器碎紊,并且可以在C Flags或C++ Flags下添加混淆標(biāo)簽佑附。

選擇編譯器

添加混淆標(biāo)簽

這樣配置完成后用含,就可以編譯項(xiàng)目生成混淆后的程序。

ollvm混淆使用

接下來使用以下demo介紹混淆功能的具體使用帮匾。

int main(){  
    int a = 1;  
    int b = 0;  
    int c = 0;  
    if(a > b){  
        a = 100;    
        b = 50;    
        c = a - b;    
        int d = a + b;    
        int e = a & b;    
        int f = a ^ b;    
        printf("c = %d\n",c);    
        printf("d = %d\n",d);    
        printf("e = %d\n",e);    
        printf("f = %d\n",f);    
        printf("a > b\n");    
    }else{  
        printf("a < b\n");    
    }  
    return 0;  
}

OLLVM默認(rèn)支持-fla -sub -bcf 三個(gè)混淆參數(shù)啄骇,這三個(gè)參數(shù)可以單獨(dú)使用,也可以配合著使用瘟斜。-fla 參數(shù)表示使用控制流平展(Control Flow Flattening)模式缸夹, -sub 參數(shù)表示使用指令替換(Instructions Substitution)模式, -bcf 參數(shù)表示使用控制流偽造(Bogus Control Flow)模式螺句。

Instructions Substitution

指令替換模式主要是將正常的運(yùn)算操作(+虽惭,-,&蛇尚,|等)替換成功能相等但表述更復(fù)雜的形式芽唇。比如,對(duì)于表達(dá)式 a = b + c取劫,它的等價(jià)式可以有 a = – ( -b – c), a = b – (-c) 或 a = -(-b) + c 等匆笤,原表達(dá)式可以替換成任意相等式,或者通過隨機(jī)數(shù)在多個(gè)相等式中做選擇谱邪。SUB模式目前只支持整數(shù)運(yùn)算操作炮捧,支持 + , – , & , | 和 ^ 操作,還是比較局限的惦银。編譯時(shí)咆课,使用 -mllvm -sub 參數(shù)即可。

-mllvm -sub: 啟用instructions substitution  
-mllvm -sub_loop=3: 對(duì)每個(gè)函數(shù)混淆3次扯俱,默認(rèn)1詞  

Control Flow Flattening

控制流平展模式可以完全改變程序原本的控制流圖书蚪。如下示例代碼是簡單的if-else分支語句,正常編譯后其控制流圖在IDA中下圖所示迅栅,是正常的if-else分支殊校,使用 -mllvm -fla參數(shù)混淆后,在IDA中顯示的控制流圖如下:



經(jīng)FLA模式混淆后库继,程序的執(zhí)行流程已經(jīng)被打亂箩艺,出現(xiàn)許多代碼分支。通過仔細(xì)對(duì)比程序混淆前后宪萄,可以發(fā)現(xiàn)上圖著色區(qū)域是相對(duì)應(yīng)的,也就是說榨惰,F(xiàn)LA模式只去更改代碼分支拜英,而不會(huì)對(duì)單個(gè)代碼塊做處理。

-mllvm -fla: 啟用control flow flattening
-mllvm -split: 啟用block切分琅催,提升平展程度
-mllvm -split_num=3: 對(duì)每個(gè)block混淆3次居凶,默認(rèn)1詞
Bogus Control Flow

控制流偽造模式也是對(duì)程序的控制流做操作虫给,不同的是,BCF模式會(huì)在原代碼塊的前后隨機(jī)插入新的代碼塊侠碧,新插入的代碼塊不是確定的抹估,然后新代碼塊再通過條件判斷跳轉(zhuǎn)到原代碼塊中。更要命地是弄兜,原代碼塊可能會(huì)被克隆并插入隨機(jī)的垃圾指令药蜻。這么多不確定性,就導(dǎo)致對(duì)同一份代碼多次做BCF模式的混淆時(shí)替饿,得到的是不同的混淆效果语泽。可見视卢,BCF混淆模式還是很強(qiáng)大的踱卵,不同于FLA那種較確定的混淆模式。使用BCF模式編譯時(shí)配置參數(shù) -mllvm -bcf即可据过,此外惋砂,BCF模式還支持其它幾個(gè)參數(shù),下面參數(shù)與-mllvm -bcf參數(shù)配合使用绳锅。

-mllvm -bcf: 啟用 bogus control flow
-mllvm -bcf_loop=3: 對(duì)一個(gè)函數(shù)混淆3次班利,默認(rèn)1次
-mllvm -bcf_prob=40: 代碼塊被混淆的概率是40%,默認(rèn)30%

如上圖榨呆,下面兩個(gè)著色的代碼塊就是有上面兩個(gè)代碼塊克隆而來罗标,而且其中被插入了一些垃圾指令,類似于這樣:

當(dāng)然积蜻,上述介紹的三種混淆模式可以搭配使用闯割,同時(shí)使用三個(gè)參數(shù)混淆后,原本簡單的if-else分支代碼將會(huì)變得異常復(fù)雜竿拆,這無疑給逆向分析增加巨大的難度宙拉。

Functions annotations

有的時(shí)候,由于效率或其他原因的考慮丙笋,我們只想給指定的函數(shù)混淆或不混淆該函數(shù)谢澈,OLLVM也提供了對(duì)這一特性的支持,你只需要給對(duì)應(yīng)的函數(shù)添加attributes即可御板。比如锥忿,想對(duì)函數(shù)foo()使用fla混淆,只需要給函數(shù)foo()增加fla屬性即可怠肋。

int foo() __attribute((__annotate__(("fla"))));
int foo() {
   return 2;
}

你可以給函數(shù)添加一個(gè)或多個(gè)注釋敬鬓。如果你不想混淆某個(gè)函數(shù),你可以使用否定標(biāo)簽。例如如果不想對(duì)func()函數(shù)使用bcf屬性钉答,那標(biāo)記為“nobcf”即可础芍。

錯(cuò)誤處理

1.編譯時(shí)報(bào)錯(cuò),提示信息如下:

clang-3.6: error: unknown argument: '-gmodules'
clang-3.6: error: unknown argument: '-fembed-bitcode-marker'
Command /Users/dream/ollvm/build/bin/clang failed with exit code 1

在Build Settings中搜索并修改:
-gmodules: Obfuscator 4.0 - Code Generation: Generate Debug Symbols: 原來yes数尿,改成no
-fembed-bitcode-marker: Build Option: Enable Bitcode: 原來yes仑性,改成no

你可以在該git地址下找到最新的插件和build編譯器文件,該編譯器所使用的Xcode版本是8.3.3右蹦。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末诊杆,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子嫩实,更是在濱河造成了極大的恐慌刽辙,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件甲献,死亡現(xiàn)場離奇詭異宰缤,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)晃洒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門慨灭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人球及,你說我怎么就攤上這事氧骤。” “怎么了吃引?”我有些...
    開封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵筹陵,是天一觀的道長。 經(jīng)常有香客問我镊尺,道長朦佩,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任庐氮,我火速辦了婚禮语稠,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘弄砍。我一直安慰自己仙畦,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開白布音婶。 她就那樣靜靜地躺著慨畸,像睡著了一般。 火紅的嫁衣襯著肌膚如雪桃熄。 梳的紋絲不亂的頭發(fā)上先口,一...
    開封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天型奥,我揣著相機(jī)與錄音瞳收,去河邊找鬼碉京。 笑死,一個(gè)胖子當(dāng)著我的面吹牛螟深,可吹牛的內(nèi)容都是我干的谐宙。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼界弧,長吁一口氣:“原來是場噩夢啊……” “哼凡蜻!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起垢箕,我...
    開封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤划栓,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后条获,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體忠荞,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年帅掘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了委煤。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡修档,死狀恐怖碧绞,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情吱窝,我是刑警寧澤讥邻,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站院峡,受9級(jí)特大地震影響兴使,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜撕予,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一鲫惶、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧实抡,春花似錦欠母、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至啄清,卻和暖如春六水,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來泰國打工掷贾, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留睛榄,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓想帅,卻偏偏與公主長得像场靴,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子港准,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容