开启ollvm所用编译器选项 -mllvm -[fla|sub|bcf]
平展控制流control flow flattening
#include <stdlib.h>
int main(int argc, char** argv) {
int a = atoi(argv[1]);
if(a == 0)
return 1;
else
return 10;
return 0;
}
经过平展得到下面的代码,其中所有基本块都被分割并放到无限循环中,由switch和变量b操作控制流
#include <stdlib.h>
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;
}
指令替换instruction substitution
替换为语义相同且更为复杂的的指令序列,这种混淆方法比较直接,且可能会在重优化时去除。如果使用不同的伪随机种子可以使生成的二进制不同,目前只支持整数操作,下面是例子:
减法: a = -(-b + (-c))
%0 = load i32* %a, align 4
%1 = load i32* %b, align 4
%2 = sub i32 0, %0
%3 = sub i32 0, %1
%4 = add i32 %2, %3
%5 = sub nsw i32 0, %4
r = rand (); a = b - r; a = a + b; a = a + r
%0 = load i32* %a, align 4
%1 = load i32* %b, align 4
%2 = sub i32 %0, 1108523271
%3 = add i32 %2, %1
%4 = add nsw i32 %3, 1108523271
与: a = b & c => a = (b ^ ~c) & b
%0 = load i32* %a, align 4
%1 = load i32* %b, align 4
%2 = xor i32 %1, -1
%3 = xor i32 %0, %2
%4 = and i32 %3, %0
伪造控制流bogus control flow
-perBCF=percent 以percent%的比率伪造代码
-boguscf-loop=num 在一个函数上重复伪造num次
-boguscf-prob=percent 基本块以percent%的伪造基本块
例子:
#include <stdlib.h>
int main(int argc, char** argv) {
int a = atoi(argv[1]);
if(a == 0)
return 1;
else
return 10;
return 0;
}
基本块拆分basic block splitting
Functionn annotations函数注释
fla/sub/bcf/spli/nofla/nosub/nobcf/nospli
如果需要混淆指定函数可以使用函数注释,以下定义用于混淆foo函数
int foo() __attribute((__annotate__(("fla"))));
int foo() {
return 2;
}
同样如果要制定禁止混淆某函数可以用相应的no-注释