eshard / obfuscator-llvm

Other
223 stars 42 forks source link

Obfuscation not being applied #10

Closed HakonHarnes closed 1 year ago

HakonHarnes commented 1 year ago

I'm successful in building LLVM and the obfuscation plugin, however I'm unable to apply the obfuscation passes. What am I missing here?

main.c

#include <stdlib.h>
int main(int argc, char** argv) {
  int a = atoi(argv[1]);
  if(a == 0)
    return 1;
  else
    return 10;
  return 0;
}

(https://github.com/heroims/obfuscator/wiki/Bogus-Control-Flow)

Compile without obfuscation

clang main.c -o main

Compile with obfuscation

export LLVM_OBF_SCALAROPTIMIZERLATE_PASSES="flattening, bogus, substitution, split-basic-blocks"
clang  -fno-legacy-pass-manager -fpass-plugin=/obfuscator-llvm/build/libLLVMObfuscator.so main.c -o obf

Compare binaries

diff main obf 

Binaries are the same. I've also tried:

export LLVM_OBF_PEEPHOLE_PASSES="flattening, bogus, substitution, split-basic-blocks"
export LLVM_OBF_SCALAROPTIMIZERLATE_PASSES="flattening, bogus, substitution, split-basic-blocks"
export LLVM_OBF_VECTORIZERSTART_PASSES="flattening, bogus, substitution, split-basic-blocks"
export LLVM_OBF_PIPELINESTART_PASSES="flattening, bogus, substitution, split-basic-blocks"
export LLVM_OBF_PIPELINEEARLYSIMPLIFICATION_PASSES="flattening, bogus, substitution, split-basic-blocks"
export LLVM_OBF_OPTIMIZERLASTEP_PASSES="flattening, bogus, substitution, split-basic-blocks"
clang  -fno-legacy-pass-manager -fpass-plugin=/obfuscator-llvm/build/libLLVMObfuscator.so main.c -o obf

Still, obfuscation is not applied.

Dockerfile

FROM archlinux

RUN pacman -Syu --needed base-devel --noconfirm

RUN pacman -S vim git cmake ninja python3 --noconfirm

RUN git clone --depth 1 --branch release/14.x https://github.com/llvm/llvm-project.git

WORKDIR /llvm-project/llvm

RUN mkdir -p build

WORKDIR /llvm-project/llvm/build

RUN cmake -G "Ninja" -DCMAKE_INSTALL_PREFIX=/opt/llvm -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS='lld;clang' -DLLVM_TARGETS_TO_BUILD="host;WebAssembly" -DLLVM_INCLUDE_EXAMPLES=OFF -DLLVM_INCLUDE_TESTS=OFF -DENABLE_LLVM_SHARED=1 ..

RUN ninja -j$(($(nproc) / 2))

RUN ninja install

WORKDIR /

RUN git clone https://github.com/eshard/obfuscator-llvm.git

WORKDIR /obfuscator-llvm

RUN sed -i 's/ LLVMCore//' CMakeLists.txt

RUN mkdir -p build

WORKDIR /obfuscator-llvm/build

RUN cmake -G "Ninja" -DLLVM_DIR=/opt/llvm/lib/cmake ..

RUN ninja -j$(($(nproc) / 2))

ENV PATH="$PATH:/llvm-project/llvm/build/bin"

WORKDIR /
PatriceBlin commented 1 year ago

The passes ENV variables doesn't accept spaces between ,

HakonHarnes commented 1 year ago

The passes ENV variables doesn't accept spaces between ,

I'll give it a try! We should probably update the README. It uses spaces between ,.

HakonHarnes commented 1 year ago

Hmm, doesn't seem to resolve the issue for me. Here's what I've tried:

export LLVM_OBF_OPTIMIZERLASTEP_PASSES="flattening,bogus,substitution,split-basic-blocks"
clang  -fno-legacy-pass-manager -fpass-plugin=/obfuscator-llvm/build/libLLVMObfuscator.so main.c -o obf
export LLVM_OBF_OPTIMIZERLASTEP_PASSES="flattening,bogus,substitution,split-basic-blocks"
clang -fpass-plugin=/obfuscator-llvm/build/libLLVMObfuscator.so main.c -o obf
export LLVM_OBF_OPTIMIZERLASTEP_PASSES="flattening"
clang  -fno-legacy-pass-manager -fpass-plugin=/obfuscator-llvm/build/libLLVMObfuscator.so main.c -o obf

It does seem like the plugin is being invoked, since:

export LLVM_OBF_DEBUG_SEED="y"
clang -fpass-plugin=/obfuscator-llvm/build/libLLVMObfuscator.so main.c -o obf

Gives:

SEED = 0xEF0E14E9BFCD370DBB4396B84B7FD670

What could be the issue here?

Edit: Adding print statements to the addPassWithName in Plugin.cpp I can see that all of the obfuscations passes are being applied. However, there is still no difference in the between the original and obfuscated binaries.

PatriceBlin commented 1 year ago

Hi again,

I didn't noticed but you need to apply optimization options (at least -01to trigger the passes with a pass plugin). When using clang, without any -O the passes are not applied.
This is not the case with opt command if I remember correctly.

# clang Install
PATH="./install-llvm/14/bin:$PATH" clang --version
custom clang version 14.0.6 (https://github.com/llvm/llvm-project.git f28c006a5895fc0e329fe15fead81e37457cb1d1)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /mnt/llvm/./install-llvm/14/bin

# Compiling with clang and without optimizations
PATH="./install-llvm/14/bin:$PATH" clang src-github-issues/issue-10.c -o /tmp/issue-10_original_no_opts

# Compiling with clang with -O1
PATH="./install-llvm/14/bin:$PATH" clang -O1 src-github-issues/issue-10.c -o /tmp/issue-10_original_opts

# Compiling with clang without optimizations and the plugin/passes
PATH="./install-llvm/14/bin:$PATH" LLVM_OBF_SCALAROPTIMIZERLATE_PASSES="flattening,bogus,substitution,split-basic-blocks" clang -fno-legacy-pass-manager -fpass-plugin=b
uild-ollvm/libLLVMObfuscator.so src-github-issues/issue-10.c -o /tmp/issue-10_obfuscated_no_opts

# Compiling with clang with -O1 and the plugin/passes
PATH="./install-llvm/14/bin:$PATH" LLVM_OBF_SCALAROPTIMIZERLATE_PASSES="flattening,bogus,substitution,split-basic-blocks" clang -O1 -fno-legacy-pass-manager -fpass-plugin=build-ollvm/libLLVMObfuscator.so src-github-issues/issue-10.c -o /tmp/issue-10_obfuscated_opts

Comparing the differences

ls /tmp/issue-10* -al
-rwxr-xr-x 1 test test  16512 Mar 21 14:37 /tmp/issue-10_obfuscated_no_opts
-rwxr-xr-x 1 test test  16568 Mar 21 14:37 /tmp/issue-10_obfuscated_opts
-rwxr-xr-x 1 test test  16512 Mar 21 14:36 /tmp/issue-10_original_no_opts
-rwxr-xr-x 1 test test  16520 Mar 21 14:36 /tmp/issue-10_original_opts

As you can see /tmp/issue-10_original_no_opts and /tmp/issue-10_original_no_opts are the same

diff -u /tmp/issue-10_original_no_opts /tmp/issue-10_obfuscated_no_opts

When compiling with clang you need to enable optimizations to force use of the plugin.

Edit: ... and -O1 was missing in the README ... sorry

HakonHarnes commented 1 year ago

Thank you! It works now.