03-ollvm相关-Pass移植-将ollvm移植到llvm源码中

移植ollvm

OLLVM项目代码在 https://github.com/obfuscator-llvm/obfuscator

github中,ollvm是基于llvm4.0进行开发的,下图中 initial LLVM and Clang4.0是llvm原始的代码,其他的都是ollvm修改的代码,我们需要把这些修改的代码,复制到自己llvm项目中。

在这里插入图片描述

需要修改的内容如下

ollvm4.0llvm-project-9.0.1
1obfuscator/include/llvm/Transforms/Obfuscation/llvm-project-9.0.1/llvm/include/llvm/Transforms/Obfuscation
2obfuscator/include/llvm/CryptoUtils.hllvm-project-9.0.1/llvm/include/llvm/CryptoUtils.h(这个有位置点问题)
3obfuscator/lib/Transforms/Obfuscation/llvm-project-9.0.1/llvm/lib/Transforms/Obfuscation
4obfuscator/lib/Transforms/CMakeLists.txt
5obfuscator/lib/Transforms/LLVMBuild.txt
6obfuscator/lib/Transforms/IPO/LLVMBuild.txt
7obfuscator/lib/Transforms/IPO/PassManagerBuilder.cpp
8obfuscator/lib/Transforms/Obfuscation/Flattening.cpp
9obfuscator/lib/Transforms/Obfuscation/BogusControlFlow.cpp
make LLVMObfuscation
make clang
10fix some bug #76https://github.com/obfuscator-llvm/obfuscator/pull/76/files

1、将项1、2、3、指定的文件或者目录复制到对应的位置

2、修改内容

4)obfuscator/lib/Transforms/CMakeLists.txt

add_subdirectory(Obfuscation)

在这里插入图片描述

5)obfuscator/lib/Transforms/LLVMBuild.txt

[common]
subdirectories = AggressiveInstCombine Coroutines IPO InstCombine Instrumentation Scalar Utils Vectorize ObjCARC TestEncodeFuncName Obfuscation

在这里插入图片描述

6)obfuscator/lib/Transforms/IPO/LLVMBuild.txt

required_libraries 中添加 Obfuscation

7)obfuscator/lib/Transforms/IPO/PassManagerBuilder.cpp
添加头文件

#include "llvm/Transforms/Obfuscation/BogusControlFlow.h"
#include "llvm/Transforms/Obfuscation/Flattening.h"
#include "llvm/Transforms/Obfuscation/Split.h"
#include "llvm/Transforms/Obfuscation/Substitution.h"
#include "llvm/CryptoUtils.h"

添加代码 参考 https://github.com/obfuscator-llvm/obfuscator/blob/llvm-4.0/lib/Transforms/IPO/PassManagerBuilder.cpp
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

8)obfuscator/lib/Transforms/Obfuscation/Flattening.cpp
导入头文件
在这里插入图片描述

9)obfuscator/lib/Transforms/Obfuscation/BogusControlFlow.cpp
在这里插入图片描述

尝试编译
make LLVMObfuscation
make clang
能编译通过说明代码移植没有啥问题了

下面修复ollvm自身的bug

https://github.com/obfuscator-llvm/obfuscator/pull/76/files

编译

make LLVMObfuscation

make clang 应该是代码没有啥问题的(还是有问题、但是当前没影响、之后有影响的时候再进行修改)

ollvm有哪些功能

  • 指令替换
  • 虚假流程
  • 控制流程平坦化
  • 函数属性(指示llvm是否对函数进行混淆、进行那种混淆)

指令替换

比方:当有一个变量 a

进行指令替换: a = b - (-c) ,将指令替换为更加复杂的方式

对于IDA F5插件的功能,可以将 a = b -(-c) 和 a = -(-b + (-c)) 全局静态变量进行优化

当时,当指令替换中存在随机数时、无法进行优化。看看ollvm的指令替换功能。

#include<stdio.h>
int main(int argc,char** argv)
{
	int n = argc + 8;
	if(n >= 10)
	{
		printf("hello ollvm:%d\r\n",n);
	}else{
		printf("hello show me\r\n");
	}
	
	return 0;
}

设置环境变量、并仅编译一个可执行文件,看看clang和代码是否正常

export PATH=/home/me/workspace/llvm-project/llvm/cmake-build-debug/bin:$PATH

clang hello_ollvm.c -o hello_ollvm

先看看clang编译上面的代码时、最原始的中间文件

clang -emit-llvm -S multiply.c -o multiply.ll
; ModuleID = 'multiply.c'
source_filename = "multiply.c"
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.16.0"

; Function Attrs: noinline nounwind optnone ssp uwtable
define i32 @main(i32 %argc, i8** %argv) #0 {
entry:
  %retval = alloca i32, align 4
  %argc.addr = alloca i32, align 4
  %argv.addr = alloca i8**, align 8
  %a = alloca i32, align 4
  store i32 0, i32* %retval, align 4
  store i32 %argc, i32* %argc.addr, align 4
  store i8** %argv, i8*** %argv.addr, align 8
  %0 = load i32, i32* %argc.addr, align 4
  %add = add nsw i32 %0, 10
  store i32 %add, i32* %a, align 4
  %1 = load i32, i32* %a, align 4
  %cmp = icmp sge i32 %1, 10
  br i1 %cmp, label %if.then, label %if.end

if.then:                                          ; preds = %entry
  store i32 11, i32* %a, align 4
  br label %if.end

if.end:                                           ; preds = %if.then, %entry
  ret i32 0
}

默认的指令替换

clang -mllvm -sub -emit-llvm -S multiply.c -o multiply.ll
define i32 @main(i32 %argc, i8** %argv) #0 {
entry:
  %retval = alloca i32, align 4
  %argc.addr = alloca i32, align 4
  %argv.addr = alloca i8**, align 8
  %a = alloca i32, align 4
  store i32 0, i32* %retval, align 4
  store i32 %argc, i32* %argc.addr, align 4
  store i8** %argv, i8*** %argv.addr, align 8
  %0 = load i32, i32* %argc.addr, align 4
  %1 = sub i32 %0, 130102393
  %2 = add i32 %1, 10
  %3 = add i32 %2, 130102393
  %add = add nsw i32 %0, 10
  store i32 %3, i32* %a, align 4
  %4 = load i32, i32* %a, align 4
  %cmp = icmp sge i32 %4, 10
  br i1 %cmp, label %if.then, label %if.end

if.then:                                          ; preds = %entry
  store i32 11, i32* %a, align 4
  br label %if.end

if.end:                                           ; preds = %if.then, %entry
  ret i32 0
}

可以增加 指令替换的复杂度

clang -mllvm -sub -emit-llvm -mllvm -sub_loop=3 -S multiply.c -o multiply_sub_3.ll
; Function Attrs: noinline nounwind optnone ssp uwtable
define i32 @main(i32 %argc, i8** %argv) #0 {
entry:
  %retval = alloca i32, align 4
  %argc.addr = alloca i32, align 4
  %argv.addr = alloca i8**, align 8
  %a = alloca i32, align 4
  store i32 0, i32* %retval, align 4
  store i32 %argc, i32* %argc.addr, align 4
  store i8** %argv, i8*** %argv.addr, align 8
  %0 = load i32, i32* %argc.addr, align 4
  %1 = sub i32 0, -1990704939
  %2 = add i32 0, %1
  %3 = sub i32 0, -1990704939
  %4 = sub i32 0, 10
  %5 = add i32 %2, %4
  %6 = sub i32 %2, 10
  %7 = sub i32 0, -1990704939
  %8 = sub i32 %5, %7
  %9 = add i32 %5, -1990704939
  %10 = sub i32 0, 1617860029
  %11 = sub i32 %10, 10
  %12 = add i32 %11, 1617860029
  %13 = sub i32 0, 10
  %14 = sub i32 %0, -1578002009
  %15 = sub i32 %14, -510241612
  %16 = add i32 %15, -1578002009
  %17 = sub i32 %0, -510241612
  %18 = sub i32 0, %8
  %19 = add i32 %16, %18
  %20 = sub i32 %16, %8
  %21 = add i32 %19, -426374699
  %22 = add i32 %21, -510241612
  %23 = sub i32 %22, -426374699
  %24 = add i32 %19, -510241612
  %25 = add i32 %0, 76155044
  %26 = sub i32 %25, %8
  %27 = sub i32 %26, 76155044
  %28 = sub i32 %0, %8
  %29 = sub i32 0, -1106340572
  %30 = add i32 %0, %29
  %31 = sub i32 %0, -1106340572
  %32 = sub i32 %30, 1721883602
  %33 = add i32 %32, 10
  %34 = add i32 %33, 1721883602
  %35 = add i32 %30, 10
  %36 = sub i32 0, -1106340572
  %37 = sub i32 %34, %36
  %38 = add i32 %34, -1106340572
  %39 = sub i32 0, %0
  %40 = sub i32 0, 10
  %41 = add i32 %39, %40
  %42 = sub i32 0, %41
  %add = add nsw i32 %0, 10
  store i32 %23, i32* %a, align 4
  %43 = load i32, i32* %a, align 4
  %cmp = icmp sge i32 %43, 10
  br i1 %cmp, label %if.then, label %if.end

if.then:                                          ; preds = %entry
  store i32 11, i32* %a, align 4
  br label %if.end

if.end:                                           ; preds = %if.then, %entry
  ret i32 0
}

虚假流程

使用如下的代码演示、执行之后的指令自己查看区别

int main(int argc, char** argv) {
  int a = argc + 8;
  if(a == 0)
    return 1;
  else
    return 10;
  return 0;
}

clang -emit-llvm -S bcf.c -o bcf.ll

clang -emit-llvm -mllvm -bcf -S bcf.c -o bcf_bcf.ll

clang -emit-llvm -mllvm -bcf -mllvm -bcf_loop=3 -S bcf.c -o bcf_bcf_3.ll

clang -emit-llvm -mllvm -bcf -mllvm -bcf_loop=3 -mllvm -bcf_prob=80 -S bcf.c -o bcf_bcf_3_prob.ll

控制流程平坦化

使用的代码还是虚假流程的代码

需要修改一下代码,在lib/Transforms/Obfuscation/Flattening.cpp 文件中,注释下面的行

#include <llvm/Transforms/Utils.h>

  FunctionPass *lower = createLowerSwitchPass();
  lower->runOnFunction(*f);

在lib/Transforms/IPO/PassManagerBuilder.cpp 文件中,添加如下的内容

  MPM.add(createSplitBasicBlock(Split));
  MPM.add(createBogus(BogusControlFlow));
  // TODO 添加的内容
  if(Flattening){
    MPM.add(createLowerSwitchPass());
  }
  MPM.add(createFlattening(Flattening));

clang -emit-llvm -mllvm -fla -S fla.c -o fla_fla.ll

; Function Attrs: noinline nounwind optnone ssp uwtable
define i32 @main(i32 %argc, i8** %argv) #0 {
entry:
  %.reg2mem = alloca i32
  %retval = alloca i32, align 4
  %argc.addr = alloca i32, align 4
  %argv.addr = alloca i8**, align 8
  %a = alloca i32, align 4
  store i32 0, i32* %retval, align 4
  store i32 %argc, i32* %argc.addr, align 4
  store i8** %argv, i8*** %argv.addr, align 8
  %0 = load i32, i32* %argc.addr, align 4
  %add = add nsw i32 %0, 8
  store i32 %add, i32* %a, align 4
  %1 = load i32, i32* %a, align 4
  store i32 %1, i32* %.reg2mem
  %switchVar = alloca i32
  store i32 637648687, i32* %switchVar
  br label %loopEntry

loopEntry:                                        ; preds = %entry, %loopEnd
  %switchVar1 = load i32, i32* %switchVar
  switch i32 %switchVar1, label %switchDefault [
    i32 637648687, label %first
    i32 972343720, label %if.then
    i32 1878977632, label %if.else
    i32 1565953112, label %return
  ]

switchDefault:                                    ; preds = %loopEntry
  br label %loopEnd

first:                                            ; preds = %loopEntry
  %.reload = load volatile i32, i32* %.reg2mem
  %cmp = icmp eq i32 %.reload, 0
  %2 = select i1 %cmp, i32 972343720, i32 1878977632
  store i32 %2, i32* %switchVar
  br label %loopEnd

if.then:                                          ; preds = %loopEntry
  store i32 1, i32* %retval, align 4
  store i32 1565953112, i32* %switchVar
  br label %loopEnd

if.else:                                          ; preds = %loopEntry
  store i32 10, i32* %retval, align 4
  store i32 1565953112, i32* %switchVar
  br label %loopEnd

return:                                           ; preds = %loopEntry
  %3 = load i32, i32* %retval, align 4
  ret i32 %3

loopEnd:                                          ; preds = %if.else, %if.then, %first, %switchDefault
  br label %loopEntry
}

函数属性

只看看这个属性怎么用就行了,可以自己到源码里看

#include<stdlib.h>
int foo() __attribute((__annotate__(("fla")))); // 会进行fla的混淆
int foo()
{
	return 2;
}

int bbb() __attribute((__annotate__(("nofla"))));   // 不会进行fla的混淆
int bbb()
{
	return 2;
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值