|
@@ -12,7 +12,7 @@ import { swapLettersCase } from '../../../../helpers/swapLettersCase';
|
|
|
import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
|
|
|
|
|
|
describe('StringArrayTransformer', function () {
|
|
|
- this.timeout(60000);
|
|
|
+ this.timeout(120000);
|
|
|
|
|
|
describe('Variant #1: default behaviour', () => {
|
|
|
const stringArrayRegExp: RegExp = /^var _0x([a-f0-9]){4} *= *\['test'\];/;
|
|
@@ -63,21 +63,156 @@ describe('StringArrayTransformer', function () {
|
|
|
});
|
|
|
});
|
|
|
|
|
|
- describe('Variant #3: `stringArrayIntermediateVariablesCount` option is enabled', () => {
|
|
|
- describe('Variant #1: correct amount of intermediate calls', () => {
|
|
|
+ describe('Variant #3: `stringArrayWrappersCount` option is enabled', () => {
|
|
|
+ describe('Variant #1: root scope', () => {
|
|
|
+ describe('Variant #1: option value value is lower then count `literal` nodes in the scope', () => {
|
|
|
+ const stringArrayCallRegExp: RegExp = new RegExp(
|
|
|
+ 'return _0x([a-f0-9]){4,6};' +
|
|
|
+ '};' +
|
|
|
+ 'const _0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4};' +
|
|
|
+ 'const _0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4};' +
|
|
|
+ 'const foo *= *_0x([a-f0-9]){4,6}\\(\'0x0\'\\);' +
|
|
|
+ 'const bar *= *_0x([a-f0-9]){4,6}\\(\'0x1\'\\);' +
|
|
|
+ 'const baz *= *_0x([a-f0-9]){4,6}\\(\'0x2\'\\);'
|
|
|
+ );
|
|
|
+
|
|
|
+ let obfuscatedCode: string;
|
|
|
+
|
|
|
+ before(() => {
|
|
|
+ const code: string = readFileAsString(__dirname + '/fixtures/string-array-wrappers-count-const.js');
|
|
|
+
|
|
|
+ obfuscatedCode = JavaScriptObfuscator.obfuscate(
|
|
|
+ code,
|
|
|
+ {
|
|
|
+ ...NO_ADDITIONAL_NODES_PRESET,
|
|
|
+ stringArray: true,
|
|
|
+ stringArrayThreshold: 1,
|
|
|
+ stringArrayWrappersCount: 2
|
|
|
+ }
|
|
|
+ ).getObfuscatedCode();
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should add scope calls wrappers', () => {
|
|
|
+ assert.match(obfuscatedCode, stringArrayCallRegExp);
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ describe('Variant #2: option value is bigger then count `literal` nodes in the scope', () => {
|
|
|
+ const stringArrayCallRegExp: RegExp = new RegExp(
|
|
|
+ 'return _0x([a-f0-9]){4,6};' +
|
|
|
+ '};' +
|
|
|
+ 'const _0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4};' +
|
|
|
+ 'const _0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4};' +
|
|
|
+ 'const _0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4};' +
|
|
|
+ 'const foo *= *_0x([a-f0-9]){4,6}\\(\'0x0\'\\);' +
|
|
|
+ 'const bar *= *_0x([a-f0-9]){4,6}\\(\'0x1\'\\);' +
|
|
|
+ 'const baz *= *_0x([a-f0-9]){4,6}\\(\'0x2\'\\);'
|
|
|
+ );
|
|
|
+
|
|
|
+ let obfuscatedCode: string;
|
|
|
+
|
|
|
+ before(() => {
|
|
|
+ const code: string = readFileAsString(__dirname + '/fixtures/string-array-wrappers-count-const.js');
|
|
|
+
|
|
|
+ obfuscatedCode = JavaScriptObfuscator.obfuscate(
|
|
|
+ code,
|
|
|
+ {
|
|
|
+ ...NO_ADDITIONAL_NODES_PRESET,
|
|
|
+ stringArray: true,
|
|
|
+ stringArrayThreshold: 1,
|
|
|
+ stringArrayWrappersCount: 5
|
|
|
+ }
|
|
|
+ ).getObfuscatedCode();
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should add scope calls wrappers', () => {
|
|
|
+ assert.match(obfuscatedCode, stringArrayCallRegExp);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ describe('Variant #2: function scope', () => {
|
|
|
+ describe('Variant #1: option value is lower then count `literal` nodes in the scope', () => {
|
|
|
+ const stringArrayCallRegExp: RegExp = new RegExp(
|
|
|
+ 'function test *\\( *\\) *{' +
|
|
|
+ 'const _0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4};' +
|
|
|
+ 'const _0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4};' +
|
|
|
+ 'const _0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\\(\'0x3\'\\);' +
|
|
|
+ 'const _0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\\(\'0x4\'\\);' +
|
|
|
+ 'const _0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\\(\'0x5\'\\);' +
|
|
|
+ '}'
|
|
|
+ );
|
|
|
+
|
|
|
+ let obfuscatedCode: string;
|
|
|
+
|
|
|
+ before(() => {
|
|
|
+ const code: string = readFileAsString(__dirname + '/fixtures/string-array-wrappers-count-const.js');
|
|
|
+
|
|
|
+ obfuscatedCode = JavaScriptObfuscator.obfuscate(
|
|
|
+ code,
|
|
|
+ {
|
|
|
+ ...NO_ADDITIONAL_NODES_PRESET,
|
|
|
+ stringArray: true,
|
|
|
+ stringArrayThreshold: 1,
|
|
|
+ stringArrayWrappersCount: 2
|
|
|
+ }
|
|
|
+ ).getObfuscatedCode();
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should add scope calls wrappers', () => {
|
|
|
+ assert.match(obfuscatedCode, stringArrayCallRegExp);
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ describe('Variant #2: option value is bigger then count `literal` nodes in the scope', () => {
|
|
|
+ const stringArrayCallRegExp: RegExp = new RegExp(
|
|
|
+ 'function test *\\(\\) *{' +
|
|
|
+ 'const _0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4};' +
|
|
|
+ 'const _0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4};' +
|
|
|
+ 'const _0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4};' +
|
|
|
+ 'const _0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\\(\'0x3\'\\);' +
|
|
|
+ 'const _0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\\(\'0x4\'\\);' +
|
|
|
+ 'const _0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\\(\'0x5\'\\);' +
|
|
|
+ '}'
|
|
|
+ );
|
|
|
+
|
|
|
+ let obfuscatedCode: string;
|
|
|
+
|
|
|
+ before(() => {
|
|
|
+ const code: string = readFileAsString(__dirname + '/fixtures/string-array-wrappers-count-const.js');
|
|
|
+
|
|
|
+ obfuscatedCode = JavaScriptObfuscator.obfuscate(
|
|
|
+ code,
|
|
|
+ {
|
|
|
+ ...NO_ADDITIONAL_NODES_PRESET,
|
|
|
+ stringArray: true,
|
|
|
+ stringArrayThreshold: 1,
|
|
|
+ stringArrayWrappersCount: 5
|
|
|
+ }
|
|
|
+ ).getObfuscatedCode();
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should add scope calls wrappers', () => {
|
|
|
+ assert.match(obfuscatedCode, stringArrayCallRegExp);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ describe('Variant #3: prevailing kind of variables', () => {
|
|
|
const stringArrayCallRegExp: RegExp = new RegExp(
|
|
|
'return _0x([a-f0-9]){4,6};' +
|
|
|
'};' +
|
|
|
- 'var _0x([a-f0-9]){4} *= *_0x([a-f0-9]){4};' +
|
|
|
- 'var _0x([a-f0-9]){4} *= *_0x([a-f0-9]){4};' +
|
|
|
- 'var _0x([a-f0-9]){4} *= *_0x([a-f0-9]){4};' +
|
|
|
- 'var test *= *_0x([a-f0-9]){4}\\(\'0x0\'\\);'
|
|
|
+ 'var _0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4};' +
|
|
|
+ 'var _0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4};' +
|
|
|
+ 'var foo *= *_0x([a-f0-9]){4,6}\\(\'0x0\'\\);' +
|
|
|
+ 'var bar *= *_0x([a-f0-9]){4,6}\\(\'0x1\'\\);' +
|
|
|
+ 'var baz *= *_0x([a-f0-9]){4,6}\\(\'0x2\'\\);'
|
|
|
);
|
|
|
|
|
|
let obfuscatedCode: string;
|
|
|
|
|
|
before(() => {
|
|
|
- const code: string = readFileAsString(__dirname + '/fixtures/simple-input.js');
|
|
|
+ const code: string = readFileAsString(__dirname + '/fixtures/string-array-wrappers-count-var.js');
|
|
|
|
|
|
obfuscatedCode = JavaScriptObfuscator.obfuscate(
|
|
|
code,
|
|
@@ -85,22 +220,22 @@ describe('StringArrayTransformer', function () {
|
|
|
...NO_ADDITIONAL_NODES_PRESET,
|
|
|
stringArray: true,
|
|
|
stringArrayThreshold: 1,
|
|
|
- stringArrayIntermediateVariablesCount: 3
|
|
|
+ stringArrayWrappersCount: 2
|
|
|
}
|
|
|
).getObfuscatedCode();
|
|
|
});
|
|
|
|
|
|
- it('should add intermediate calls to the string array calls wrapper', () => {
|
|
|
+ it('should add scope calls wrappers with a correct variables kind', () => {
|
|
|
assert.match(obfuscatedCode, stringArrayCallRegExp);
|
|
|
});
|
|
|
});
|
|
|
|
|
|
- describe('Variant #2: correct evaluation of the intermediate calls', () => {
|
|
|
- const expectedEvaluationResult: number = 15;
|
|
|
- let evaluationResult: number;
|
|
|
+ describe('Variant #4: correct evaluation of the scope calls wrappers', () => {
|
|
|
+ const expectedEvaluationResult: string = 'aaabbbcccdddeee';
|
|
|
+ let evaluationResult: string;
|
|
|
|
|
|
before(() => {
|
|
|
- const code: string = readFileAsString(__dirname + '/fixtures/intermediate-variables-count-eval.js');
|
|
|
+ const code: string = readFileAsString(__dirname + '/fixtures/string-array-wrappers-count-eval.js');
|
|
|
|
|
|
const obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
|
|
|
code,
|
|
@@ -108,17 +243,57 @@ describe('StringArrayTransformer', function () {
|
|
|
...NO_ADDITIONAL_NODES_PRESET,
|
|
|
stringArray: true,
|
|
|
stringArrayThreshold: 1,
|
|
|
- stringArrayIntermediateVariablesCount: 5
|
|
|
+ stringArrayWrappersCount: 5
|
|
|
}
|
|
|
).getObfuscatedCode();
|
|
|
|
|
|
evaluationResult = eval(obfuscatedCode);
|
|
|
});
|
|
|
|
|
|
- it('should correctly evaluate intermediate calls', () => {
|
|
|
+ it('should correctly evaluate scope calls wrappers', () => {
|
|
|
assert.equal(evaluationResult, expectedEvaluationResult);
|
|
|
});
|
|
|
});
|
|
|
+
|
|
|
+ describe('Variant #5: `stringArrayWrappersChainedCalls` option is enabled', () => {
|
|
|
+ describe('Variant #1: correct evaluation of the string array wrappers chained calls', () => {
|
|
|
+ const samplesCount: number = 50;
|
|
|
+ const expectedEvaluationResult: string = 'aaabbbcccdddeee';
|
|
|
+ let isEvaluationSuccessful: boolean = true;
|
|
|
+
|
|
|
+ before(() => {
|
|
|
+ const code: string = readFileAsString(__dirname + '/fixtures/string-array-wrappers-chained-calls-eval.js');
|
|
|
+
|
|
|
+ for (let i = 0; i < samplesCount; i++) {
|
|
|
+ const obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
|
|
|
+ code,
|
|
|
+ {
|
|
|
+ ...NO_ADDITIONAL_NODES_PRESET,
|
|
|
+ stringArray: true,
|
|
|
+ stringArrayThreshold: 1,
|
|
|
+ stringArrayEncoding: [
|
|
|
+ StringArrayEncoding.None,
|
|
|
+ StringArrayEncoding.Rc4
|
|
|
+ ],
|
|
|
+ stringArrayWrappersChainedCalls: true,
|
|
|
+ stringArrayWrappersCount: 5
|
|
|
+ }
|
|
|
+ ).getObfuscatedCode();
|
|
|
+
|
|
|
+ const evaluationResult: string = eval(obfuscatedCode);
|
|
|
+
|
|
|
+ if (evaluationResult !== expectedEvaluationResult) {
|
|
|
+ isEvaluationSuccessful = false;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should correctly evaluate string array wrappers chained calls', () => {
|
|
|
+ assert.equal(isEvaluationSuccessful, true);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ });
|
|
|
});
|
|
|
|
|
|
describe('Variant #4: string contains non-latin and non-digit characters and `unicodeEscapeSequence` is disabled', () => {
|
|
@@ -342,7 +517,7 @@ describe('StringArrayTransformer', function () {
|
|
|
|
|
|
describe('Variant #11: none and base64 encoding', () => {
|
|
|
describe('Variant #1: string array values', () => {
|
|
|
- const samplesCount: number = 100;
|
|
|
+ const samplesCount: number = 300;
|
|
|
const expectedMatchesChance: number = 0.5;
|
|
|
const expectedMatchesDelta: number = 0.15;
|
|
|
|
|
@@ -395,48 +570,170 @@ describe('StringArrayTransformer', function () {
|
|
|
});
|
|
|
});
|
|
|
|
|
|
- describe('Variant #2: `stringArrayIntermediateVariablesCount` option is enabled', () => {
|
|
|
- const stringArrayIntermediateCallRegExp: RegExp = new RegExp(
|
|
|
- 'return _0x([a-f0-9]){4,6};' +
|
|
|
- '};' +
|
|
|
- 'var _0x([a-f0-9]){4} *= *_0x([a-f0-9]){4};' +
|
|
|
- 'var _0x([a-f0-9]){4} *= *_0x([a-f0-9]){4};' +
|
|
|
- 'var _0x([a-f0-9]){4} *= *_0x([a-f0-9]){4};' +
|
|
|
- 'var _0x([a-f0-9]){4} *= *_0x([a-f0-9]){4};' +
|
|
|
- 'var _0x([a-f0-9]){4} *= *_0x([a-f0-9]){4};' +
|
|
|
- 'var _0x([a-f0-9]){4} *= *_0x([a-f0-9]){4};' +
|
|
|
- 'var test *= *_0x([a-f0-9]){4}\\(\'0x0\'\\);'
|
|
|
- );
|
|
|
-
|
|
|
- let obfuscatedCode: string;
|
|
|
-
|
|
|
- before(() => {
|
|
|
- const code: string = readFileAsString(__dirname + '/fixtures/simple-input.js');
|
|
|
+ describe('Variant #2: `stringArrayWrappersCount` option is enabled', () => {
|
|
|
+ describe('Variant #1: root scope', () => {
|
|
|
+ describe('Variant #1: `1` scope calls wrapper for each encoding type', () => {
|
|
|
+ const stringArrayWrappersRegExp: RegExp = new RegExp(
|
|
|
+ 'return _0x([a-f0-9]){4,6};' +
|
|
|
+ '};' +
|
|
|
+ 'const _0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4};' +
|
|
|
+ // this one may be added or not depends on:
|
|
|
+ // if all literal values encoded with a single encoding or not
|
|
|
+ '(?:const _0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4};)?' +
|
|
|
+ 'const foo *= *_0x([a-f0-9]){4,6}\\(\'0x0\'\\);' +
|
|
|
+ 'const bar *= *_0x([a-f0-9]){4,6}\\(\'0x1\'\\);' +
|
|
|
+ 'const baz *= *_0x([a-f0-9]){4,6}\\(\'0x2\'\\);'
|
|
|
+ );
|
|
|
+
|
|
|
+ let obfuscatedCode: string;
|
|
|
+
|
|
|
+ before(() => {
|
|
|
+ const code: string = readFileAsString(__dirname + '/fixtures/string-array-wrappers-count-const.js');
|
|
|
+
|
|
|
+ obfuscatedCode = JavaScriptObfuscator.obfuscate(
|
|
|
+ code,
|
|
|
+ {
|
|
|
+ ...NO_ADDITIONAL_NODES_PRESET,
|
|
|
+ stringArray: true,
|
|
|
+ stringArrayEncoding: [
|
|
|
+ StringArrayEncoding.None,
|
|
|
+ StringArrayEncoding.Base64
|
|
|
+ ],
|
|
|
+ stringArrayWrappersCount: 1,
|
|
|
+ stringArrayThreshold: 1
|
|
|
+ }
|
|
|
+ ).getObfuscatedCode();
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should add scope calls wrappers for both `none` and `base64` string array wrappers', () => {
|
|
|
+ assert.match(obfuscatedCode, stringArrayWrappersRegExp);
|
|
|
+ });
|
|
|
+ });
|
|
|
|
|
|
- obfuscatedCode = JavaScriptObfuscator.obfuscate(
|
|
|
- code,
|
|
|
- {
|
|
|
- ...NO_ADDITIONAL_NODES_PRESET,
|
|
|
- stringArray: true,
|
|
|
- stringArrayEncoding: [
|
|
|
- StringArrayEncoding.None,
|
|
|
- StringArrayEncoding.Base64
|
|
|
- ],
|
|
|
- stringArrayIntermediateVariablesCount: 3,
|
|
|
- stringArrayThreshold: 1
|
|
|
- }
|
|
|
- ).getObfuscatedCode();
|
|
|
+ describe('Variant #2: `2` scope calls wrappers for each encoding type', () => {
|
|
|
+ const stringArrayWrappersRegExp: RegExp = new RegExp(
|
|
|
+ 'return _0x([a-f0-9]){4,6};' +
|
|
|
+ '};' +
|
|
|
+ 'const _0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4};' +
|
|
|
+ 'const _0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4};' +
|
|
|
+ // this one may be added or not depends on:
|
|
|
+ // if all literal values encoded with a single encoding or not
|
|
|
+ '(?:const _0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4};)?' +
|
|
|
+ 'const foo *= *_0x([a-f0-9]){4,6}\\(\'0x0\'\\);' +
|
|
|
+ 'const bar *= *_0x([a-f0-9]){4,6}\\(\'0x1\'\\);' +
|
|
|
+ 'const baz *= *_0x([a-f0-9]){4,6}\\(\'0x2\'\\);'
|
|
|
+ );
|
|
|
+
|
|
|
+ let obfuscatedCode: string;
|
|
|
+
|
|
|
+ before(() => {
|
|
|
+ const code: string = readFileAsString(__dirname + '/fixtures/string-array-wrappers-count-const.js');
|
|
|
+
|
|
|
+ obfuscatedCode = JavaScriptObfuscator.obfuscate(
|
|
|
+ code,
|
|
|
+ {
|
|
|
+ ...NO_ADDITIONAL_NODES_PRESET,
|
|
|
+ stringArray: true,
|
|
|
+ stringArrayEncoding: [
|
|
|
+ StringArrayEncoding.None,
|
|
|
+ StringArrayEncoding.Base64
|
|
|
+ ],
|
|
|
+ stringArrayWrappersCount: 2,
|
|
|
+ stringArrayThreshold: 1
|
|
|
+ }
|
|
|
+ ).getObfuscatedCode();
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should add scope calls wrappers for both `none` and `base64` string array wrappers', () => {
|
|
|
+ assert.match(obfuscatedCode, stringArrayWrappersRegExp);
|
|
|
+ });
|
|
|
+ });
|
|
|
});
|
|
|
|
|
|
- it('should add intermediate variables for both `none` and `base64` string array wrappers', () => {
|
|
|
- assert.match(obfuscatedCode, stringArrayIntermediateCallRegExp);
|
|
|
+ describe('Variant #2: function scope', () => {
|
|
|
+ describe('Variant #1: `1` scope calls wrapper for each encoding type', () => {
|
|
|
+ const stringArrayWrappersRegExp: RegExp = new RegExp(
|
|
|
+ 'function test *\\( *\\) *{' +
|
|
|
+ 'const _0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4};' +
|
|
|
+ // this one may be added or not depends on:
|
|
|
+ // if all literal values encoded with a single encoding or not
|
|
|
+ '(?:const _0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4};)?' +
|
|
|
+ 'const _0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\\(\'0x3\'\\);' +
|
|
|
+ 'const _0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\\(\'0x4\'\\);' +
|
|
|
+ 'const _0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\\(\'0x5\'\\);' +
|
|
|
+ '}'
|
|
|
+ );
|
|
|
+
|
|
|
+ let obfuscatedCode: string;
|
|
|
+
|
|
|
+ before(() => {
|
|
|
+ const code: string = readFileAsString(__dirname + '/fixtures/string-array-wrappers-count-const.js');
|
|
|
+
|
|
|
+ obfuscatedCode = JavaScriptObfuscator.obfuscate(
|
|
|
+ code,
|
|
|
+ {
|
|
|
+ ...NO_ADDITIONAL_NODES_PRESET,
|
|
|
+ stringArray: true,
|
|
|
+ stringArrayEncoding: [
|
|
|
+ StringArrayEncoding.None,
|
|
|
+ StringArrayEncoding.Base64
|
|
|
+ ],
|
|
|
+ stringArrayWrappersCount: 1,
|
|
|
+ stringArrayThreshold: 1
|
|
|
+ }
|
|
|
+ ).getObfuscatedCode();
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should add scope calls wrappers for both `none` and `base64` string array wrappers', () => {
|
|
|
+ assert.match(obfuscatedCode, stringArrayWrappersRegExp);
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ describe('Variant #2: `2` scope calls wrappers for each encoding type', () => {
|
|
|
+ const stringArrayWrappersRegExp: RegExp = new RegExp(
|
|
|
+ 'function test *\\( *\\) *{' +
|
|
|
+ 'const _0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4};' +
|
|
|
+ 'const _0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4};' +
|
|
|
+ // this one may be added or not depends on:
|
|
|
+ // if all literal values encoded with a single encoding or not
|
|
|
+ '(?:const _0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4};)?' +
|
|
|
+ 'const _0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\\(\'0x3\'\\);' +
|
|
|
+ 'const _0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\\(\'0x4\'\\);' +
|
|
|
+ 'const _0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\\(\'0x5\'\\);' +
|
|
|
+ '}'
|
|
|
+ );
|
|
|
+
|
|
|
+ let obfuscatedCode: string;
|
|
|
+
|
|
|
+ before(() => {
|
|
|
+ const code: string = readFileAsString(__dirname + '/fixtures/string-array-wrappers-count-const.js');
|
|
|
+
|
|
|
+ obfuscatedCode = JavaScriptObfuscator.obfuscate(
|
|
|
+ code,
|
|
|
+ {
|
|
|
+ ...NO_ADDITIONAL_NODES_PRESET,
|
|
|
+ stringArray: true,
|
|
|
+ stringArrayEncoding: [
|
|
|
+ StringArrayEncoding.None,
|
|
|
+ StringArrayEncoding.Base64
|
|
|
+ ],
|
|
|
+ stringArrayWrappersCount: 2,
|
|
|
+ stringArrayThreshold: 1
|
|
|
+ }
|
|
|
+ ).getObfuscatedCode();
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should add scope calls wrappers for both `none` and `base64` string array wrappers', () => {
|
|
|
+ assert.match(obfuscatedCode, stringArrayWrappersRegExp);
|
|
|
+ });
|
|
|
+ });
|
|
|
});
|
|
|
});
|
|
|
});
|
|
|
|
|
|
describe('Variant #12: none and rc4 encoding', () => {
|
|
|
describe('Variant #1: string array calls wrapper call', () => {
|
|
|
- const samplesCount: number = 100;
|
|
|
+ const samplesCount: number = 300;
|
|
|
const expectedMatchesChance: number = 0.5;
|
|
|
const expectedMatchesDelta: number = 0.15;
|
|
|
|
|
@@ -488,11 +785,42 @@ describe('StringArrayTransformer', function () {
|
|
|
assert.closeTo(rc4EncodingMatchesChance, expectedMatchesChance, expectedMatchesDelta);
|
|
|
});
|
|
|
});
|
|
|
+
|
|
|
+ describe('Variant #2: `stringArrayWrappersCount` option is enabled', () => {
|
|
|
+ describe('Variant #1: correct evaluation of the scope calls wrappers', () => {
|
|
|
+ const expectedEvaluationResult: string = 'aaabbbcccdddeee';
|
|
|
+ let evaluationResult: string;
|
|
|
+
|
|
|
+ before(() => {
|
|
|
+ const code: string = readFileAsString(__dirname + '/fixtures/string-array-wrappers-count-eval.js');
|
|
|
+
|
|
|
+ const obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
|
|
|
+ code,
|
|
|
+ {
|
|
|
+ ...NO_ADDITIONAL_NODES_PRESET,
|
|
|
+ stringArray: true,
|
|
|
+ stringArrayThreshold: 1,
|
|
|
+ stringArrayEncoding: [
|
|
|
+ StringArrayEncoding.None,
|
|
|
+ StringArrayEncoding.Rc4
|
|
|
+ ],
|
|
|
+ stringArrayWrappersCount: 5
|
|
|
+ }
|
|
|
+ ).getObfuscatedCode();
|
|
|
+
|
|
|
+ evaluationResult = eval(obfuscatedCode);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should correctly evaluate scope calls wrappers', () => {
|
|
|
+ assert.equal(evaluationResult, expectedEvaluationResult);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ });
|
|
|
});
|
|
|
|
|
|
describe('Variant #13: base64 and rc4 encoding', () => {
|
|
|
describe('Variant #1: single string literal', () => {
|
|
|
- const samplesCount: number = 100;
|
|
|
+ const samplesCount: number = 300;
|
|
|
const expectedMatchesChance: number = 0.5;
|
|
|
const expectedMatchesDelta: number = 0.15;
|
|
|
|
|
@@ -544,6 +872,37 @@ describe('StringArrayTransformer', function () {
|
|
|
assert.closeTo(rc4EncodingMatchesChance, expectedMatchesChance, expectedMatchesDelta);
|
|
|
});
|
|
|
});
|
|
|
+
|
|
|
+ describe('Variant #2: `stringArrayWrappersCount` option is enabled', () => {
|
|
|
+ describe('Variant #1: correct evaluation of the scope calls wrappers', () => {
|
|
|
+ const expectedEvaluationResult: string = 'aaabbbcccdddeee';
|
|
|
+ let evaluationResult: string;
|
|
|
+
|
|
|
+ before(() => {
|
|
|
+ const code: string = readFileAsString(__dirname + '/fixtures/string-array-wrappers-count-eval.js');
|
|
|
+
|
|
|
+ const obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
|
|
|
+ code,
|
|
|
+ {
|
|
|
+ ...NO_ADDITIONAL_NODES_PRESET,
|
|
|
+ stringArray: true,
|
|
|
+ stringArrayThreshold: 1,
|
|
|
+ stringArrayEncoding: [
|
|
|
+ StringArrayEncoding.Base64,
|
|
|
+ StringArrayEncoding.Rc4
|
|
|
+ ],
|
|
|
+ stringArrayWrappersCount: 5
|
|
|
+ }
|
|
|
+ ).getObfuscatedCode();
|
|
|
+
|
|
|
+ evaluationResult = eval(obfuscatedCode);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should correctly evaluate scope calls wrappers', () => {
|
|
|
+ assert.equal(evaluationResult, expectedEvaluationResult);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ });
|
|
|
});
|
|
|
|
|
|
describe('Variant #14: `stringArrayThreshold` option value', () => {
|