To obfuscate your program with Tigress first include the tigress.h file supplied in the Tigress distribution directory, and then invoke Tigress specifying at least one transformation applied to at least one function. Here is a trivial example where Tigress is flattening the function bar in the program foo.c:
#include "PATH-TO-TIGRESS-INSTALLATION/tigress.h"
void bar () {
...
}
int main () {
...
}
tigress \
--Environment=x86_64:Linux:Gcc:4.6 \
--Transform=Flatten \
--Functions=bar \
--out=foo_out.c foo.c
Command line options. These are some useful Tigress command line options:
*) tigress --help : Show this message
*) tigress --install : Show how to install Tigress
*) tigress --license : Display the tigress license
*) tigress --bugs : How to get past some known issues
*) tigress --version : Show the current Tigress version
Multiple Input Files. Note that Tigress accepts exactly one C file as input. This is so that Tigress can do whole-program analysis and transformations. If your project has multiple files you must first merge them together into one. Tigress (through the CIL library on which it is built) allows you to merge your source files automatically. For complex scenarios, see the CIL information page about merging. For simple cases, all you have to do to merge two files file1.c and file2.c into full.c, is to call the tigress-merge program like this:
$ tigress-merge file1.c file2.c --out=full.c
Cross-compilation and 32-vs-64-bit machine models. By default, we assume you're generating code for the machine on which you execute Tigress. If this is not the case, in particular, if your target machine has a different wordsize than the one you compile on, you must run Tigress with the --envmachine option and set the CIL_MACHINE environment variable with the relevant C type sizes. For the current version of Tigress, this is really only relevant for the virtualize transformation. See the CIL documentation for more information.
If you want to use a specific compiler (other than the default gcc) you can use the --gcc=command to tell cilly which compiler to use, for example --gcc=arm-elf-gcc.
Here's an example of how to set CIL_MACHINE for a typical 32-bit target:
CIL_MACHINE="short=2,2 int=4,4 long=4,4 long_long=8,8 pointer=4,4 \
alignof_enum=4 float=4,4 double=8,8 long_double=12,12 \
void=1 bool=1,1 fun=1,1 alignof_string=1 max_alignment=16 \
size_t=unsigned_int wchar_t=int char_signed=true \
const_string_literals=true big_endian=false \
__thread_is_keyword=true __builtin_va_list=true \
underscore_name=true"; export CIL_MACHINE;
Generating CIL_MACHINE. You can generate CIL_MACHINE automatically. Look for the file machdep-ml.c in the Tigress distribution directory. Compile and run as shown below. You have to provide the compiler you're using, as well as the types of size_t and wide characters as these are not yet auto-detected. You need to run this on your target machine (i.e. the one you're cross-compiling for).
> gcc -D_GNUCC \
-DTYPE_SIZE_T="\"unsigned long\"" \
-DTYPE_WCHAR_T=\"int\" machdep-ml.c -o machdep-ml
> ./machdep-ml --env | grep -v Generating
short=2,2 int=4,4 long=8,8 .... underscore_name=true
WebAssembly: Below is an example of how to first obfuscate a C program foo_in.c with Tigress, and then compile the obfuscated file foo_obf.c with Emscripten to a WebAssembly/html/Javascript package. Note the use of the CIL_MACHINE environment variable and the --envmachine argument to Tigress; these specify that the word size of the target machine (WASM) is different from that of the machine of which Tigress is run. Notice also the --gcc=emcc argument to Tigress. This specifies that the WebAssembly compiler (emcc) should be used, rather than the native C compiler.
export EMSDKPATH=PATH-TO-EMCC-INSTALLATION/emsdk/emscripten/1.38.29/system/include/
export CIL_MACHINE="short=2,2 int=4,4 long=4,4 long_long=8,8 pointer=4,4 alignof_enum=4 float=4,4 \
double=8,8 long_double=8,8 void=1 bool=1,1 fun=1,4 alignof_string=1 max_alignment=16 \
size_t=unsigned_long wchar_t=int char_signed=true const_string_literals=true \
big_endian=false __thread_is_keyword=true __builtin_va_list=true underscore_name=true"
tigress \
--gcc=emcc \
--envmachine \
-D _Float128=double \
-I $EMSDKPATH \
--Environment=x86_64:Linux:Gcc:4.6 \
--Transform=Flatten \
--Functions=bar \
--out=foo_obf.c foo_in.c
emcc \
-I $EMSDKPATH \
-O2 \
foo_obf.c \
-o foo_wasm.html \
-s WASM=1 \
-s ALLOW_MEMORY_GROWTH=1 \
-s AGGRESSIVE_VARIABLE_ELIMINATION=1 \
-s ERROR_ON_UNDEFINED_SYMBOLS=0 \
-s USE_WEBGL2=1 \
-s USE_GLFW=3 \
-s FULL_ES3=1 \
-fmacro-backtrace-limit=0
WebAssembly (From Version 3.3): Starting with Tigress version 3.3 and emscripten v. 14, it's easier to obfuscate for webassembly:
EMSDKPATH=PATH_TO_EMSDK_INSTALLATION/emsdk/upstream/include/c++/v1
> tigress \
--Environment=wasm:Linux:Emcc:4.6 \
--Transform=Flatten --Functions=fib \
--out=obf.c foo.c
> emcc \
-I $EMSDKPATH \
-O2 \
obf.c \
--emrun \
-o wasm.html \
-s WASM=1 \
-s ASSERTIONS=1 \
-s ALLOW_MEMORY_GROWTH=1 \
-s AGGRESSIVE_VARIABLE_ELIMINATION=1 \
-s ERROR_ON_UNDEFINED_SYMBOLS=0 \
-s USE_WEBGL2=0 \
-s USE_GLFW=3 \
-s FULL_ES3=0 \
-fmacro-backtrace-limit=0
> emrun --browser safari wasm.html
Android: Tigress has not been extensively tested on Android, but the following commands seem to work. Download the Android NDK from https://developer.android.com/ndk/downloads. Create the following shell script, name it "compiler", and set the target to the platform for which you want to compile:
#!/bin/sh
./toolchains/llvm/prebuilt/darwin-x86_64/bin/clang -target aarch64-none-linux-android21 "$@"
If you're not on OSX, you need to replace darwin-x86_64 with the appropriate path. Set CIL_MACHINE to the appropriate value for your target (depending on if it is a 32 or 64 bit architecture). Assuming you have two files foo.c and bar.c, issue these commands to merge them into out.c and obfuscate them into obf.c:
> cd android-ndk-r20b
> chmod a+rx ./compiler
> CIL_MACHINE="short=2,2 int=4,4 long=4,4 ...; export CIL_MACHINE;
> tigress-merge --Environment=x86_64:Linux:Gcc:4.6 --envmachine --gcc=./compiler foo.c bar.c --out=out.c
> tigress --Environment=x86_64:Linux:Gcc:4.6 --envmachine --gcc=./compiler --Transform=Flatten --Functions=fib out.c --out=obf.c