Home

Awesome

LLVM-YX-CALLOBFUSCATOR

LLVM plugin to transparently apply stack spoofing and indirect syscalls to Windows x64 native calls at compile time.

"I've 5 mins, what is this?"

This project is a plugin meant to be used with opt, the LLVM optimizer. Opt will use the pass included in this plugin to hook calls to Windows functions based on a config file and point those calls to a single function, which, given an ID identifying the function to be called, will apply dynamic stack obfuscation, and if the function is a syscall stub, will invoke it using "indirect syscalling".

Usage brief: Set up a config file indicating the functions to be hooked, write your C code without caring about Windows function calls, compile with clang to generate .ir files, give them to opt along with this plugin, opt hooks functions, llc compiles the .ir to a.obj, and ld links it to an executable that automatically obfuscates function calls.

Table of Contents

Setup

This instructions are written for Windows, but it should be possible to setup this environment in Linux easily (still output executables can only be built for Windows x64). Tested with LLVM 16.x and 17.x.

All the commands described in the following steps are supossed to be used in an MSYS2 terminal ie they have Linux format.

Usage and example

First of all, we need to set up our configuration file. In this section, we will be using the config file found in the ./example folder. You can add any number of functions to the file, and the functions do not need to appear in the program.

The plugin will get the path to the config file from an environment variable called LLVM_OBF_FUNCTIONS. You can either add it along with all the other environment variables for the user, the system, or just set it up for the current terminal. You can also set it from a makefile, if using one. To set the example config for the current terminal:

    export LLVM_OBF_FUNCTIONS=<absolute path to callobfuscator.conf>

Now it is time to run the pass. A more detailed explanation about every step can be found here.

NOTE: Any path in MYSYS2 must be written using / and not \

Now you should have ./build/example.exe, the final executable.

In case you are thinking that those are a lot of commands, well, they are always "the same", so writing makefiles helps, Im leaving a makefile example inside the example folder to compile the same code as before.

Developer guide

Thanks

To Arash Parsa, aka waldoirc, Athanasios Tserpelis, aka trickster0 and Alessandro Magnosi, aka klezVirus because of SilentMoonwalk


TODO:

This includes things that I really dont want to forget, but more stuff could be added here. Not by now

Docs/formatting:

Opsec:

General quality:

Functionality: