Jscrambler 101 — Control Flow Flattening
September 12th, 2023 | By Jscrambler | 3 min read
Last updated on August 23rd, 2023
Introduction: Control Flow Flattening
Last time, on Jscrambler 101 — Self Defending, we covered using Self Defending and its anti-tampering and anti-debugging capabilities.
This time, we will talk about Control Flow Flattening. Explore the complete documentation about Control Flow Flattening in our Help Center.
Control Flow Flattening
Control Flow Flattening aims to obfuscate the program flow by flattening it.
To achieve this, the transformation splits all the basic blocks of the source code, such as function body, loops, and conditional branches, and puts them all inside a single infinite loop with a switch statement that controls the program flow.
This makes the program flow significantly harder to follow because the natural conditional constructs that made the code easier to read are now gone.
The following diagram is an abstract representation of what happens to control flow. It depicts a simplification of what a Control Flow Graph (CFG) would look like before (on the left) and after (on the right) flattening the program flow with a Static Code Analysis Tool.
The CFG on the left has not yet been flattened, and because of that, it is easy to pinpoint conditional statements like the red node that creates a forked path (also known as branches) to the green and orange nodes.
We can see that, after flattening the control flow, the CFG nodes are all on the same nesting level, switching and looping back to the black node to choose the next node to go to.
Control Flow Flattening offers parameterization, allowing it to increase confusion when trying to reverse engineer it and resilience against static code analysis.
Clones are semantically equivalent copies of basic blocks that can be executed interchangeably with their original basic blocks.
By adding these semantically equivalent clones and making the program choose randomly between them, we are adding to the confusion and making the program flow harder to understand.
Dead Clones are dummy copies of basic blocks that are never executed but mimic and can be confused with the code that will be executed, adding to the confusion factor.
Depending on the size and complexity of the source code, Jscrambler may choose not to add dead clones if it determines that they aren’t needed. This will result in a smaller code.
Opaque Steps obfuscates the switching variable, making it harder to understand what's the next switch case that’ll be executed.
This improves the resilience against static code analysis, as opaque steps make it harder for static code analysis to determine the next step without actually executing the code.
Therefore, reversing such a transformation into its unflattened equivalent becomes much harder.
Protecting your application with Control Flow Flattening makes it troublesome to follow the program flow, making it almost impossible to understand and reverse-engineer.
This allows you to add conditional opaqueness, flatten the control flow, and add confusion with irrelevant code clones.
Combining it with other Jscrambler protection transformations is safe, works out of the box, and results in more potent and resilient protection. Also, remember to test it out on the Jscrambler Web App.
Feel free to proceed to one of our other 101 Tutorials:
Jscrambler 101 — Code Annotations (Code Performance)
Jscrambler 101 — Profiling (Code Performance)
Enjoy your testing.
Start protecting your Applications ASAP! If you have any additional questions, contact our client-side security experts.
Must read next
Jscrambler 101 - Code Locks
August 16, 2023 | By Jscrambler | 4 min read
Jscrambler 101 — How to use the CLI
June 20, 2023 | By Jscrambler | 4 min read