OLLVM混淆初始及环境搭建

发布时间 2023-07-07 20:28:18作者: Qsons

OLLVM混淆初识及环境搭建(Ubuntu22.04)

前言

前些日子在国赛华中分区赛上,碰到了蛮多OLLVM混淆的题目,当时用IDA的D-810没去掉,借此机会,学习学习OLLVM。

介绍:

OLLVM就不细讲了,需要了解的直接看

https://blog.quarkslab.com/deobfuscation-recovering-an-ollvm-protected-program.html

环境搭建:

我自己用的环境:

Ubuntu22.04,之前用来搭PWN的环境,2个U,内存4G,硬盘20G+10G(怕OLLVM构建项目时卡死,多分配点swap分区)

首先换国内源

  • cp /etc/apt/source.list /etc/apt/source.list.bak
  • vim /etc/apt/source.list
  • 然后换源,我自己换的是阿里源(因为cmake)

Ubuntu硬盘扩容:

注意,这里的扩容网上有很多教程,都没细说。

LLVM在进行交叉编译的时候会出现空间不足,或者swap分区占用100%的情况。所以我们需要进行扩容。

这里要分二步,先进行硬盘扩容然后进行swap分区扩容,确保

硬盘扩容

详细教程:https://blog.csdn.net/qq_34160841/article/details/113058756

这里我的硬盘一开始是20GB,而且之前装了PWN的环境,剩余的也不多,做了个扩容。

swap分区扩容

详细教程:https://www.linuxidc.com/Linux/2019-07/159580.htm#:~:text=如何在Ubuntu上增加swap交换空间 1 第2步:检查分区上的可用空间 2 第3步:在Ubuntu中创建swap文件 3,第4步:在Ubuntu中启用swap文件 4 第5步:在Ubuntu中永久挂载交换文件 5 第6步:调整Ubuntu中的交换设置 6 第7步:删除Ubuntu中的交换文件.

最终效果:

更新软件源

  • sudo apt update && sudo apt upgrade -y

安装gcc和g++的8.x版本以及cmake

安装cmake

  • sudo apt-get install cmake -y

安装gcc和g++

  • sudo apt-get install gcc-8
  • sudo apt-get install g++-8

调整gcc和g++的优先级

gcc的9.x版本是无法编译的,我们需要通过以下命令来调整gcc和g++的优先级

  • sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-8 8
    sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-8 8
    sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 9
    sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-9 9

查看gcc版本

  • gcc --version

查看g++版本

  • g++ --version

gcc切换版本,我们需要切换到gcc8

  • sudo update-alternatives --config gcc

g++切换版本,我们需要切换到g++8

  • sudo update-alternatives --config gcc

最终效果图

Git LLVM源码

提前安装git:

sudo apt install git

下载源码:

git clone -b llvm-4.0  https://github.com/obfuscator-llvm/obfuscator.git

踩坑的点:

需要对源码进行修改
vim ollvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h

有些人是把char改成了uint_8,这是错误的。

编译

先在obfuscator的同级的目录,创建build目录,命令如下:

mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_INCLUDE_TESTS=OFF ../obfuscator/
make
sudo make install 

如果出现卡死,多半是交叉编译时,内存不够引起的。

处理方法可以用make -j8.

编译成功了之后,我们就可以进行混淆了。

1、控制流扁平化

clang -mllvm -fla test.c -o test1

2、指令替换

clang -mllvm -sub test.c -o test2

3、控制流伪造

clang -mllvm -bcf test.c -o test

出现报错

原因是我需要到build/bin目录下,通过编译好的程序clang,进行OLLVM混淆。

练习代码:

#include <stdio.h>
#include <stdlib.h>

int encryptFunc(int inputNum_1,int inputNum_2){
    int tmpNum_1 = 666, tmpNum_2 = 888, tmpNum_3 = 777;
    return tmpNum_1 ^ tmpNum_2 + tmpNum_3 * inputNum_1 - inputNum_2;
}

int main(int argc,char *argv[]){

    int printNum = 55;
    if (argc > 1)
    {
        printNum = encryptFunc(printNum, atoi(argv[1]));
    }else{
        printNum = encryptFunc(printNum, argc);
    }
    
    printf("Hello OLLVM %d\r\n", printNum);

    return 0;
}

编译成功。

我们再用普通的GCC去编译这个程序,最后用IDA看一看。

最终效果

混淆后

混淆前

OLLVM用法:

参考链接:https://blog.csdn.net/weixin_51732593/article/details/126707046

踩坑日记:

构建项目时,在%96时出现报错

报错情况如下:

Consolidate compiler generated dependencies of target lli
[ 96%] Building CXX object tools/lli/CMakeFiles/lli.dir/lli.cpp.o
In file included from /media/babypwn/qqq/ollvm/obfuscator/include/llvm/CodeGen/LinkAllCodegenComponents.h:20,
                 from /media/babypwn/qqq/ollvm/obfuscator/tools/lli/lli.cpp:22:
/media/babypwn/qqq/ollvm/obfuscator/include/llvm/CodeGen/SchedulerRegistry.h: In constructor ‘llvm::RegisterScheduler::RegisterScheduler(const char*, const char*, llvm::RegisterScheduler::FunctionPassCtor)’:
/media/babypwn/qqq/ollvm/obfuscator/include/llvm/CodeGen/SchedulerRegistry.h:42:52: warning: cast between incompatible function types from ‘llvm::RegisterScheduler::FunctionPassCtor’ {aka ‘llvm::ScheduleDAGSDNodes* (*)(llvm::SelectionDAGISel*, llvm::CodeGenOpt::Level)’} to ‘llvm::MachinePassCtor’ {aka ‘void* (*)()’} [-Wcast-function-type]
   : MachinePassRegistryNode(N, D, (MachinePassCtor)C)
                                                    ^
In file included from /media/babypwn/qqq/ollvm/obfuscator/tools/lli/lli.cpp:30:
/media/babypwn/qqq/ollvm/obfuscator/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h: In member function ‘llvm::Expected<std::vector<char> > llvm::orc::remote::OrcRemoteTargetClient<ChannelT>::readMem(uint8_t*, llvm::JITTargetAddress, uint64_t)’:
/media/babypwn/qqq/ollvm/obfuscator/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h:696:26: error: could not convert ‘((llvm::orc::remote::OrcRemoteTargetClient<ChannelT>*)this)->callB<llvm::orc::remote::OrcRemoteTargetRPCAPI::ReadMem>(Src, Size)’ from ‘Expected<vector<unsigned char,allocator<unsigned char>>>’ to ‘Expected<vector<char,allocator<char>>>’
     return callB<ReadMem>(Src, Size);
            ~~~~~~~~~~~~~~^~~~~~~~~~~
In file included from /media/babypwn/qqq/ollvm/obfuscator/include/llvm/ADT/Twine.h:13,
                 from /media/babypwn/qqq/ollvm/obfuscator/include/llvm/ADT/Triple.h:13,
                 from /media/babypwn/qqq/ollvm/obfuscator/tools/lli/OrcLazyJIT.h:18,
                 from /media/babypwn/qqq/ollvm/obfuscator/tools/lli/lli.cpp:16:
/media/babypwn/qqq/ollvm/obfuscator/include/llvm/ADT/SmallVector.h: In instantiation of ‘void llvm::SmallVectorTemplateBase<T, true>::push_back(const T&) [with T = std::pair<void*, long unsigned int>]’:
/media/babypwn/qqq/ollvm/obfuscator/include/llvm/Support/Allocator.h:241:33:   required from ‘void* llvm::BumpPtrAllocatorImpl<AllocatorT, SlabSize, SizeThreshold>::Allocate(size_t, size_t) [with AllocatorT = llvm::MallocAllocator; long unsigned int SlabSize = 4096; long unsigned int SizeThreshold = 4096; size_t = long unsigned int]’
/media/babypwn/qqq/ollvm/obfuscator/include/llvm/MC/MCContext.h:548:44:   required from here
/media/babypwn/qqq/ollvm/obfuscator/include/llvm/ADT/SmallVector.h:309:11: warning: ‘void* memcpy(void*, const void*, size_t)’ writing to an object of type ‘struct std::pair<void*, long unsigned int>’ with no trivial copy-assignment; use copy-assignment or copy-initialization instead [-Wclass-memaccess]
     memcpy(this->end(), &Elt, sizeof(T));
     ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/8/utility:70,
                 from /media/babypwn/qqq/ollvm/obfuscator/include/llvm/ADT/iterator_range.h:22,
                 from /media/babypwn/qqq/ollvm/obfuscator/include/llvm/ADT/SmallVector.h:17,
                 from /media/babypwn/qqq/ollvm/obfuscator/include/llvm/ADT/Twine.h:13,
                 from /media/babypwn/qqq/ollvm/obfuscator/include/llvm/ADT/Triple.h:13,
                 from /media/babypwn/qqq/ollvm/obfuscator/tools/lli/OrcLazyJIT.h:18,
                 from /media/babypwn/qqq/ollvm/obfuscator/tools/lli/lli.cpp:16:
/usr/include/c++/8/bits/stl_pair.h:208:12: note: ‘struct std::pair<void*, long unsigned int>’ declared here
     struct pair
            ^~~~
In file included from /media/babypwn/qqq/ollvm/obfuscator/include/llvm/ADT/Twine.h:13,
                 from /media/babypwn/qqq/ollvm/obfuscator/include/llvm/ADT/Triple.h:13,
                 from /media/babypwn/qqq/ollvm/obfuscator/tools/lli/OrcLazyJIT.h:18,
                 from /media/babypwn/qqq/ollvm/obfuscator/tools/lli/lli.cpp:16:
/media/babypwn/qqq/ollvm/obfuscator/include/llvm/ADT/SmallVector.h: In instantiation of ‘static void llvm::SmallVectorTemplateBase<T, true>::uninitialized_copy(T1*, T1*, T2*, typename std::enable_if<std::is_same<typename std::remove_const<T1>::type, T2>::value>::type*) [with T1 = const std::pair<const llvm::MCSymbol*, const llvm::MCSymbol*>; T2 = std::pair<const llvm::MCSymbol*, const llvm::MCSymbol*>; T = std::pair<const llvm::MCSymbol*, const llvm::MCSymbol*>; typename std::enable_if<std::is_same<typename std::remove_const<T1>::type, T2>::value>::type = void]’:
/media/babypwn/qqq/ollvm/obfuscator/include/llvm/ADT/SmallVector.h:399:5:   required from ‘void llvm::SmallVectorImpl<T>::append(in_iter, in_iter) [with in_iter = const std::pair<const llvm::MCSymbol*, const llvm::MCSymbol*>*; T = std::pair<const llvm::MCSymbol*, const llvm::MCSymbol*>]’
/media/babypwn/qqq/ollvm/obfuscator/include/llvm/ADT/SmallVector.h:858:5:   required from ‘llvm::SmallVector<T, N>::SmallVector(ItTy, ItTy) [with ItTy = const std::pair<const llvm::MCSymbol*, const llvm::MCSymbol*>*; T = std::pair<const llvm::MCSymbol*, const llvm::MCSymbol*>; unsigned int N = 2]’
/media/babypwn/qqq/ollvm/obfuscator/include/llvm/MC/MCFragment.h:546:42:   required from here
/media/babypwn/qqq/ollvm/obfuscator/include/llvm/ADT/SmallVector.h:296:13: warning: ‘void* memcpy(void*, const void*, size_t)’ writing to an object of type ‘struct std::pair<const llvm::MCSymbol*, const llvm::MCSymbol*>’ with no trivial copy-assignment; use copy-assignment or copy-initialization instead [-Wclass-memaccess]
       memcpy(Dest, I, (E - I) * sizeof(T));
       ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/8/utility:70,
                 from /media/babypwn/qqq/ollvm/obfuscator/include/llvm/ADT/iterator_range.h:22,
                 from /media/babypwn/qqq/ollvm/obfuscator/include/llvm/ADT/SmallVector.h:17,
                 from /media/babypwn/qqq/ollvm/obfuscator/include/llvm/ADT/Twine.h:13,
                 from /media/babypwn/qqq/ollvm/obfuscator/include/llvm/ADT/Triple.h:13,
                 from /media/babypwn/qqq/ollvm/obfuscator/tools/lli/OrcLazyJIT.h:18,
                 from /media/babypwn/qqq/ollvm/obfuscator/tools/lli/lli.cpp:16:
/usr/include/c++/8/bits/stl_pair.h:208:12: note: ‘struct std::pair<const llvm::MCSymbol*, const llvm::MCSymbol*>’ declared here
     struct pair
            ^~~~
make[2]: *** [tools/lli/CMakeFiles/lli.dir/build.make:76:tools/lli/CMakeFiles/lli.dir/lli.cpp.o] 错误 1
make[1]: *** [CMakeFiles/Makefile2:18697:tools/lli/CMakeFiles/lli.dir/all] 错误 2
make: *** [Makefile:156:all] 错误 2

原因

ollvm/include/llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h的690行,只改了一个char,没有全部改掉

解决方法:

两个char都改为uint8_t
重新make或者make -j8
-j,相当于调用多线程进行编译,速度更快,前提是你内存够,不然容易卡死,导致报错

参考链接: