What is Tigress?
Tigress is a diversifying obfuscator for the C language that supports many novel defenses against both static and dynamic reverse engineering and de-virtualization attacks. Tigress supports two major transformations:
- Virtualization, i.e. transforming a function into an interpreter whose bytecode language is specialized for this function, and
- Jitting, i.e. transforming a function into one that generates its machine code at runtime.
In addition, Tigress has a collection of supporting transformations that can help with resilience to attack, diversity, and stealth:
- Control flow flattening,
- function Splitting, Merging, and Argument randomization,
- Control flow splitting with opaque predicates,
- encoding of Literals, Data, and Arithmetic.
Tigress also supports three transformations designed to thwart particular static and dynamic analyses:
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:
- 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.
- Tigress transformations can be combined in arbitrary ways, such as virtualizing a virtualized function, jit two merged functions, virtualize a jitted function, etc.
Usage. The user interacts with Tigress by giving an input C file, a seed, and a sequence of transformations:
- Research: Tigress was originally designed as the backend of a system for distributed application tamper detection via continuous software updates. The idea was to force rapid updates to the code running on an untrusted remote site in order to increase the workload of the attacker who has to crack, and re-crack, the code as it is constantly updated. We are currently using Tigress to measure the stealth of obfuscated code. Another group is using Tigress to test code stylometric algorithms.
- Benchmarking: We are planning to use Tigress to generate collections of software protection benchmark programs. These will provide the community with randomly generated attack targets to form a basis for uniform and generally accepted evaluation procedures for software protection algorithms. In particular, we are hoping future de-virtualization research projects will use Tigress-generated interpreters as one of their attack targets.
- Challenges: To stimulate reverse engineering research, we are publishing sets of challenge problems generated by Tigress.
- Education. In our classes we use Tigress to generate reverse engineering exam/challenge problems for the students. We use Tigress' RandomFuns trasformation to generate a unique random program for every student in the class, next transform the program using some appropriate combination of obfuscations, and finally give the resulting program to students as a cracking target. The difficulty of the challenge 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.