-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Control Flow Flattening
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.
-
-mllvm -fla
: activates control flow flattening -
-mllvm -split
: activates basic block splitting. Improve the flattening when applied together. -
-mllvm -split_num=3
: if the pass is activated, applies it 3 times on each basic block. Default: 1
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 :
After the flattening, we get the following instruction flow:
As one can see, the main difference between the example in pure C, the IR version is completely flattened.