Transforming Libraries

Tigress is a whole-program transformer. The reason is that for many transformations you need complete knowledge of the whole program in order to do a safe translation. However, sometimes it's desirable to transform a single function, or a few functions in a library. For simple cases, there is an easy trick that allows you to do that. Start by adding empty main and tigress_init functions to your program:

#include "tigress.h"
#include <time.h>
#include <pthread.h>

void tigress_init() {
    // Empty!
}
void foo () {
}
void bar () {
}
int main(){
    // Empty!
}

Then go ahead and transform the program as normal, making sure that any initialization code goes in tigress_init:

> tigress \
    --Environment=x86_64:Darwin:Clang:4.5 \
    --Transform=InitEntropy --Functions=tigress_init \
    --Transform=Flatten --Functions=foo,bar \
    --out=obf.c lib.c

Now, the Tigress output file will contain a lot of information that you don't really care about. Fortunately, the output format has been designed such that it is easy to extract the pieces you need by means of a simple script. Here's an example of what the obfuscated output might look like:

/* BEGIN FUNCTION-DEF tigress_init LOC=UNKNOWN */
void tigress_init(void) { 
   ...
}
/* END FUNCTION-DEF tigress_init LOC=UNKNOWN */

/* BEGIN FUNCTION-DEF foo LOC=UNKNOWN */
void foo(void) { 
   ...
}
/* END FUNCTION-DEF foo LOC=UNKNOWN */

/* BEGIN FUNCTION-DEF bar LOC=UNKNOWN */
void bar(void) { 
   ...
}
/* END FUNCTION-DEF bar LOC=UNKNOWN */

/* BEGIN STRUCT sched_param LOC=sched.h:35 */
struct sched_param {
   int sched_priority ;
   char __opaque[4] ;
};
/* END STRUCT sched_param LOC=/sched.h:35 */

/* BEGIN ENUM __anonenum_788482901 LOC=qos.h:130 */
enum __anonenum_788482901 {
    QOS_CLASS_USER_INTERACTIVE = 33,
    QOS_CLASS_USER_INITIATED = 25,
    QOS_CLASS_DEFAULT = 21,
    QOS_CLASS_UTILITY = 17,
    QOS_CLASS_BACKGROUND = 9,
    QOS_CLASS_UNSPECIFIED = 0
} ;
/* END ENUM __anonenum_788482901 LOC=qos.h:130 */

/* BEGIN FUNCTION-DECL-EXTERN pthread_cond_broadcast LOC=pthread.h:293 */
extern int pthread_cond_broadcast(pthread_cond_t * ) ;
/* END FUNCTION-DECL-EXTERN pthread_cond_broadcast LOC=pthread.h:293 */

As you can see, every C object is bracketed by comments, making it easy to strip out what you don't want. In this case, a simple awk script will do the trick:

> cat strip.awk
/BEGIN FUNCTION-DEF tigress_init/,/END FUNCTION-DEF tigress_init/{print};
/BEGIN FUNCTION-DEF foo/,/END FUNCTION-DEF foo/{print};
/BEGIN FUNCTION-DEF bar/,/END FUNCTION-DEF bar/{print}; 

> gawk -f strip.awk obf.c > obf_clean.c

Keep in mind that the tigress_init function contains code that must be executed prior to any other obfuscated function, so make sure that any code using your obfuscated library calls tigress_init at startup.