The goal of this transformation is to disrupt static analysis tools that make use of inter-procedural alias analysis. The current implementation is simplistic: we simply replace all direct function calls with indirect ones.

A call to x = foo(n) turns into

void *arr[]  = {..., & foo, ... };

int main () {
   int x = ((int (*)(int n ))arr[expr=42])(n);
}
where arr is a global array containing function addresses, and expr=42 is an opaque expression computing the index of foo's address in arr.

To make analysis a bit harder, we can also insert bogus elements in arr, and insert updates to these bogus elements. Here, both arr[6] and arr[7] are bogus:

int main () {
   int x;
   arr[expr=6] = arr[expr=42];
   arr[expr=7] = &x;
}
 

Options

OptionArgumentsDescription
--Transform AntiAliasAnalysis Transform the code by replacing direct function calls with indirect ones, making alias analysis become less precise.
--AntiAliasAnalysisObfuscateIndex BOOLSPEC Use opaque expressions to compute function addresses. Default=true.
--AntiAliasAnalysisBogusEntries BOOLSPEC Add bogus function addresses, and bogus updates to them. Default=true.

 

Issues

It is best to perform this transformation at the end of the transformation sequence, when all functions (including new ones generated by the virtualize, split, and merge transformations) are known. The reason is that, by definition, this transformation makes alias analysis difficult, which trips up subsequent transformations. This is particularly true for the EncodeData transformation which relies on alias analysis. The --AntiAliasAnalysisBogusEntries=true option seems to be particularly troublesome.