windows环境编译OLLVM

windows环境下编译OLLVM并使用

编译环境及相关工具:

windows 64位 win10系统
内存16G CPU4核
MinGW
cmake

步骤

  1. 安装MinGW

    MinGW下载地址选择MinGW-W64 GCC-8.1.0栏目下x86_64-posix-sjlj
    下载完毕后将gcc所在的bin目录添加环境变量即可
    其中posix版本使用的pthreadwindows版本, 不同平台间移植成本更低, 但某些情况下性能可能会下降, win32使用的是windows原生线程库, 性能方面更出色
    sjlj : 支持windows环境下的异常抛出, 同时性能开销也增大了, 该版本支持win32和win64
    seh : 异常处理零开销, 该版本支持win64
    dwarf : 首先, dwarf是一种可执行文件的格式, 类似与Linux下的elf, 该版本会将程序编译为dwarf格式的二进制文件

  2. 安装cmake

    cmake github 下载地址
    cmake 官网下载地址

  3. 拉取代码

    1
    2
    git clone -b llvm-4.0 https://github.com/obfuscator-llvm/obfuscator.git
    md build
  4. 修改代码

    打开文件obfuscator\lib\Transforms\Obfuscation\CryptoUtils.cpp, 找到无参函数prng_seed, 注意这个文件中有两个prng_seed, 一个有参数, 一个没有参数, 需要修改的是无参的那个, 将函数注释掉, 添加以下代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    #include <windows.h>
    #include <wincrypt.h>
    bool CryptoUtils::prng_seed() {
    bool bRet = false;
    HCRYPTPROV Rnd;
    LPCSTR UserName = "MyKeyContainer";
    if(CryptAcquireContext(&Rnd, UserName, NULL, PROV_RSA_FULL, 0)) {
    bRet = true;
    } else {
    if (GetLastError() == NTE_BAD_KEYSET) {
    if(CryptAcquireContext(&Rnd, UserName, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET)) {
    } else {
    printf("Could not create a new key container.\n");
    bRet = false;
    }
    } else {
    printf("A cryptographic service handle could not be acquired.\n");
    bRet = false;
    }
    }
    if (bRet) {
    if (CryptGenRandom(Rnd, 4, (BYTE*)key)) {
    memset(ctr, 0, 16);
    aes_compute_ks(ks, key);
    seeded = true;
    bRet = true;
    }
    else {
    puts("Windows CryptGenRandom Error\n");
    bRet = false;
    }
    if (!CryptReleaseContext(Rnd,0))
    printf("ERROR : The handle could not be released.\n\n");
    }
    return bRet;
    }

    修改这个函数是为了避免Cannot open /dev/random这个报错

  5. 开始编译

    1
    2
    3
    cd build
    cmake -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release -DLLVM_INCLUDE_TESTS=OFF ..
    mingw32-make -j4
  6. 处理报错

    如果编译过程中出现了OrcRemoteTargetClient.h:696:26: error: could not convert ***, 找到这个文件, 将函数readMem的返回值由Expected<std::vector<char>>修改为Expected<std::vector<uint8_t>>

  7. 编译完成

    编译出来的可执行程序都位于build/bin目录内, 添加到环境变量后即可执行clang --version测试编译结果

    1
    2
    3
    Obfuscator-LLVM clang version 4.0.1  (based on Obfuscator-LLVM 4.0.1)
    Target: x86_64-w64-windows-gnu
    Thread model: posix
  8. 测试

    1
    2
    3
    4
    5
    #include <stdio.h>
    int main(int argc, char * argv[]) {
    printf("test ollvm\n");
    return 0;
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    CC=clang
    CFLAGS += -mllvm -sub -mllvm -sub_loop=3
    CFLAGS += -mllvm -bcf -mllvm -bcf_loop=3
    CFLAGS += -mllvm -bcf_prob=40
    CFLAGS += -mllvm -fla
    CFLAGS += -mllvm -split
    CFLAGS += -mllvm -split_num=3
    CFLAGS += -Wall -O1
    LDFLAGS=
    PROJECT=test.exe
    SRC=main.c
    all:
    $(CC) $(SRC) $(CFLAGS) $(LDFLAGS) -o $(PROJECT)
    clean:
    del $(PROJECT)