123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- import { assert } from 'chai';
- import { IObfuscationResult } from '../../../../src/interfaces/IObfuscationResult';
- import { NO_CUSTOM_NODES_PRESET } from '../../../../src/options/presets/NoCustomNodes';
- import { readFileAsString } from '../../../helpers/readFileAsString';
- import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscator';
- describe('FunctionControlFlowTransformer', () => {
- const variableMatch: string = '_0x([a-z0-9]){4,6}';
- const rootControlFlowStorageNodeMatch: string = `` +
- `var *${variableMatch} *= *\\{` +
- `'(\\\\x[a-f0-9]*){3}' *: *function *${variableMatch} *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
- `return *${variableMatch} *\\+ *${variableMatch};` +
- `\\}` +
- `\\};` +
- ``;
- const innerControlFlowStorageNodeMatch: string = `` +
- `var *${variableMatch} *= *\\{` +
- `'(\\\\x[a-f0-9]*){3}' *: *function *${variableMatch} *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
- `return *${variableMatch}\\['(\\\\x[a-f0-9]*){3}'\\]\\(${variableMatch}, *${variableMatch}\\);` +
- `\\}` +
- `\\};` +
- ``;
- describe('transformNode (functionNode: ESTree.Function): ESTree.Node', () => {
- describe('variant #1 - single `control flow storage` node with single item', () => {
- const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
- readFileAsString(
- './test/fixtures/node-transformers/control-flow-transformers/function-control-flow-transformer-1.js'
- ),
- {
- ...NO_CUSTOM_NODES_PRESET,
- controlFlowFlattening: true,
- controlFlowFlatteningThreshold: 1
- }
- );
- const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
- const regexp: RegExp = new RegExp(rootControlFlowStorageNodeMatch);
- it('should add `control flow storage` node to the obfuscated code', () => {
- assert.match(obfuscatedCode, regexp);
- });
- });
- describe('variant #2 - two `control flow storage` nodes: root and inner', () => {
- const samplesCount: number = 200;
- const delta: number = 0.1;
- const expectedValue: number = 0.5;
- const regExp1: RegExp = new RegExp(
- `\\(function\\(\\) *\\{ *${rootControlFlowStorageNodeMatch}`,
- 'g'
- );
- const regExp2: RegExp = new RegExp(
- `function *${variableMatch} *\\(\\) *\\{ *${innerControlFlowStorageNodeMatch}`,
- 'g'
- );
- let totalValue: number = 0;
- for (let i = 0; i < samplesCount; i++) {
- const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
- readFileAsString(
- './test/fixtures/node-transformers/control-flow-transformers/function-control-flow-transformer-2.js'
- ),
- {
- ...NO_CUSTOM_NODES_PRESET,
- controlFlowFlattening: true,
- controlFlowFlatteningThreshold: 1
- }
- );
- const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
- if (regExp1.test(obfuscatedCode)) {
- totalValue += obfuscatedCode.match(regExp1)!.length;
- if (regExp2.test(obfuscatedCode)) {
- totalValue += obfuscatedCode.match(regExp2)!.length;
- }
- }
- }
- it('should add two `control flow storage` nodes (root and inner) to the obfuscated code in different scopes', () => {
- assert.closeTo((totalValue - samplesCount) / samplesCount, expectedValue, delta);
- });
- });
- describe('variant #3 - single `control flow storage` node with multiple items', () => {
- const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
- readFileAsString(
- './test/fixtures/node-transformers/control-flow-transformers/function-control-flow-transformer-multiple-items-1.js'
- ),
- {
- ...NO_CUSTOM_NODES_PRESET,
- controlFlowFlattening: true,
- controlFlowFlatteningThreshold: 1
- }
- );
- const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
- const regexp: RegExp = new RegExp(
- `var *${variableMatch} *= *\\{` +
- `'(\\\\x[a-f0-9]*){3}' *: *function *${variableMatch} *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
- `return *${variableMatch} *\\+ *${variableMatch};` +
- `\\}, *` +
- `'(\\\\x[a-f0-9]*){3}' *: *function *${variableMatch} *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
- `return *${variableMatch} *- *${variableMatch};` +
- `\\}` +
- `\\};`
- );
- it('should add `control flow storage` node with multiple items to the obfuscated code', () => {
- assert.match(obfuscatedCode, regexp);
- });
- });
- describe('variant #4 - no `control flow storage` node to the root block scope', () => {
- const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
- readFileAsString(
- './test/fixtures/node-transformers/control-flow-transformers/function-control-flow-transformer-root-block-scope-1.js'
- ),
- {
- ...NO_CUSTOM_NODES_PRESET,
- controlFlowFlattening: true,
- controlFlowFlatteningThreshold: 1
- }
- );
- const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
- it('should\'t add control flow storage node when transformed node in the root block scope', () => {
- assert.match(obfuscatedCode, /^var *test *= *0x1 *\+ *0x2;$/);
- });
- });
- describe('variant #5 - no `control flow storage` node in the root block scope', () => {
- const samplesCount: number = 20;
- const expectedValue: number = 0;
- const regExp: RegExp = new RegExp(
- `var *[a-zA-Z]{6} *= *\\{` +
- `'(\\\\x[a-f0-9]*){3}' *: *function *_0x[0-9] *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
- `return *${variableMatch} *\\+ *${variableMatch};` +
- `\\}` +
- `\\};`
- );
- it('should\'t add control flow storage node to the root block scope when transformed nodes not in the root block scope', () => {
- let totalValue: number = 0;
- for (let i = 0; i < samplesCount; i++) {
- const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
- readFileAsString(
- './test/fixtures/node-transformers/control-flow-transformers/function-control-flow-transformer-root-block-scope-2.js'
- ),
- {
- ...NO_CUSTOM_NODES_PRESET,
- controlFlowFlattening: true,
- controlFlowFlatteningThreshold: 1
- }
- );
- const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
- if (regExp.test(obfuscatedCode)) {
- totalValue++;
- }
- }
- assert.equal(totalValue, expectedValue);
- });
- });
- describe('variant #6 - no single `control flow storage` node when threshold is 0', () => {
- const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
- readFileAsString(
- './test/fixtures/node-transformers/control-flow-transformers/function-control-flow-transformer-zero-threshold.js'
- ),
- {
- ...NO_CUSTOM_NODES_PRESET,
- controlFlowFlattening: true,
- controlFlowFlatteningThreshold: 0
- }
- );
- const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
- const controlFlowStorageMatch: RegExp = new RegExp(rootControlFlowStorageNodeMatch);
- const regexp: RegExp = /var *_0x([a-z0-9]){4,6} *= *0x1 *\+ *0x2;/;
- it('shouldn\'t add `control flow storage` node to the obfuscated code when threshold is 0', () => {
- assert.match(obfuscatedCode, regexp);
- assert.notMatch(obfuscatedCode, controlFlowStorageMatch);
- });
- });
- });
- });
|