基礎(chǔ)知識
LLVM是lowlevel virtual machine的簡稱,它誕生于2003.10伊利諾伊大學(xué)香檳分校,創(chuàng)始人是ChrisLattner,它是一個完整的編譯器框架,它兼容大部分主流開發(fā)語言例如:C, C++, Objective-C等等,它也兼容大部分主流的平臺:x86, x86-64, PowerPC, PowerPC-64,ARM,Thumb等等。
(圖片來源網(wǎng)絡(luò))
LLVM會先將源碼生成為與目標(biāo)機器無關(guān)的LLVMIR代碼,然后把LLVMIR代碼先優(yōu)化,再向目標(biāo)機器的匯編語言而轉(zhuǎn)換。LLVM編譯器主要細(xì)分為前端、中層優(yōu)化和后端的3部分構(gòu)成。
(圖片來源網(wǎng)絡(luò))
OLLVM就是在LLVM的基礎(chǔ)上增加了obfuscator(混淆), Obfuscator-LLVM (OLLVM) 是2010 年 6 月由 Yverdon-les-Bains 的瑞士西北應(yīng)用科技大學(xué)安全實驗室針對LLVM編譯組件開發(fā)的代碼混淆工具,該工具完全開源,這個OLLVM主要為了增加逆向工程的難度,保證代碼的安全性。
Obfuscator-LLVM (OLLVM)集成了LLVM編譯器,并且兼容LLVM支持的所有語言(C,C++, Objective-C, Ada and Fortran)和平臺(x86, x86-64, PowerPC,PowerPC-64,ARM,Thumb,SPARC,Alpha,CellSPU,MIPS, MSP430, SystemZ,XCore)。
OLLVM的混淆原理,就是在不改變源代碼功能前提下,將C或C++代碼中的控制語句if、while、for、do等轉(zhuǎn)換成switch分支語句。這樣實現(xiàn)的優(yōu)勢是,它可以模糊switch中case代碼塊之間的關(guān)系,從而增加逆向分析代碼難度。
混淆的具體實現(xiàn)思路,首先將要實現(xiàn)代碼平坦化的函數(shù)分成多個基本塊(就是case代碼塊)和一個入口塊,并為每個基本塊設(shè)置編號,并讓這些基本塊都有共同的前驅(qū)模塊和后繼模塊。前驅(qū)模塊主要是進(jìn)行基本塊的分發(fā),后繼模塊的分發(fā)通過改變switch變量來實現(xiàn)。
OLLVM和LLVM主要的功能的代碼差異點如下圖所示
OLLVM功能介紹
OLLVM全面模式支持以下四種代碼包含模式
1、-mllvm -fla: 控制流化扁平化
2、-mllvm -sub:指令替換
3、-mllvm -bcf: 控制流程
4、-mllvm -sobf: 字符串加密
以O(shè)LLVM保護(hù)后的功能效果都在文章的后部分進(jìn)行展示。
-mllvm -fla中fla的全稱:Control Flow Flattening,它也稱為控制流扁平化,這個功能模式主要原理就是把一些if-else語句,嵌套成do-while語句。
它支持以下3種保護(hù)功能模式:
-mllvm -fla: 激活控制流扁平化
-mllvm -split:激活基本塊分裂。一起使用時提高平整度。
-mllvm -split_num=3:如果激活通行證,則在每個基本塊上應(yīng)用 3 次。默認(rèn)值:1
-mllvm -sub,它的全稱Instructions Substitution,它又稱為指令替換,這個的原理可以理解為就是不改變功能的前提下,將簡單的指令替換成更復(fù)雜的指令,當(dāng)有多個等效指令序列可用時候,會隨機選擇一個指令進(jìn)行替換。這個混淆它并不會增強過多的安全性,因為它可以通過重新優(yōu)化生成的代碼輕松刪除,如果選擇使用隨機生成器以不同數(shù)值作為種子,指令替換會在生成的二進(jìn)制文件中帶來多樣性。
它支持以下的2種模式功能:
-mllvm -sub:激活指令替換
-mllvm -sub_loop=3:如果激活了傳遞,則在函數(shù)上應(yīng)用3次。默認(rèn)值:1
-mllvm -bcf,它的全稱Bogus Control Flow,也稱為虛假控制流。這個主要原理就是在當(dāng)前基本塊之前添加一個新的基本塊用來修改函數(shù)調(diào)用圖,這個新的基本塊包含一個不透明的謂詞,通過有條件地跳轉(zhuǎn)到原來的基本塊。原始的基本塊也會被克隆并填充隨機的垃圾指令。
這虛假控制流代碼保護(hù)模式主要通過在不改變代碼功能前提下往代碼里面嵌套幾層的判斷邏輯,這種模式下會大大影響程序的性能,因為它在代碼下混雜著真真假假的代碼。
這個模式下它支持3種功能選項:
-mllvm -bcf: 激活偽造的控制流通道
-mllvm -bcf_loop=3: 如果 pass 被激活,在一個函數(shù)應(yīng)用 3 次。默認(rèn)值:1
-mllvm -bcf_prob=40:如果激活通行證,一個基本塊將以 40% 的概率被混淆。默認(rèn)值:30
-mllvm -sobf也稱為字符串混淆,主要實現(xiàn)將代碼中的字符串做加密,使得無法通過靜態(tài)逆向方式直接看到字符串信息。
它主要支持2種功能模式選項:
-mllvm -sobf:編譯時候添加選項開啟字符串加密
-mllvm -seed=0xdeadbeaf:指定隨機數(shù)生成器種子流程
OLLVM編譯
編譯OLLVM前需要以下的工具和代碼:
1、OLLVM源碼(基礎(chǔ)之源)
https://releases.llvm.org/download.html
2、cmake工具(將OLLVM轉(zhuǎn)換為sln項目)
https://cmake.org/download/
3、Visual studio工具(編譯OLLVM源碼)
https://visualstudio.microsoft.com/zh-hans/
在window環(huán)境下編譯OLLVM的源碼主要需要經(jīng)歷2個步驟
1、通過利用cmake將OLLVM的源碼轉(zhuǎn)換為sln的項目
可以通過利用cmake工具或者用命令行方式轉(zhuǎn)換,下面以命令行方式轉(zhuǎn)換的
cmake -Thost=x64 -G "Visual Studio 16" E:ollvm9obfuscator-llvm-9.0.1obfuscator-llvm-9.0.1
上面要主要的是Visual Studio 16這個代表你環(huán)境中安裝的vs版本,我安裝2019版本的,所以用它。
通過執(zhí)行以上命令后就會出現(xiàn)下圖的效果
2、用Visual studio 2019 直接編譯前面生成的OLLVM項目,主要編譯Release版本。編譯后正確情況下會生成bin和lib兩個文件夾。
OLLVM集成
通過前面的編譯后生成的bin和lib文件夾,集成到NDK中,并通過android studio編譯器進(jìn)行so代碼保護(hù)的應(yīng)用。
將vs編譯生成后的bin和lib文件夾,替換到NDK中的llvm文件夾下面toolchainsllvmprebuiltwindows-x86_64(替換之前切記做下備份,萬一出問題了還能回滾)
通過配置Android.mk文件進(jìn)行設(shè)定需要對so文件采用什么方式的全局代碼保護(hù)。
可能大家會覺得保護(hù)強度越強越好,代碼虛擬化、字符串混淆、指令替換等等都給用下去,那樣就安全了,其實不是這樣的,這些強度雖然上去了但是會給項目帶來非常大的負(fù)擔(dān)。往往會帶來負(fù)面性能影響。
個人建議:可以針對字符串做個混淆(-mllvm -sobf),外加指定核心函數(shù)進(jìn)行做代碼保護(hù)。這樣強度也有了,對應(yīng)用的性能影響方面也相對較小。
上圖中Android.mk設(shè)置的保護(hù)方式屬于全局的保護(hù),設(shè)置后整個so就都會基于設(shè)置的保護(hù)。
通過配置Application.mk文件,進(jìn)行指定ollvm的clang具體版本數(shù)據(jù)(這個具體版本數(shù)據(jù)也可以lib文件夾下clang文件夾下查看)。
OLLVM保護(hù)效果
為了更好展示分析ollvm保護(hù)后的效果,主要通過基于__attribute((__annotate__(("sub"))))這種方式,對指定函數(shù)進(jìn)行做保護(hù),而沒有進(jìn)行配置全局的保護(hù)。
下圖的代碼功能效果僅是為了測試OLLVM的虛假指令保護(hù)后的實現(xiàn)效果
下圖是基于IDA工具的原始和虛假控制流的代碼保護(hù)流程圖,可以看到代碼的執(zhí)行流程已被調(diào)整變得相對復(fù)雜化,這樣就大大強化了代碼的安全強度,這種逆向分析其代碼至少靜態(tài)分析起來就費勁了。
下圖是通過指定函數(shù)進(jìn)行設(shè)置指令替換的功能的代碼展示
通過下圖IDA靜態(tài)的代碼流程圖可以很清晰分析到,它實際上代碼流程是沒有任何變化的,所以這種保護(hù)模式下的代碼保護(hù)功能時沒有很明顯的效果的。
下圖的代碼是通過調(diào)用ollvm的控制流扁平化功能進(jìn)行對函數(shù)保護(hù)的代碼展示
通過下圖IDA的代碼流程圖,可以看到代碼控制流扁平化保護(hù)后,整個流程就變得復(fù)雜化了。這就讓代碼的安全性上升一個層次了,這樣逆向分析還原代碼功能的成本就大大提高了。
小結(jié)
通過上文OLLVM的一系列的原理集成、編譯、配置、集成、代碼生成、效果展示,主要為了給SO代碼的防破解防逆向增加點門檻,提高點安全性。這系列的代碼保護(hù)對于專業(yè)搞逆向的人員來說,它們可以通過基于Trace、unicron、frida這些方式去還原和去除OLLVM的混淆保護(hù)。
對于代碼的安全性思考,不過在安全攻防對抗的過程中防御一直屬于被動狀態(tài)的也是相對滯后的。安全防護(hù)也是隨著對抗去不斷去提高變強。
代碼安全防護(hù)方面可以借助于OLLVM然后進(jìn)行做定制魔改,現(xiàn)有的逆向工具更多是基于標(biāo)準(zhǔn)化進(jìn)行做反匯編,那么我們可以對這些逆向工具做些防護(hù)(可以多個方案結(jié)合),然后調(diào)整成為一些非標(biāo)準(zhǔn)化的,這樣會大大增加逆向分析的成本。
只要逆向分析成本超過所破解后所獲取的收益,那么你的代碼就相對安全了。
-
代碼
+關(guān)注
關(guān)注
30文章
4837瀏覽量
69131 -
編譯器
+關(guān)注
關(guān)注
1文章
1642瀏覽量
49318
原文標(biāo)題:一種高端的APP代碼保護(hù)方案
文章出處:【微信號:哆啦安全,微信公眾號:哆啦安全】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
請問ubuntu 14.04 編譯am57xx SDK , 發(fā)生nativesdk-ti-llvm3.6異常是為什么?
LLVM clang 公開 -std=c++23
在Swift中使用LLVM的四個要點
![在Swift中使用<b class='flag-5'>LLVM</b>的四個要點](https://file.elecfans.com/web2/M00/4A/04/pYYBAGKhvImAJECmAAAQHBhHYC8733.png)
四個不同的系統(tǒng)上進(jìn)行LLVM/Clang 6.0 和 5.0 的編譯器Benchmark測試
LLVM終身程序分析與轉(zhuǎn)換的編譯框架的詳細(xì)資料說明
![<b class='flag-5'>LLVM</b>終身程序分析與轉(zhuǎn)換的編譯框架的詳細(xì)資料說明](https://file.elecfans.com/web1/M00/BE/6A/pIYBAF7dtdaAEESSAACbwf9HFso010.png)
微軟與LLVM、Rust達(dá)成合作,將CFG支持添加到編譯器
淺談LLVM LibFuzzer工具和實踐
LLVM源碼淺析-1
![<b class='flag-5'>LLVM</b>源碼淺析-1](https://file1.elecfans.com/web2/M00/81/BE/wKgaomQAWOiAOBP3AAWt4hqd4j8634.jpg)
LLVM國際開源軟件社區(qū)發(fā)布正式支持LoongArch架構(gòu)的版本
什么是LLVM?LLVM的優(yōu)勢和特點有哪些?
使用LLVM-embedded-toolchain-for-Arm-17.0.1開發(fā)STM32
![使用<b class='flag-5'>LLVM</b>-embedded-toolchain-for-Arm-17.0.1開發(fā)STM32](https://file1.elecfans.com/web2/M00/AB/9B/wKgZomU2MjmAK1guAADOLcPS5Uc010.jpg)
評論