> ## Documentation Index
> Fetch the complete documentation index at: https://docs.js-confuser.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Control Flow Flattening

> Control-flow Flattening hinders program comprehension by creating convoluted switch statements.

**⚠️ Significantly impacts performance, use sparingly!**

* Option name: `"controlFlowFlattening"`

* Option values: `true/false/0-1`

***

### Input / Output

This example showcases how `Control Flow Flattening` transforms the code. Try it out by changing the input code and see changes apply in real-time.

```js title="Input.js" lines interactive-mode="obfuscate" theme={null}
// Input.js
function countTo(num) {
  for (var i = 1; i <= num; i++) {
    console.log(i);
  }
}

var number = 10;
countTo(number); // 1,2,3,4,5,6,7,8,9,10

// Output.js
function yUNI20(yUNI20, XCDWsqE) {
  var rnH2egO = '',
    VYbmK0M = ((XCDWsqE % 95) + 95) % 95;
  for (var JldP2NN = 0; JldP2NN < yUNI20.length; JldP2NN++) {
    var Bkks2L = yUNI20.charCodeAt(JldP2NN),
      OyggnU = Bkks2L - 32,
      KzEwmcV = (OyggnU - VYbmK0M + 95) % 95;
    rnH2egO += String.fromCharCode(KzEwmcV + 32);
  }
  return rnH2egO;
}
function XCDWsqE(yUNI20) {
  for (var XCDWsqE = 0, rnH2egO = 0; rnH2egO < yUNI20.length; rnH2egO++)
    XCDWsqE += yUNI20[rnH2egO];
  return XCDWsqE;
}
function rnH2egO(
  lAzK_Z3,
  QLZkcjn = {
    WeQM9V: {},
  },
  jBNuA9v,
  MCi4Zlr,
) {
  while (XCDWsqE(lAzK_Z3) !== -178)
    switch (XCDWsqE(lAzK_Z3)) {
      case -186:
      case -189:
        [
          QLZkcjn[yUNI20('B@-"/~', lAzK_Z3[1] + 226)][
            yUNI20('-.[42u', lAzK_Z3[2] + -229)
          ],
        ] = MCi4Zlr;
        for (
          QLZkcjn.WUB7D4.ENrsJRf = 1;
          QLZkcjn.WUB7D4.ENrsJRf <= QLZkcjn.WUB7D4.bc1igK;
          QLZkcjn.WUB7D4.ENrsJRf++
        )
          console.log(QLZkcjn.WUB7D4.ENrsJRf);
        return;
      case 79:
      case lAzK_Z3[3] - -279:
      case -13:
        ((lAzK_Z3[0] += lAzK_Z3[4] - 56),
          (lAzK_Z3[1] += lAzK_Z3[0] - -42),
          (lAzK_Z3[2] += lAzK_Z3[3] - -110),
          (lAzK_Z3[3] += lAzK_Z3[4] - -729),
          (lAzK_Z3[4] += lAzK_Z3[2] - 84));
        break;
      case 150:
        ((lAzK_Z3[0] += lAzK_Z3[2] - 472),
          (lAzK_Z3[2] += lAzK_Z3[4] - 216),
          (lAzK_Z3[3] += lAzK_Z3[2] - -407),
          (lAzK_Z3[4] += lAzK_Z3[3] - 209));
        break;
      case 228:
      case 225:
      case 200:
        ((lAzK_Z3[0] += lAzK_Z3[1] - 291),
          (lAzK_Z3[3] += lAzK_Z3[1] - -270),
          (lAzK_Z3[4] += lAzK_Z3[3] - 29));
        break;
      case lAzK_Z3[0] != 482 && lAzK_Z3[0] - 549:
        ((lAzK_Z3[0] += lAzK_Z3[1] - 495),
          (lAzK_Z3[2] += lAzK_Z3[3] - 82),
          (lAzK_Z3[3] += lAzK_Z3[0] - 62),
          (lAzK_Z3[4] += lAzK_Z3[0] - -211));
        break;
      case lAzK_Z3[2] - 241:
        [QLZkcjn.WeQM9V.pPVZkr, QLZkcjn.WeQM9V.UsgNxl] = [90, 45];
        ((lAzK_Z3[0] += lAzK_Z3[3] - 270),
          (lAzK_Z3[1] += lAzK_Z3[4] - -708),
          (lAzK_Z3[2] += lAzK_Z3[3] - 211),
          (lAzK_Z3[3] += lAzK_Z3[0] - -330),
          (lAzK_Z3[4] += lAzK_Z3[2] - -504));
        break;
      case lAzK_Z3[1] - -94:
      case -35:
        [QLZkcjn.WeQM9V.pPVZkr, QLZkcjn.WeQM9V.UsgNxl] = [-83, -221];
        QLZkcjn.WeQM9V.OEKszZJ = function (...lAzK_Z3) {
          return rnH2egO(
            [134, -57, -14, -34, -215],
            {
              WeQM9V: QLZkcjn.WeQM9V,
              WUB7D4: {},
            },
            jBNuA9v,
            lAzK_Z3,
          );
        };
        QLZkcjn.WeQM9V.t3XEjET = lAzK_Z3[3] + -320;
        return (1, QLZkcjn.WeQM9V.OEKszZJ)(QLZkcjn.WeQM9V.t3XEjET);
    }
}
rnH2egO([106, 91, -143, 330, -199]);
```

***

### Control Flow Flattening Process

Control Flow Flattening transforms the code into a large, convoluted switch statement. This switch statement is intended to replicate the functionality of the 'goto' statement seen in other languages.

The switch statement is designed to be difficult to follow, making it harder for reverse engineers to understand the program's flow.

* Control Flow Flattening introduces dead code through these methods:

* * Adds fake chunks that are never reached

* * Adds fake jumps to really mess with deobfuscators ("irreducible control flow")

* * Clones chunks but these chunks are never executed

* Control Flow Flattening introduces opaque predicates through these methods:

* * Adds fake conditions that are always true or false

* * XOR encrypts strings found within the basic blocks

* * Entangles number literals found within the basic blocks against the current state values

* Control Flow Flattening mangles the scoped variables through the use of the `with` statement.

* * This makes identifiers harder to track from static analysis tools.

* Control Flow Flattening obfuscates IF-statements into equivalent switch-case statements.

* Control Flow Flattening obfuscates certain eligible functions into equivalent switch-case statements.

***

### Usage Example

The provided code example will obfuscate the file `input.js` and write the output to a file named `output.js`.

```js title="Usage Example" lines theme={null}
import JSConfuser from "js-confuser";
import {readFileSync, writeFileSync} from "fs";

// Read input code
const sourceCode = readFileSync("input.js", "utf8");
const options = {
  target: 'browser',
  controlFlowFlattening: true,
};

JSConfuser.obfuscate(sourceCode, options).then((result)=>{
  // Write output code
  writeFileSync("output.js", result.code);
}).catch(err=>{
  // Error occurred
  console.error(err);  
});
```

***

#### Enabled In

* [High Preset](/presets/high): Yes (50%)
* [Medium Preset](/presets/medium): Yes (25%)
* [Low Preset](/presets/low): No

***

### Performance reduction

Control Flow Flattening reduces the performance of your program. You should adjust the option `controlFlowFlattening` to be a percentage that is appropriate for your app.

### Other notes

Control Flow Flattening only applies to:

* Blocks of 3 statements or more

***

#### See Also

* [Pack](./pack)
