windows环境下编译OLLVM并使用
编译环境及相关工具:
windows 64位 win10系统
内存16G CPU4核
MinGW
cmake
步骤
安装MinGW
MinGW下载地址选择MinGW-W64 GCC-8.1.0栏目下x86_64-posix-sjlj
下载完毕后将gcc所在的bin目录添加环境变量即可
其中posix版本使用的pthread是windows版本, 不同平台间移植成本更低, 但某些情况下性能可能会下降, win32使用的是windows原生线程库, 性能方面更出色
sjlj : 支持windows环境下的异常抛出, 同时性能开销也增大了, 该版本支持win32和win64
seh : 异常处理零开销, 该版本支持win64
dwarf : 首先, dwarf是一种可执行文件的格式, 类似与Linux下的elf, 该版本会将程序编译为dwarf格式的二进制文件安装cmake
拉取代码
1
2git clone -b llvm-4.0 https://github.com/obfuscator-llvm/obfuscator.git
md build修改代码
打开文件
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
这个报错开始编译
1
2
3cd build
cmake -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release -DLLVM_INCLUDE_TESTS=OFF ..
mingw32-make -j4处理报错
如果编译过程中出现了
OrcRemoteTargetClient.h:696:26: error: could not convert ***
, 找到这个文件, 将函数readMem的返回值由Expected<std::vector<char>>
修改为Expected<std::vector<uint8_t>>
编译完成
编译出来的可执行程序都位于build/bin目录内, 添加到环境变量后即可执行
clang --version
测试编译结果1
2
3Obfuscator-LLVM clang version 4.0.1 (based on Obfuscator-LLVM 4.0.1)
Target: x86_64-w64-windows-gnu
Thread model: posix测试
1
2
3
4
5
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
15CC=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)