Control Flow Flattening CFF

Hi Man,

I am going to write a sample of Control Flow Flattening (CFF) code in C++. The control flow flattening has been used by many malware. Emotet is the malware which uses this technique heavily

What is Control Flow Flattening ?

Control Flow Flattening is a technique that aims to obfuscate program flow by taking away tidy program structures in favor of putting the program blocks inside a loop with a single switch statement controlling program flow.

I write a simple C++ code below where the sequence of the code is very clear from the top to the bottom

#include <iostream>
#include <stdlib.h>
#include<stdio.h>
#include <Windows.h>
using namespace std;

int main()
{

        cout << "First Block ";
   
        cout << ".." << 8 << endl;
        Sleep(1);
    
        cout << "2nd Block ";
    
        cout << ".." << 9 << endl;
        Sleep(1);
    
        cout << "3rd Block ";
  
        cout << ".." << 10 << endl;
        Sleep(1);
 
}

When we compiled that code into a PE and open it in IDA, The flow is very easy to understand from the very begining of the main function to the end of the main function. With this flow, application is very easy to understand because we can see obviously block of code sequencialy executed

Lets tweak the code to make the flow of the application become flat left to right which could give much confusion to the analyst because the flow is broken and flattened.

#include <iostream>
#include <stdlib.h>
#include<stdio.h>
#include <Windows.h>
using namespace std;

int main()
{
    int nextStep = 10;
  
    while (nextStep !=20){
       
        switch (nextStep) {
        case 10:
            cout << "First Block";
            
                cout << ".." << 8 << endl;
                Sleep(1);
            
            nextStep = 11;
            break;
        case 11:
            cout << "2nd Block";
            
                cout << ".." << 9 << endl;
                Sleep(1);
            
            nextStep = 12;
            break;
        case 12:
            cout << "3rd Block";
            
                cout << ".." << 10 << endl;
                Sleep(1);
            
            nextStep = 20;
            break;
            }
    }
}

I put the code into while loop and switch case statement to ensure the sequence of the code is the same. We can see from the output of the application that code sequence is the same but if we open the application in IDA then the flow is totaly different

Emotet applies multiple layer of obfuscation thus making the analyst harder to analyze the code statically.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s