Each Tigress transformation is specified, at a minimum, by the --Transform
option
that selects the type of transformation and the --Functions
option that
selects the function(s) to which it should be applied. The Tigress options described here
apply to all transformations. Each transformation additionally has their
own set of options, all prefixed by the name of the transformation.
Option | Arguments | Description |
---|---|---|
--Environment | string | A string that describes the architecture, operating system, and compiler being used. We currently recognize the following strings: x86_64:Linux:Gcc:4.6 , x86_64:Darwin:Clang:5.1 , armv7:Linux:Gcc:4.6 , armv8:Linux:Gcc:4.6 . This is mostly necessary because Clang does not support some features (most notably asm goto ) that Gcc does. In the future we will use this to provide better support for 32-bit binaries. Default=0. |
--out | file.c | The file to write to. |
--Seed | INTSPEC | The randomization seed. --Seed=0 makes Tigress generate its own seed. |
--Verbosity | int | Tigress' chattiness level. --Verbosity=0 makes Tigress quiet. --Verbosity=1 prints each transformation as it is being applied. Higher levels also print out all the versions of functions and variables being constructed. If --LogDir=dirName is set, generated log files will go in dirName . Default=0. |
--Version | Print the current Tigress version and exit. | |
--License | Print the current Tigress license and exit. | |
--Skip | BOOLSPEC | Skip a particular transformation. Typically, use like this to skip transformation T1 : tigress --Transform=T1 --Skip=true ... --Transform=T2 --Skip=false ... . This can be useful when you have a long sequence of transformations and want to experiment with turning certain ones on or off. Default=false. |
--Input | INPUTSPEC | Specify invariants over the command line arguments, such the range of integer values a particular argument may take, the range of lengths of an argument, or the string value of an argument. These are used by the input opaque predicate, which is created by --InitOpaqueStructs=input . Default=0. |
To avoid name clashes and to allow you to specify the results of a
transformation, prefixes can be added to all new identifiers. For
example, after a Split
transformation, you may want to
perform additional transformations to the newly formed functions,
and thus need to know their new names. You can use the --Prefix
for this. Also, if you intend to run Tigress multiple times on the same
file (rather than applying all transformations in one run), you need
to make sure that new names don't clash with old ones. Use
--FilePrefix
for this.
Option | Arguments | Description |
---|---|---|
--out | file.c | The file to write to. |
--FilePrefix | AUTO, NONE, string | Use this if you intend to run tigress multiple times on each file to avoid name clashes. Only set this option once. Default=NONE.
|
--Prefix | string | Add this prefix to each new generated symbol. This is in addition to the --filePrefix. Default is "_number_" where number is the order number of the transformation given on the command line. You can set this for every transformation. Default=_number_. |
--Exclude | string,string,... | Comma-separated list of the functions to exclude from obfuscation. Useful after an --Functions=* or --Functions=?int option, like this: --Functions=* --Exclude=main |
--Functions | IDENTSPEC | The functions to which the transformation should be applied. See below for how to specify a set of functions. |
--GlobalVariables | IDENTSPEC | The global variables to which the transformation should be applied. Currently only used for the --Transform=EncodeData transformation. |
--LocalVariables | LOCALSPEC | The local variables and formal parameters to which the transformation should be applied. Currently only used for the --Transform=EncodeData transformation. |
--outJson | string | Whether to also save the output as a json file, and which file to save it on. From version 3.3 |
--DumpConfig | bool | Print the configuration options in effect, such as sizes of types. From version 4.0.0 |
--LogDir | string | --LogDir=dir will create all future log files will go in the dir directory. If dir does not exist, it will be created. From version 3.3. |
--TransformVLA | alloca, malloc, doNotTransform | Describe how Variable Length Arrays (VLAs) should be translated to calls to alloca or malloc. This only applies to transformations that make wholesale changes to the control structures of a function, like flattening or virtualization. Default=alloca.
|
AAA_BBB_opaque_list1
, give the options
--FilePrefix=AAA_ \
--Transform=initOpaque \
--Prefix=BBB
AAA__0__opaque_Node
, give the options
--FilePrefix=AAA_ \
--Transform=InitOpaque
For options that take an integer an argument we provide an INTSPEC notation that allows randomized selection of the value. There's a similar BOOLSPEC notation for booleans.
All transformations require you to specify the set of functions to
which they should be applied. IDENTSPEC (identifier
specifications) allow you to flexibly select all or some of the
available functions. Some transformations also use identifier
specifications to specify variables, as
in --UpdateEntropyVar=*
which would select all variables of
a function.
Here are some examples:
--Functions=?3,foo
--Transform=UpdateEntropy \
--Functions=foo \
--UpdateEntropyVar=*
--Transform=split \
--Functions=%20
Note that some care needs to be exercised when specifiying identifiers, since some renaming can happen during obfuscation.
Some transformations allow you to specify a region of a function to transform. In your
source program you use the macro TIGRESS_REGION(region-name,code)
:
#include "tigress.h"
void fib(int n) {
int a=0;
int b=1;
int s=1;
int i;
TIGRESS_REGION(region1,
for (i=1; i<n; i++) {
s=a+b;
a=b;
b=s;
}
);
printf("fib(%i)=%i\n",n,s);
}
Then, in your tigress command, you add :region-name
to the --Functions
option:
tigress ... --Transform=Virtualize --Functions=fib:region1 ...
Caveats:
Typically, Tigress generates a C file as output, specified by the --out=filename.c
option.
If you want to process the output further you can also provide --outJson=filename.json
option
which will produce the output file as an abstract syntax tree. There is no formal definition of this Json AST
at this point, but it closely follows the structure of the CIL AST
on which it is based. Here's a piece of a function AST:
"GFun": {
"vname": "TEST",
"sformals": [],
"slocals": [
{ "vname": "g", "vtype": { "TInt": "int" }, "vglob": false,
"vstorage": "NoStorage", "vid": 3252 }
],
"sbody": {
"bstmts": [
{ "labels": [], "sid": -1, "preds": [], "succs": [],
"skind": {
"Instr": [
{
"Set": [
{
"Var": {
"vname": "g",
"vtype": { "TInt": "int" },
"vglob": false,
"vstorage": "NoStorage",
"vid": 3252
}, "offset": "NoOffset" }, {
"Const": { "CInt64": [ "42", "int" ] } }
] }, {
"Call": [
"None", "printf", [
{
"CastE": [
{ "TPtr": { "TInt": "char" } }, {
"Const": { "CStr": "g=%i\n" } }
] }, {