使用O-LLVM和NDK對Android應用進行混淆

發表於2015-08-07

混淆是一種用來隱藏程式意圖的技術,具體的實現技術可能差別比較大,最有效的技術可以增加逆向工程和破解的難度,防止智慧財產權被竊取。已經有很多第三方的軟體可以用來混淆我們的Android應用,常見的有:

  • Proguard
  • DashO
  • Dexguard
  • DexProtector
  • ApkProtect
  • Shield4j
  • Stringer
  • Allitori

這些混淆器在程式碼中起作用的層次是不一樣的。Android編譯的大致流程如下:

有的混淆器是在編譯之前直接作用於java原始碼,有的作用於java位元組碼,有的作用於Dalvik位元組碼。

Android NDK使得開發者可以繞過虛擬機器從而進一步提高程式效能,或者更直接的與核心和硬體互動。Google對NDK的描述是:“NDK是允許開發者使用原生C/C++語言開發app的一套工具集。這樣有利於某些型別的app複用C/C++編寫的已有程式碼庫,當然大部分app不需要使用Android NDK”。

相對於Dalvik虛擬機器層次的混淆而言,原生語言(C/C++)元件的程式碼混淆選擇並不多,Obfuscator-LLVM工程是一個值得關注的例外。這個專案專注於LLVM編譯器,這一點使得它可移植性很高,相容LLVM支援的所有語言(C,C++, Objective-C, Ada and Fortran)和平臺(x86, x86-64, PowerPC, PowerPC-64,ARM, Thumb, SPARC, Alpha, CellSPU, MIPS, MSP430, SystemZ,and XCore)。0vercl0k在o-llvm釋出之前發表了一篇論文,解釋了使用LLVM編譯器的優點以及簡單的程式碼轉換。

我使用O-LLVM和NDK已經有一段時間了。在瞭解到TowelRoot也在使用O-LLVM時,我決定寫一篇文章來介紹它。TowelRoot是一款Android一鍵Root工具,關於它是如何利用Linux核心bug來達到root目的的可以參見這篇文章。TowelRoot使用O-LLVM主要用來防止其他人拷貝並利用它來實現非法目的,同時防止被重打包後並出售。

下面我們就來講解如何開始使用O-LLVM來混淆原生程式碼,實現類似TowelRoot的目的。

使用NDK O-LLVM二進位制疊加包

我已經在OSX和Linux平臺上把混淆器基於NDK打包成二進位制疊加包,你也可以參照本文最後一節的步驟自己從原始碼進行編譯。混淆器的二進位制疊加包下載地址:

下載正確的二進位制疊加包,將它解壓到你電腦的NDK目錄中。

配置O-LLVM NDK工程

現在讓我們對NDK工程進行配置,使其支援O-LLVM混淆器。我們工程目錄結構如下所示:

工程的Application.mk內容如下:

混淆器的各種程式碼轉換可以參見Obfuscator Wiki。可以通過LOCAL_CFLAGS標籤把這些轉換標記設定給混淆器。記住混淆器的轉換標記需要以-mllvm開頭,這樣clang編譯器可以傳遞它。

Android.mk的配置示例如下:

現在可以編譯我們的工程了:

使用了上面的配置和指令碼結構的例子工程可以參見AndroidObfuscation-NDK。

上面我預先構建的二進位制疊加包包含了由yag00貢獻的試驗性的字串混淆技術。你可以通過給LOCAL_CFLAGS傳遞“-mllvm -xse”標記來使能字串混淆功能。

這個例子中,在使用字串混淆功能之前效果如下:

使用字串混淆功能之後:

從原始碼構建適用於NDK的O-LLVM

構建o-llvm的完整指南參見這裡,不過上面的說明應該足夠了。

開啟檔案

將檔案裡面的:

修改為(記得修改o-llvm為你自己電腦上面的路徑)

相關文章