Leak

Transform a function such that it leaks a secret, in particular (part of) the code of a secret function. This can be useful to simulate a misbehaving obfuscator. Leaking can be static (simply insert a variable that holds the encrypted source code of the secret function) or dynamic (only leak if a certain formal parameter has a certain value).

OptionArgumentsDescription
--Transform Leak Simulate a misbehaving obfuscator by inserting code that leak (part of) the secret function. Note that openssl needs to be installed.
--LeakSecretFunction string The name of the secret function whose code will be leaked Default=0.
--LeakVariable string For dynamic leakers, the formal parameter that will be tested Default=0.
--LeakValue INTSPEC For dynamic leakers, the value that the formal parameter will be tested against Default=0.
--LeakKind static, dynamic, dynamic_byte Select the kind of leaking code to be inserted. Default=static.
  • static = insert the encrypted code into a variable
  • dynamic = return the encrypted code when a particular formal parameter has a particular value
  • dynamic_byte = return the i:th byte of the encrypted code depending on the value of the formal parameter
--LeakDebug boolean Turn debugging on or off. Default=false.
 

Examples

The static leaker simply inserts the encrypted source code of the secret function as a string. For example, this command

tigress \
   --Transform=Leak \
      --LeakKind=static \
      --Functions=foo \
      --LeakSecretFunction=main 

produces this code

char *leak_global_enc  =    0;

int foo(int x) { 
  char *leak_enc ;
  leak_enc = "U2Fs...Blsvk=\n";
  leak_global_enc = leak_enc;
  g = 42;
  return (g);
}

The dynamic leaker will leak the entire (encrypted) source code of the secret function, but only when a particular formal parameter has a particular value. For example, this command

tigress \
    --Transform=Leak \
       --LeakKind=dynamic \
       --Functions=foo \
       --LeakVariable=x \
       --LeakValue=42 \
       --LeakSecretFunction=main 

will transform function foo such that when formal parameter x!=42 the function behaves normally, but when x==42, it will leak the source of main main. Note that for this transformation, the signature of foo changes:

struct leak_object {
   long key ;
   char *enc ;
};
union return_object {
   int return_value ;
   struct leak_object leak_value ;
};
struct result_object {
   unsigned char result_tag ;
   union return_object result_value ;
};

struct result_object foo(int x) { 
  struct result_object return_var ;
  if (x == 42UL) {
    return_var.result_tag = 1;
    return_var.result_value.leak_value.key = 934550629044916202UL;
    return_var.result_value.leak_value.enc = "U....EW\n";
    return (return_var);
  } else {
    g = 42;
    return_var.result_tag = 0;
    return_var.result_value.return_value = g;
    return (return_var);
  }
}

The dynamic_byte leaker will leak one byte at a time of the (encrypted) secret function. The byte leaked depends on the value of the selected formal parameter. For example, this command

tigress \
   --Transform=Leak \
      --LeakKind=dynamic_byte \
      --Functions=foo \
      --LeakVariable=x \
      --LeakValue=42 \
      --LeakSecretFunction=main 

will transform function foo such that when formal parameter x<=42 the function behaves normally, but when x>42, it will leak byte x-42 of the encryption of main:

int foo(int x) { 
  int return_var ;
  char *leak_enc ;
  unsigned long leak_key ;
  if (x > 42UL) {
    leak_enc = "U2Fs.....=\n";
    *((char *)(& return_var)) = leak_enc[x - 42UL];
    return (return_var);
  } else {
    g = 42;
    return (g);
  }
}

Issues

  • Doesn't work for functions whose address is taken and then called through a function pointer.
  • openssl must be installed.