InitCheckers
(Experimental)

This is the initialization transformation that should precede the Checksum and CheckEnvironment transformations. This transformation will create a set of global variables that checkers will increment whenever a check fails. It will also create a set of responders which will trigger a response whenever the number of failed checks exceed a threshold.

As an example, consider this command:

tigress --Environment=x86_64:Linux:Clang:5.1 \
    --Transform=InitChecker \
       --InitCheckersResponseKinds=abort \
       --InitCheckersResponderCount=2 \
       --InitCheckersStateSize=2 \
       --InitCheckersFakeSize=2 \
       --InitCheckersThreshold=2 \
       --InitCheckersStateEncodings=rnc,xor \
       --InitCheckersFunctionsToInvokeResponders=fib,fac \
       --Functions=main \
   --Transform=CheckEnvironment \
       --Functions=fac \
       --CheckEnvironmentSandboxes=valgrind \
       --CheckEnvironmentCheckerCount=2 \
   foo.c --out=obf.c

--Transform=InitChecker will create global variables that will count the number of tests conducted and the number of tests that failed. You can also add fake variables to make it harder for the attacker to identify the real ones:

int fail_1 = 0;
int fail_2 = 0;
int test_1 = 0;
int test_2 = 0;
int fake_1 = 0;
int fake_2 = 0;

In practice, we don't want these values in cleartext. The --InitCheckersStateEncodings option decides how the state variables should be encoded. Here's what the initialization looks like when you choose Residue Number Coding:

long fail_1_0 = ((0L % 230135L ^ ~ (10L * 230135L)) + ((0L % 230135L | 10L * 230135L) + (0L % 230135L | 10L * 230135L))) + 1L;
long fail_1_1 = ((0L % 211253L | 10L * 211253L) << 1L) - (0L % 211253L ^ 10L * 211253L);

The --InitCheckersFunctionsToInvokeResponders option decides into which functions the responders should be inserted.

The --Transform=CheckEnvironment transformation will spread responders throughout the program. The --CheckEnvironmentSandboxes and --CheckEnvironmentCheckerCount options decide what sandboxes we should check for, and how many checks we should insert. The --Functions option decides into which functions the checkers should be inserted. The responders look like this:

  total4 = __1_counterState_fail_1_0;
  total4 += __1_counterState_fail_0_0;
  if (total4 > 2) {
    abort();
  } else {

  }

I.e. we compute the total number of failed tests by adding up all the failure state variables, and, if the total exceeds the --InitCheckersThreshold value, we execute the response. With Residue Number Coding, it looks like this:

  decode4 = (((fail_1_0 * 16680518100L) % 24104988860L + (fail_1_1 * 7424470761L) % 24104988860L) % 24104988860L + 24104988860L) % 24104988860L;
  if (decode4 > 12052494429L) {
    decode4 -= 24104988860L;
  } else {

  }
  total5 = (int )decode4;
  decode6 = (((fail_0_0 * 7721719656L) % 48616709155L + (fail_0_1 * 40894989500L) % 48616709155L) % 48616709155L + 48616709155L) % 48616709155L;
  if (decode6 > 24308354576L) {
    decode6 -= 48616709155L;
  } else {

  }
  total5 += (int )decode6;
  if (total5 > 2) {
    abort();
  } else {

  }

OptionArgumentsDescription
--Transform InitCheckers Initialize the checking system used by transforms Checksum and CheckEnvironment
--InitCheckersResponseKinds abort, modifyGlobal, random, plugin Comma-separated list of ways to respond when a check fails. Default=abort.
  • abort = Call the abort function
  • modifyGlobal = Make random modification to a global variable
  • random = Execute random bytes
  • plugin = Call one of the plugin responders
--InitCheckersRespondWhen immediately, delay Comma-separated list of when the response to a failed test should be issued.
  • immediately = Invoke the response action as soon as a check fails (will always trigger).
  • delay = Delay the response action until some later time (may or may not trigger, depending on subsequent control flow).
--InitCheckersResponderCount INTSPEC Number of responders to insert in the program. Default=1.
--InitCheckersStateSize INTSPEC Number of global variables that hold the check counts. Default=1.
--InitCheckersFakeSize INTSPEC Number of fake global variables that look like real state variables. Default=1.
--InitCheckersThreshold INTSPEC How many tests need to fail before a response is issued. Default=1.
--InitCheckersStateEncodings rnc, xor, list, plugin, none The encoding of the state in which to store successes and failures. Default=rnc.
  • rnc = Use Residue Number Coding
  • xor = Use XOR coding
  • list = Use list encoding (not yet implemented)
  • plugin = Use plugins (not yet implemented)
  • none = Don't encode the state variables
--InitCheckersFunctionsToInvokeResponders Comma-separated list of functions in which we can install responders. Default=None.