一 、概念介绍:LLVM和OLLVM
-
LLVM是一个完整的编译器架构,其中前端编译器使用了clang。
代码经过LLVM的编译过程:
其中,解释一下IR(也成为BitCode码),LLVM编译器在传统的三层模型中加入了中介码,前端完成源码解析编译后,转成中介码,LLVM编译器针对中介码进行优化和改良,然后将中介码送入目标平台编译器生成目标代码,整个编译过程中都是中介码在参与,所以说跟目标语言和平台无关,但是与架构相关。 -
OLLVM(Obfuscator-llvm)
在原有的LLVM上添加PASS,添加了bla/sub/bcf/fla等pass,这些pass对IR(Bitcode)进行处理,如指令替换(sub),控制流平展(fla),控制流伪造(bcf)等。
这点从OLLVM的源码中也能体现出来:// Flags for obfuscation static cl::opt<bool> Flattening("fla", cl::init(false), cl::desc("Enable the flattening pass")); static cl::opt<bool> BogusControlFlow("bcf", cl::init(false), cl::desc("Enable bogus control flow")); static cl::opt<bool> Substitution("sub", cl::init(false), cl::desc("Enable instruction substitutions")); static cl::opt<std::string> AesSeed("aesSeed", cl::init(""), cl::desc("seed for the AES-CTR PRNG")); static cl::opt<bool> Split("split", cl::init(false), cl::desc("Enable basic block splitting")); MPM.add(createSplitBasicBlock(Split)); MPM.add(createBogus(BogusControlFlow)); MPM.add(createFlattening(Flattening));
注:即使不用ollvm,LLVM本身也是有很多pass的,具体的类型主要有以下几种
- ImmutablePass
- MoudlePass
- CallGraphSCCPass
- FuncationPass
- LoopPass
- RegionPass
- BasicBlockPass
- MachineFunctionPass
二、官方LLVM和其Clang
1.安装
在官方下载llvm,下载源码包,官方把llvm和clang分开,需要把llvm和clang源码包都下载下来。
解压,改clang的包名,移动至llvm的tools下。
在llvm同级目录新建build目录,cd build
cmake -G "Unix Makefiles" --enable-optimized -DCMAKE_BUILD_TYPE=Release ../llvm-5.0.2.src
2.使用clang编译.c文件
源代码:
#include<stdio.h>
int main() {
int a = 4,b = 5;
printf("a+b=%d",a+b);
printf("hello world\n");
return 0;
}
-
用clang将源文件编译为LLVM IR的二进制文件(Bitcode)
- 编译不添加-fembed-bitcode参数,即
clang -emit-llvm -c test.c -o test.bc
然而.bc文件不易读取其内容,命令llvm-dis test.bc
可以将bc转化为.ll变为可读的IR文件
执行cat test.ll
,输出如下:
; ModuleID = 'test.bc' source_filename = "test.c" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" @.str = private unnamed_addr constant [7 x i8] c"a+b=%d\00", align 1 @.str.1 = private unnamed_addr constant [13 x i8] c"hello world\0A\00", align 1 ; Function Attrs: noinline nounwind optnone uwtable define i32 @main() #0 { %1 = alloca i32, align 4 %2 = alloca i32, align 4 %3 = alloca i32, align 4 store i32 0, i32* %1, align 4 store i32 4, i32* %2, align 4 store i32 5, i32* %3, align 4 %4 = load i32, i32* %2, align 4 %5 = load i32, i32* %3, align 4 %6 = add nsw i32 %4, %5 %7 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str, i32 0, i32 0), i32 %6) %8 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.1, i32 0, i32 0)) ret i32 0 } declare i32 @printf(i8*, ...) #1 attributes #0 = { noinline nounwind optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } !llvm.module.flags = !{ !0} !llvm.ident = !{ !1} !0 = !{ i32 1, !"wchar_size", i32 4} !1 = !{ !"clang version 5.0.2 (tags/RELEASE_502/final)"}
- 添加-fembed-bitcode参数,即
clang -emit-llvm -fembed-bitcode -c test.c -o test_bitcode.bc
,产生的bc文件经过llvm-dis文件处理,cat查看,输出如下:
; ModuleID = 'test_bitcode.bc' source_filename = "test.c" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" @.str = private unnamed_addr constant [7 x i8] c"a+b=%d\00", align 1 @.str.1 = private unnamed_addr constant [13 x i8] c"hello world\0A\00", align 1 @llvm.embedded.module = private constant [2756 x i8] c"BC\C0\DE5\14\00\00\05\00\00\00b\0C0$IY\BEf\EE\D3\BE-D\012\05\00\00\00\00! \0C\00\00_\02\00\00\0B\02!\00\02\00\00\00\13\00\00\00\07\81#\91A\C8\04I\06\1029\92\01\84\0C%\05\08\19\1E\04\8Bb\80\10E\02B\92\0B B\84\102\148\08\18K\0A2B\88H\90\14 CF\88\A5\00\192B\E4H\0E\90\11\22\C4PAQ\81\8C\E1\83\E5\8A\04!F\06Q\18\00\00(\01\00\00\1B\D8&\F 8\FF\FF\FF\FF\01p\00\09(\03 \0C\88qx\07y\90\87r\18\07z`\87|h\03yx\87zp\07r(\07rh\03rH\07{ H\07r(\876\98\87x\90\07zh\03s\80\876h\8 7p\A0\07t\00\CC!\1C\D8a\1E\CA\01 \C8!\1D\E6!\1C\C4\81\1D\CA\A1\0D\E8!\1C\D2\81\1D\DA`\1C\C2\81\1D\D8a\1E\00s\08\07v\98\87r\00\08 v(\87y\98\876\80\07y(\87qH\87y(\8760\07xh\87p \07\C0\1C\C2\81\1D\E6\A1\1C\00\C2\1D\DE\A1\0D\CCA\1E\C2\A1\1D\CA\A1\0D\E0\E1\1D\D2 \C1\1D\E8\A1\1C\E4\A1\0D\CA\81\1D\D2\A1\1D\00z\90\87z(\07`p\87wh\03s\90\87ph\87rh\03xx\87tp\07z(\07yh\83r`\87th\876p\87wp\876`\8 7r\08\07s\00\08wx\876H\07w0\87yh\03s\80\876h\87p\A0\07t\00\CC!\1C\D8a\1E\CA\01 \DC\E1\1D\DA@\1D\EA\A1\1D\E0\A1\0D\E8!\1C\C4\81\1 D\CAa\1E\00s\08\07v\98\87r\00\08wx\876p\87pp\87yh\03s\80\876h\87p\A0\07t\00\CC!\1C\D8a\1E\CA\01 \DC\E1\1D\DA`\1E\D2\E1\1C\DC\A1\ 1C\C8\A1\0D\F4\A1\1C\E4\E1\1D\E6\A1\0D\CC\01\1E\DA\A0\1D\C2\81\1E\D0\010\87p`\87y(\07\80p\87wh\03z\90\87p\80\07xH\07w8\876h\87p\ A0\07t\00\CC!\1C\D8a\1E\CA\01 \E6\81\1E\C2a\1C\D6\A1\0D\E0A\1E\DE\81\1E\CAa\1C\E8\E1\1D\E4\A1\0D\C4\A1\1E\CC\C1\1C\CAA\1E\DA`\1E \D2A\1F\CA\01\C0\03\80\A0\87p\90\87s(\07zh\83q\80\87z\00\F0\01\0F\EC\A0\0D\EC\80\0E\00\82\1E\C2A\1E\CE\A1\1C\E8\A1\0D\CC\A1\1C\C 2\81\1E\EAA\1E\CAa\1E\8050\07|\98\07y`\835h\87v\C0\076X\83y\98\87r`\835\98\87y(\079`\835\C0\07<\B8\03\80\A8\07w\98\87p0\87rh\03s \80\876h\87p\A0\07t\00\CC!\1C\D8a\1E\CA\01 \EAa\1E\CA\A1\0D\E6\E1\1D\CC\81\1E\DA\C0\1C\D8\E1\1D\C2\81\1E\00s\08\07v\98\87r\006\B 8\8C\F0\FF\FF\FF\FF\031\0E\EF \0F\F2P\0E\E3@\0F\EC\90\0Fm \0F\EFP\0F\EE@\0E\E5@\0Em@\0E\E9`\0F\E9@\0E\E5\D0\06\F3\10\0F\F2@\0Fm` \0E\F0\D0\06\ED\10\0E\F4\80\0E\809\84\03;\CCC9\00\049\A4\C3<\84\838\B0C9\B4\01=\84C:\B0C\1B\8CC8\B0\03;\CC\03`\0E\E1\C0\0E\F3P\0 E\00\C1\0E\E50\0F\F3\D0\06\F0 \0F\E50\0E\E90\0F\E5\D0\06\E6\00\0F\ED\10\0E\E4\00\98C8\B0\C3<\94\03@\B8\C3;\B4\819\C8C8\B4C9\B4\0 1<\BCC:\B8\03=\94\83<\B4A9\B0C:\B4\03@\0F\F2P\0F\E5\00\0C\EE\F0\0Em`\0E\F2\10\0E\EDP\0Em\00\0F\EF\90\0E\EE@\0F\E5 \0FmP\0E\EC\90 \0E\ED\D0\06\EE\F0\0E\EE\D0\06\ECP\0E\E1`\0E\00\E1\0E\EF\D0\06\E9\E0\0E\E60\0Fm`\0E\F0\D0\06\ED\10\0E\F4\80\0E\809\84\03;\CCC9\0 0\84;\BCC\1B\B8C8\B8\C3<\B4\819\C0C\1B\B4C8\D0\03:\00\E6\10\0E\EC0\0F\E5\00\10\EE\F0\0Em0\0F\E9p\0E\EEP\0E\E4\D0\06\FAP\0E\F2\F0 \0E\F3\D0\06\E6\00\0Fm\D0\0E\E1@\0F\E8\00\98C8\B0\C3<\94\03@\B8\C3;\B4\01=\C8C8\C0\03<\A4\83;\9CC\1B\B4C8\D0\03:\00\E6\10\0E\EC0 \0F\E5\00\10\F3@\0F\E10\0E\EB\D0\06\F0 \0F\EF@\0F\E50\0E\F4\F0\0E\F2\D0\06\E2P\0F\E6`\0E\E5 \0Fm0\0F\E9\A0\0F\E5\00\E0\01@\D0C8\ C8\C39\94\03=\B4\C18\C0C=\00\F8\80\07v\D0\06v@\07\00A\0F\E1 \0F\E7P\0E\F4\D0\06\E6P\0E\E1@\0F\F5 \0F\E50\0F\C0\1A\98\03>\CC\83<\ B0\C1\1A\B4C;\E0\03\1B\AC\C1<\CCC9\B0\C1\1A\CC\C3<\94\83\1C\B0\C1\1A\E0\03\1E\DC\01@\D4\83;\CCC8\98C9\B4\819\C0C\1B\B4C8\D0\03:\ 00\E6\10\0E\EC0\0F\E5\00\10\F50\0F\E5\D0\06\F3\F0\0E\E6@\0Fm`\0E\EC\F0\0E\E1@\0F\809\84\03;\CCC9\00\00\00I\18\00\00\02\00\00\00\ 13\82`B \00\00\00\89 \00\00\0E\00\00\002\22\08\09 d\85\04\13\22\A4\84\04\13\22\E3\84\A1\90\14\12L\88\8C\0B\84\84L\108s\04H\1E\00 E6\00\CD\1C\01\18\94\A0\C8\08\AAPH9\10@5\02\00\00\130|\C0\03;\F8\05;\A0\836\A8\07wX\07wx\87{p\876`\87tp\87z\C0\8768\07w\A8\87\0D
- 编译不添加-fembed-bitcode参数,即