1. 程式人生 > >為OLLVM新增字串混淆功能

為OLLVM新增字串混淆功能

本文簡單介紹了下使用上海交大GoSSIP小組開源的“孤挺花”混淆框架來給OLLVM加上字串混淆的功能。

0x01 OLLVM 4.0

OLLVM(Obfuscator-LLVM)是瑞士西北應用科技大學安全實驗室於2010年6月份發起的一個針對LLVM程式碼混淆專案,主要作用是增加逆向難度,從而一定程度上保護程式碼的安全。因為後期轉向了商業專案strong.protect,所以專案的進度一度停滯,而在17年3月,LLVM已經更新到了4.0版本,新版本的一些特性導致老版本的OLLVM存在一定的侷限性。

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=

幾天前,上海交大密碼與電腦保安實驗室GoSSIP小組開源了他們設計的基於LLVM 4.0的孤挺花混淆框架

,功能包含字串加密,控制流扁平化和指令替換。出於穩定性考慮,目前開源的程式碼僅包括對編譯原始碼中的常量字串加密一項基本功能(相關簡介)。給上海交大的同學點贊 : )

YSRC簡單的做了下分析,發現該功能主要是實現了一個用於字串加密的pass,具體什麼是pass,可以參考如下文章( ,),本文主要介紹將孤挺花的字串加密pass整合到OLLVM 4.0中。(官方分支暫時還未支援Constants encryption)

0x02 pass整合

字串加密的pass位於如下目錄

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=

提取出該檔案,放到OLLVM相同目錄下,並將標頭檔案也複製到對應目錄下

在Obfuscation下的cmakelists.txt將StringObfuscation.cpp新增到編譯庫中,最後只需要在Transforms/IPO下的PassManagerBuilder.cpp將字串加密的編譯選項新增進去即可

1. 新增#include “llvm/Transforms/Obfuscation/StringObfuscation.h”引用

2. 在合適的地方插入以下兩條函式宣告,即編譯時的編譯引數-mllvm -sobf: 

3. 在PassManagerBuilder::PassManagerBuilder()建構函式中新增隨機數因子的初始化

static cl::opt<std::string> Seed("seed", cl::init(""), cl::desc("seed for the random")); static cl::opt<bool> StringObf("sobf"
, cl::init(false), cl::desc("Enable the string obfuscation"));

4. 最後將該pass新增進void PassManagerBuilder::populateModulePassManager中即可

0x03 Windows下編譯OLLVM

這裡編譯環境選擇的是windows,其它平臺類似 

編譯器:

MinGW64 for Windows

Cmake 3.9 rc5 for Windows x64

這裡注意下套件都是選擇的64位版本的,並且要注意最好清除下系統變數中之前配置的變數。

官方編譯命令:

mkdir build

cd build

cmake -DCMAKE_BUILD_TYPE=Release ../obfuscator/

make -j7

如果cmake如果不指定引數的話,會預設去選擇當前電腦裡已有的編譯器,如果安裝了vs的話,會自動去查詢vs的編譯器

如果打算使用vs編譯 

cmake -DCMAKE_BUILD_TYPE=Release ../obfuscator/ 

會生成32位的依賴版本 

cmake -G “Visual Studio 15 2017 Win64” -DCMAKE_BUILD_TYPE=Release ../obfuscator/ 

上面這種方法就會生成64位版本的編譯環境,不過在測試編譯時,32位正常編譯通過,64位踩了很多坑,所以還是不建議使用vs編譯。

使用MinGw編譯時,需要加上引數 

cmake -G “MinGW Makefiles” -DCMAKE_BUILD_TYPE=Release ../obfuscator/ 

最後再執行make -j7 即可,數字可根據電腦配置進行選擇,編譯完成後,會在build/bin下看到編譯完成的二進位制檔案。

0x04 NDK使用OLLVM

將編譯好的clang.exe , clang++.exe 以及上級目錄下 lib/clang下的資料夾拷貝出來,我這裡使用的是ndk 13,直接將這些檔案拷貝到toolchainsllvmprebuiltwindows-x86_64,其中exe檔案複製到bin目錄下,lib資料夾直接複製到windows-x86_64目錄下即可。

新建一個Android Studio工程測試下效果,開啟字串加密編譯選項

編寫測試函式

在函式前添加了fla屬性,該屬性代表ollvm的Control Flow Flattening ,具體可見ollvm專案的wiki,編譯執行檢視結果。

使用IDA開啟編譯後的so檔案,可以看到函式中的字串已經不顯示了,

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=

而Test函式的流程也被進行了混淆。

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=

F5後:

640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=

0x05 總結

在專案中合理的使用ollvm可以幫助增加逆向難度,並且針對關鍵的函式混淆對效能的影響也比較小。