為OLLVM新增字串混淆功能
本文簡單介紹了下使用上海交大GoSSIP小組開源的“孤挺花”混淆框架來給OLLVM加上字串混淆的功能。
0x01 OLLVM 4.0
OLLVM(Obfuscator-LLVM)是瑞士西北應用科技大學安全實驗室於2010年6月份發起的一個針對LLVM程式碼混淆專案,主要作用是增加逆向難度,從而一定程度上保護程式碼的安全。因為後期轉向了商業專案strong.protect,所以專案的進度一度停滯,而在17年3月,LLVM已經更新到了4.0版本,新版本的一些特性導致老版本的OLLVM存在一定的侷限性。
幾天前,上海交大密碼與電腦保安實驗室GoSSIP小組開源了他們設計的基於LLVM 4.0的孤挺花混淆框架
YSRC簡單的做了下分析,發現該功能主要是實現了一個用於字串加密的pass,具體什麼是pass,可以參考如下文章(① ,②),本文主要介紹將孤挺花的字串加密pass整合到OLLVM 4.0中。(官方分支暫時還未支援Constants encryption)
0x02 pass整合
字串加密的pass位於如下目錄
提取出該檔案,放到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檔案,可以看到函式中的字串已經不顯示了,
而Test函式的流程也被進行了混淆。
F5後:
0x05 總結
在專案中合理的使用ollvm可以幫助增加逆向難度,並且針對關鍵的函式混淆對效能的影響也比較小。