Tigress is a diversifying virtualizer/obfuscator for the C language that supports many defenses against both static and dynamic reverse engineering and de-virtualization attacks. Tigress is a source-to-source transformer - it takes a C source program as input and returns a new C program as output. An obfuscation script (actually, a long sequence of command line options) describes the sequences of transformations that should be applied to the functions of the program:

Here is an example of how to transform a function bar in a program foo.c using Tigress. The first transformation flattens the code, the second turns the flattened function into an interpreter:

tigress --Verbosity=1 --Environment=x86_64:Linux:Gcc:4.6 --Seed=42 \
   --Transform=Flatten \
      --Functions=bar \
      --FlattenDispatch=switch \
      --FlattenObfuscateNext=false \
      --FlattenRandomizeBlocks=true \
      --FlattenConditionalKinds=branch,compute,flag \
      --FlattenImplicitFlowNext=true \
   --Transform=Virtualize \
      --Functions=bar \
      --VirtualizeDispatch=direct \
   --Transform=CleanUp \
       --CleanUpKinds=annotations,constants,names \
   --out=foo_out.c foo.c

Design. Tigress is built in OCaml (about 83,000 lines of code) and C (about 9000 lines) on top of two libraries: CIL (a C front end) and MyJit (a run-time code generator):


Tigress supports all of the C99 language, including gcc extensions. The source-to-source design means that the transformed code can be easily examined, which is useful in a pedagogical setting. Also, Tigress' output, once compiled and stripped of symbols, is a good target for reverse engineering and de-virtualization exercises.

Availability. Tigress has been used both for academic and commercial projects. You can try out Tigress by downloading and installing the binary from our website. If you like what Tigress does and decide to use it in a commercial project, you will need a license from the University of Arizona. We regularly share the source code with academics (because we believe code sharing is good). In both cases, contact us.

Transformations. Tigress protects against static de-virtualization by generating virtual instruction sets of arbitrary complexity and diversity, by producing interpreters with multiple types of instruction dispatch, and by inserting code for anti alias analysis. Tigress protects against dynamic de-virtualization by merging the real code with bogus functions, by inserting implicit flow, and by creating slowly-executing reentrant interpreters. Tigress implements its own version of code packing through the use of runtime code generation. Finally, Tigress' dynamic transformation provides a generalized form of continuous runtime code modification.

Diversity. Tigress is designed such that, from a single source program, it is possible to generate large numbers of highly diversified variants. This diversity is both static and dynamic, i.e. two variants will differ both in their machine code and in the resulting instruction traces. In essence, every decision Tigress makes is dependent on a randomization seed, controllable by the user. There are two major sources of diversity:

  1. Tigress goes to great lengths to provide as many variants of each transformation as possible. For example, our virtualization transformation supports eight kinds of dispatch, can generate arbitrarily complex virtual instruction sets, and can generate instructions which arbitrarily mix stack and register operands.
  2. Tigress' transformations can be combined in arbitrary ways, such as virtualizing a virtualized function, jit two merged functions, virtualize a jitted function, etc:

Challenges.To stimulate reverse engineering research, we are publishing sets of challenge problems generated by Tigress. Prizes will be awarded to those who are first to crack. To participate, please go to revenge.cs.arizona.edu.

Education. In our classes we use Tigress to generate reverse engineering exercises and take-home exams for the students. We use Tigress' RandomFuns transformation to generate a unique random program for every student in the class and protect it using some appropriate combination of transformations. The difficulty of the exercises can be easily varied by picking different sequences of transformations, and, since diversity guarantees that every program instance is unique, cheating is made more difficult. To use this in your own classes, please go to revenge.cs.arizona.edu.

WebAssembly: The typical way to protect code running in the browser from attacks by the user is to write the code in Javascript and transform it with a Javascript obfuscator. An alternative approach is to write the code in C, transform it with Tigress, and to compile the resulting code using Emscripten (a C-to-WASM compiler) to a WebAssembly/html/Javascript package. This package can be loaded by most browsers. The advantage of this approach is that the resulting code can run at near-native speeds and that Tigress supports more powerful obfuscating transformations than most Javascript obfuscators. Here's a depiction of the process;

Note to academics. We see Tigress used in many research projects, and this is very satisfying! We encourage anyone working in reverse engineering to try to attack Tigress-generated code, and anyone working in software protection to compare their techniques against the standard set of techniques provided by Tigress. We are always keen to collaborate, so please get in touch if you have some interesting ideas to work on! That said, we often see papers where researchers have used Tigress and where the analyses they perform are not as accurate as one would like. Here are some common problems we've seen:

  • "We run Tigress with default options". There is no such thing. By "default", Tigress does nothing! There are lots of different transformations, lots of different options, and you need to specify which ones you used. Different options to the same transformation can have radically different performance characteristics.
  • "Tigress does not support transformation X".  There are lots of transformations. Lots of options. To be sure you're not missing something, contact me. 
  • "Tigress-generated code crashed, so we ignored it." I'm not saying there are no bugs, but Tigress has been used in commercial projects and I believe it mostly "works". If you find a bug, contact me. Often, the problem is system specific and can be taken care of by simply adding another compiler flag or #define.
  •  "Tigress-generated code is slow". Yeah, true, but again, it depends on the particular set of options you're using. Virtualization, for example, has specfic options to generate faster code. Again, if you're unsure you're running the best possible Tigress script, contact me.