The goal of this transformation is to hide calls to external functions, such as system calls or calls to standard library functions. The current implementation is simplistic: we simply replace direct calls with indirect ones, and load the address of the functions using dlsym().

Consider the following program syscall.c which makes two system calls to getpid and gettimeofday:

#include "apple.h"

void tigress_init() {}

int main () {
   int x = getpid(); 
   printf("%i\n", x);
   struct timeval tv;
   int y = gettimeofday(&tv, NULL); 
   printf ("%ld.%06ld\n", tv.tv_sec, tv.tv_usec); 

We obfuscate using the following script:

> tigress -ldl \
        --Environment=x86_64:Darwin:Clang:5.1 \
        --Transform=InitEncodeExternal \
           --Functions=tigress_init \
           --InitEncodeExternalSymbols=getpid,gettimeofday  \
        --Transform=EncodeLiterals \
           --Functions=tigress_init \
           --EncodeLiteralsKinds=string \
           --EncodeLiteralsEncoderName=STRINGENCODER \
        --Transform=Virtualize \
           --Functions=STRINGENCODER \
        --Transform=EncodeExternal \
           --Functions=main \
           --EncodeExternalSymbols=getpid,gettimeofday  \
        --out=syscall_out.c syscall.c
> gcc -o syscall_out syscall_out.c -ldl

The InitEncodeExternal transformation uses dlsym() to load the system calls we want to hide by name, the EncodeLiterals transformation hides these names in a function we call STRINGENCODER, the Virtualize transformation hides what's going on in the STRINGENCODER function, and finally, the EncodeExternal transformation replaces the direct calls to the system calls in main() with indirect ones.

The resulting code will look something like this:

void *_externalFunctionPtrArray[2];

void tigress_init(void) { 
  STRINGENCODER(0, encodeStrings_litStr0);
  _externalFunctionPtrArray[0] = dlsym((void *)-3, encodeStrings_litStr0);
  STRINGENCODER(1, encodeStrings_litStr1);
  _externalFunctionPtrArray[1] = dlsym((void *)-3, encodeStrings_litStr1);

void STRINGENCODER(int n , char str[] ) {
  while (1) {
    switch (*(STRINGENCODER_$pc[0])) {
    case STRINGENCODER__store_char$left_STA_0$right_STA_1: 
    (STRINGENCODER_$pc[0]) ++;
    *((char *)(STRINGENCODER_$sp[0] + 0)->_void_star) = (STRINGENCODER_$sp[0] + -1)->_char;
    STRINGENCODER_$sp[0] += -2;

int main( ) { 
  int x,y;
  struct timeval tv ;
  x = ((pid_t (*)(void))_externalFunctionPtrArray[1])();
  printf((char const *)"%i\n", x);
  y = ((int (*)(struct timeval * __restrict   , void * __restrict ))
               _externalFunctionPtrArray[0])((struct timeval *)(& tv),
                (void *)((void *)0));
  printf((char const *)"%ld.%06ld\n", tv.tv_sec, tv.tv_usec);

Note how this program no longer has any mention of getpid and gettimeofday. The transformation is purely static, of course; at runtime it is trivial to see that these functions are being called.  


--Transform InitEncodeExternal Replace direct system calls with indirect ones through dlsym.
--InitEncodeExternalSymbols Comma-separated list of strings List of of external functions to be encoded.
--Transform EncodeExternal Replace direct system calls with indirect ones through dlsym.
--EncodeExternalObfuscateIndex BOOLSPEC Use opaque expressions to compute function addresses. Default=true.
--EncodeExternalSymbols comma-separated list of strings Set of external functions to be encoded in this function Default=true.