Control Flow Flattening (original) (raw)

Description

The purpose of this pass is to completely flatten the control flow graph of a program.

For a detailed explanation of the control flow flattening technique, see for instance the paper of T László and Á Kiss, Obfuscating C++ programs via control flow flattening, Annales Univ. Sci. Budapest., Sect. Comp. 30 (2009) 3-19.

Note however that our algorithm fully flattens the control flow, which is not the case of the one of László and Kiss.

Available Compiler Options

Implemented Technique

Here is an example. Consider this very simple C program :

#include <stdlib.h>
int main(int argc, char** argv) {
  int a = atoi(argv[1]);
  if(a == 0)
    return 1;
  else
    return 10;
  return 0;
}

The flattening pass will transform this code into this one :

#include <stdlib.h>
int main(int argc, char** argv) {
  int a = atoi(argv[1]);
  int b = 0;
  while(1) {
    switch(b) {
      case 0:
        if(a == 0)
          b = 1;
        else
          b = 2;
        break;
      case 1:
        return 1;
      case 2:
        return 10;
      default:
        break;
    }
  }
  return 0;
}

As one can see, all basic blocks are split and put into an infinite loop and the program flow is controlled by a switch and the variable b.

Here, it's what it looks like for the control flow generated before the flattening :

Without fla

After the flattening, we get the following instruction flow:

With fla

As one can see, the main difference between the example in pure C, the IR version is completely flattened.