日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

代码混淆android.mk,利用ollvm进行代码混淆

發(fā)布時(shí)間:2024/9/27 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 代码混淆android.mk,利用ollvm进行代码混淆 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

OLLVM簡(jiǎn)介

OLLVM(Obfuscator-LLVM)是瑞士西北應(yīng)用科技大學(xué)于2010年6月份發(fā)起的一個(gè)項(xiàng)目,該項(xiàng)目旨在提供一套開源的針對(duì)LLVM的代碼混淆工具,以增加對(duì)逆向工程的難度。

OLLVM是基于LLVM實(shí)現(xiàn)的,LLVM是一個(gè)編譯器框架,它也采用經(jīng)典的三段式設(shè)計(jì)。前端可以使用不同的編譯工具對(duì)代碼文件做詞法分析以形成抽象語(yǔ)法樹AST,然后將分析好的代碼轉(zhuǎn)換成LLVM的中間表示IR(intermediate representation);中間部分的優(yōu)化器只對(duì)中間表示IR操作,通過(guò)一系列的Pass對(duì)IR做優(yōu)化;后端負(fù)責(zé)將優(yōu)化好的IR解釋成對(duì)應(yīng)平臺(tái)的機(jī)器碼。LLVM的優(yōu)點(diǎn)在于,不同的前端語(yǔ)言最終都轉(zhuǎn)換成同一種的IR。

OLLVM的混淆操作就是在中間表示IR層,通過(guò)編寫Pass來(lái)混淆IR,然后后端依據(jù)IR來(lái)生成的目標(biāo)代碼也就被混淆了。得益于LLVM的設(shè)計(jì),OLLVM適用LLVM支持的所有語(yǔ)言(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的幾種混淆方式

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)模式

-sub instruction substitution(指令替換)

-fla control flow flattening(控制流平坦化)

-bcf bogus control flow(控制流偽造)

此外,OLLVM支持對(duì)單個(gè)函數(shù)進(jìn)行混淆,即Functions annotations模式

以下分別介紹這幾種方式并舉例說(shuō)明:

instruction substitution(指令替換)

指令替換是一種比較簡(jiǎn)單的混淆方式,OLLVM將一些簡(jiǎn)單的運(yùn)算復(fù)雜化,但這種方式容易被代碼優(yōu)化給去除,目前OLLVM只實(shí)現(xiàn)對(duì)整數(shù)運(yùn)算的混淆。

加法混淆

例如 a = b + c 可以被混淆為:

1

2

3

41. a = b - (-c)

2. a = -(-b + (-c))

3. r = rand (); a = b + r; a = a + c; a = a - r

4. r = rand (); a = b - r; a = a + b; a = a + r

減法混淆

例如 a = b-c 可以被混淆為:

1

2

31. a = b + (-c)

2. r = rand (); a = b + r; a = a - c; a = a - r

3. r = rand (); a = b - r; a = a - c; a = a + r

AND運(yùn)算混淆

a = b & c => a = (b ^ ~c) & b

OR運(yùn)算混淆

a = b | c => a = (b & c) | (b ^ c)

XOR運(yùn)算混淆

a = a ^ b => a = (~a & b) | (a & ~b)

如果一種運(yùn)算對(duì)應(yīng)多種混淆方式,OLLVM將會(huì)隨機(jī)選擇一種,以下為使用OLLVM進(jìn)行指令替換后的前后對(duì)比:

源碼:1

2

3

4

5int test(int a,int b)

{

int c = a + b;

return c+2;

}

sub前:

sub后

分析匯編指令得出,a+b+2 運(yùn)算變成了 -(-b-(a+2))

control flow flattening(控制流平坦化)

control flow flattening(控制流平坦化)通過(guò)多個(gè)case-swich結(jié)構(gòu)將程序的控制流變成扁平形狀,打破原有的邏輯結(jié)構(gòu),增加逆向的難度。

例如對(duì)于以下代碼:

1

2

3

4

5

6

7

8

9#include

int main(int argc, char** argv) {

int a = atoi(argv[1]);

if(a == 0)

return 1;

else

return 10;

return 0;

}

OLLVM將把它變?yōu)槿缦陆Y(jié)構(gòu):

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22#include

int main(int argc, char** argv) {

int a = atoi(argv[1]);

int b = 0;

while(1) {

switch(b) {

case 0:

if(a == 0)

b = 1;

else

b = 2;

break;

case 1:

return 1;

case 2:

return 10;

default:

break;

}

}

return 0;

}

從代碼中可以看到,OLLVM將源代碼分割為幾個(gè)基本塊,并放在一個(gè)while循環(huán)結(jié)構(gòu)中無(wú)線循環(huán),程序的流程由變量b控制。

以下是使用OLLVM進(jìn)行控制混淆后的前后對(duì)比:

源碼1

2

3

4

5

6

7

8

9#include

int main(int argc, char** argv) {

int a = atoi(argv[1]);

if(a == 0)

return 1;

else

return 10;

return 0;

}

fla之前:

fla之后:

F5之后的代碼:

由此可見(jiàn),fla之后的控制流比較復(fù)雜,通過(guò)分析fla之后的代碼,我們發(fā)現(xiàn)代碼中的result僅僅受v7的影響,但分析起來(lái)著實(shí)費(fèi)力。

bogus control flow(控制流偽造)

bogus control flow通過(guò)在源程序的控制流中添加一些基本塊,這些基本塊僅僅起了連接作用,并不影響實(shí)際的執(zhí)行邏輯。

以下為使用OLLVM進(jìn)行控制流偽造后的對(duì)比:

源碼

1

2

3

4

5

6

7

8

9#include

int main(int argc, char** argv) {

int a = atoi(argv[1]);

if(a == 0)

return 1;

else

return 10;

return 0;

}

bcf之前:

![upload successful](/images/pasted-128.png)

bcf之后:

![upload successful](/images/pasted-131.png)

F5之后的代碼:

![upload successful](/images/pasted-132.png)

由此看出,bcf的方式在程序中增加了一個(gè)代碼塊,這個(gè)代碼塊對(duì)函數(shù)返回值沒(méi)有任何影響,但對(duì)于逆向人員來(lái)說(shuō),增加了其逆向分析的無(wú)用功。

Functions annotations

有時(shí)候?yàn)榱颂岣咝?#xff0c;開發(fā)者僅需要對(duì)指定的函數(shù)進(jìn)行混淆,OLLVM的Functions annotations模式支持對(duì)單個(gè)函數(shù)進(jìn)行混淆。比如,想對(duì)函數(shù)func()使用bcf混淆,只需要給函數(shù)func()增加bcf屬性即可。

1int func() __attribute((__annotate__(("bcf"))));

OLLVM的fla,sub和bcf三個(gè)屬性可以搭配使用,只需要添加對(duì)應(yīng)的編譯選項(xiàng)即可。

利用OLLVM進(jìn)行Android native代碼混淆

1.下載并編譯ollvm1

2

3

4

5$ 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

2.配置NDK以支持ollvm新建編譯鏈

在 android-ndk-r14b/toolchains 下新建目錄 ollvm-4.0/prebuilt/darwin-x86_64(我的環(huán)境是mac),把前一步編譯生成的結(jié)果拷貝到此目錄下(主要是bin和lib)

配置編譯鏈

在 android-ndk-r14b/build/core/toolchains 目錄下,新建目錄 arm-linux-androideabi-clang-ollvm4.0,拷貝目錄 arm-linux-androideabi-clang 下的文件 config.mk 與 setup.mk 到 arm-linux-androideabi-clang-ollvm4.0 中,修改setup.mk文件。1

2

3

4

5

6

7

8

9############################ 原始配置 ############################

#LLVM_TOOLCHAIN_PREBUILT_ROOT := $(call get-toolchain-root,llvm)

#LLVM_TOOLCHAIN_PREFIX := $(LLVM_TOOLCHAIN_PREBUILT_ROOT)/bin/

#################################################################

############################ 修改后 #############################

OLLVM_NAME := ollvm-4.0

LLVM_TOOLCHAIN_PREBUILT_ROOT := $(call get-toolchain-root,$(OLLVM_NAME))

LLVM_TOOLCHAIN_PREFIX := $(LLVM_TOOLCHAIN_PREBUILT_ROOT)/bin/

#其他配置不做修改

3.使用ollvm進(jìn)行編譯

使用 ollvm 進(jìn)行 ndk 的編譯需要對(duì) Application.mk 和 Android.mk 文件做相應(yīng)的修改。

Android.mk 中添加混淆編譯參數(shù):

1LOCAL_CFLAGS += -mllvm -sub -mllvm -bcf -mllvm -fla

Application.mk 中配置 NDK_TOOLCHAIN_VERSION

1

2APP_ABI := x86 armeabi-v7a x86_64 arm64-v8a armeabi mips64

NDK_TOOLCHAIN_VERSION := clang-ollvm-4.0

參考資料:

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的代码混淆android.mk,利用ollvm进行代码混淆的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。