|
@@ -63,537 +63,7 @@ describe('StringArrayTransformer', function () {
|
|
|
});
|
|
|
});
|
|
|
|
|
|
- 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 #3: correct wrappers order', () => {
|
|
|
- const stringArrayCallRegExp: RegExp = new RegExp(
|
|
|
- 'const f *= *b;' +
|
|
|
- 'const g *= *b;' +
|
|
|
- 'const foo *= *[f|g]\\(\'0x0\'\\);' +
|
|
|
- 'const bar *= *[f|g]\\(\'0x1\'\\);' +
|
|
|
- 'const baz *= *[f|g]\\(\'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,
|
|
|
- identifierNamesGenerator: IdentifierNamesGenerator.MangledIdentifierNamesGenerator,
|
|
|
- stringArray: true,
|
|
|
- stringArrayThreshold: 1,
|
|
|
- stringArrayWrappersCount: 2
|
|
|
- }
|
|
|
- ).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: correct wrappers order', () => {
|
|
|
- const stringArrayCallRegExp: RegExp = new RegExp(
|
|
|
- 'function test *\\( *\\) *{' +
|
|
|
- 'const h *= *b;' +
|
|
|
- 'const i *= *b;' +
|
|
|
- 'const c *= *[h|i]\\(\'0x3\'\\);' +
|
|
|
- 'const d *= *[h|i]\\(\'0x4\'\\);' +
|
|
|
- 'const e *= *[h|i]\\(\'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,
|
|
|
- identifierNamesGenerator: IdentifierNamesGenerator.MangledIdentifierNamesGenerator,
|
|
|
- stringArray: true,
|
|
|
- stringArrayThreshold: 1,
|
|
|
- stringArrayWrappersCount: 2
|
|
|
- }
|
|
|
- ).getObfuscatedCode();
|
|
|
- });
|
|
|
-
|
|
|
- it('should add scope calls wrappers', () => {
|
|
|
- assert.match(obfuscatedCode, stringArrayCallRegExp);
|
|
|
- });
|
|
|
- });
|
|
|
- });
|
|
|
-
|
|
|
- describe('Variant #3: prohibited scopes', () => {
|
|
|
- describe('Variant #1: if statement scope', () => {
|
|
|
- const stringArrayCallRegExp: RegExp = new RegExp(
|
|
|
- 'var c *= *b;' +
|
|
|
- 'if *\\(!!\\[]\\) *{' +
|
|
|
- 'var foo *= *c\\(\'0x0\'\\);' +
|
|
|
- '}'
|
|
|
- );
|
|
|
-
|
|
|
- let obfuscatedCode: string;
|
|
|
-
|
|
|
- before(() => {
|
|
|
- const code: string = readFileAsString(__dirname + '/fixtures/string-array-wrappers-count-prohibited-scope-1.js');
|
|
|
-
|
|
|
- obfuscatedCode = JavaScriptObfuscator.obfuscate(
|
|
|
- code,
|
|
|
- {
|
|
|
- ...NO_ADDITIONAL_NODES_PRESET,
|
|
|
- identifierNamesGenerator: IdentifierNamesGenerator.MangledIdentifierNamesGenerator,
|
|
|
- stringArray: true,
|
|
|
- stringArrayThreshold: 1,
|
|
|
- stringArrayWrappersCount: 1
|
|
|
- }
|
|
|
- ).getObfuscatedCode();
|
|
|
- });
|
|
|
-
|
|
|
- it('should not add scope calls wrappers to a prohibited scope', () => {
|
|
|
- assert.match(obfuscatedCode, stringArrayCallRegExp);
|
|
|
- });
|
|
|
- });
|
|
|
-
|
|
|
- describe('Variant #2: arrow function scope without statements', () => {
|
|
|
- const stringArrayCallRegExp: RegExp = new RegExp(
|
|
|
- 'var c *= *b;' +
|
|
|
- '\\[]\\[c\\(\'0x0\'\\)]\\(\\(\\) *=> *c\\(\'0x1\'\\)\\);'
|
|
|
- );
|
|
|
-
|
|
|
- let obfuscatedCode: string;
|
|
|
-
|
|
|
- before(() => {
|
|
|
- const code: string = readFileAsString(__dirname + '/fixtures/string-array-wrappers-count-prohibited-scope-2.js');
|
|
|
-
|
|
|
- obfuscatedCode = JavaScriptObfuscator.obfuscate(
|
|
|
- code,
|
|
|
- {
|
|
|
- ...NO_ADDITIONAL_NODES_PRESET,
|
|
|
- identifierNamesGenerator: IdentifierNamesGenerator.MangledIdentifierNamesGenerator,
|
|
|
- stringArray: true,
|
|
|
- stringArrayThreshold: 1,
|
|
|
- stringArrayWrappersCount: 1
|
|
|
- }
|
|
|
- ).getObfuscatedCode();
|
|
|
- });
|
|
|
-
|
|
|
- it('should not add scope calls wrappers to a prohibited scope', () => {
|
|
|
- assert.match(obfuscatedCode, stringArrayCallRegExp);
|
|
|
- });
|
|
|
- });
|
|
|
- });
|
|
|
-
|
|
|
- describe('Variant #4: prevailing kind of variables', () => {
|
|
|
- const stringArrayCallRegExp: RegExp = new RegExp(
|
|
|
- 'return _0x([a-f0-9]){4,6};' +
|
|
|
- '};' +
|
|
|
- '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/string-array-wrappers-count-var.js');
|
|
|
-
|
|
|
- obfuscatedCode = JavaScriptObfuscator.obfuscate(
|
|
|
- code,
|
|
|
- {
|
|
|
- ...NO_ADDITIONAL_NODES_PRESET,
|
|
|
- stringArray: true,
|
|
|
- stringArrayThreshold: 1,
|
|
|
- stringArrayWrappersCount: 2
|
|
|
- }
|
|
|
- ).getObfuscatedCode();
|
|
|
- });
|
|
|
-
|
|
|
- it('should add scope calls wrappers with a correct variables kind', () => {
|
|
|
- assert.match(obfuscatedCode, stringArrayCallRegExp);
|
|
|
- });
|
|
|
- });
|
|
|
-
|
|
|
- describe('Variant #5: 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,
|
|
|
- stringArrayWrappersCount: 5
|
|
|
- }
|
|
|
- ).getObfuscatedCode();
|
|
|
-
|
|
|
- evaluationResult = eval(obfuscatedCode);
|
|
|
- });
|
|
|
-
|
|
|
- it('should correctly evaluate scope calls wrappers', () => {
|
|
|
- assert.equal(evaluationResult, expectedEvaluationResult);
|
|
|
- });
|
|
|
- });
|
|
|
-
|
|
|
- describe('Variant #6: `stringArrayWrappersChainedCalls` option is enabled', () => {
|
|
|
- describe('Variant #1: correct chained calls', () => {
|
|
|
- describe('Variant #1: `Mangled` identifier names generator', () => {
|
|
|
- const stringArrayCallRegExp: RegExp = new RegExp(
|
|
|
- 'const q *= *b;' +
|
|
|
- 'const foo *= *q\\(\'0x0\'\\);' +
|
|
|
- 'function test\\(c, *d\\) *{' +
|
|
|
- 'const r *= *q;' +
|
|
|
- 'const e *= *r\\(\'0x1\'\\);' +
|
|
|
- 'const f *= *r\\(\'0x2\'\\);' +
|
|
|
- 'function g\\(h, *i\\) *{' +
|
|
|
- 'const s *= *r;' +
|
|
|
- 'const j *= *s\\(\'0x3\'\\);' +
|
|
|
- 'const k *= *s\\(\'0x4\'\\);' +
|
|
|
- 'function l\\(m, *n *\\) *{' +
|
|
|
- 'const t *= *s;' +
|
|
|
- 'const o *= *t\\(\'0x3\'\\);' +
|
|
|
- 'const p *= *t\\(\'0x4\'\\);' +
|
|
|
- 'return o *\\+ *p;' +
|
|
|
- '}' +
|
|
|
- 'return j *\\+ *k;' +
|
|
|
- '}' +
|
|
|
- 'return e *\\+ *f *\\+ *g\\(\\);' +
|
|
|
- '}'
|
|
|
- );
|
|
|
-
|
|
|
- let obfuscatedCode: string;
|
|
|
-
|
|
|
- before(() => {
|
|
|
- const code: string = readFileAsString(__dirname + '/fixtures/string-array-wrappers-chained-calls-1.js');
|
|
|
-
|
|
|
- obfuscatedCode = JavaScriptObfuscator.obfuscate(
|
|
|
- code,
|
|
|
- {
|
|
|
- ...NO_ADDITIONAL_NODES_PRESET,
|
|
|
- identifierNamesGenerator: IdentifierNamesGenerator.MangledIdentifierNamesGenerator,
|
|
|
- stringArray: true,
|
|
|
- stringArrayThreshold: 1,
|
|
|
- stringArrayWrappersChainedCalls: true,
|
|
|
- stringArrayWrappersCount: 1
|
|
|
- }
|
|
|
- ).getObfuscatedCode();
|
|
|
- });
|
|
|
-
|
|
|
- it('should add correct scope calls wrappers', () => {
|
|
|
- assert.match(obfuscatedCode, stringArrayCallRegExp);
|
|
|
- });
|
|
|
- });
|
|
|
- });
|
|
|
-
|
|
|
- describe('Variant #2: correct evaluation of the string array wrappers chained calls', () => {
|
|
|
- describe('Variant #1: base', () => {
|
|
|
- describe('Variant #1: `Hexadecimal` identifier names generator', () => {
|
|
|
- const samplesCount: number = 50;
|
|
|
- const expectedEvaluationResult: string = 'aaabbbcccdddeee';
|
|
|
- let isEvaluationSuccessful: boolean = true;
|
|
|
-
|
|
|
- before(() => {
|
|
|
- const code: string = readFileAsString(__dirname + '/fixtures/string-array-wrappers-chained-calls-1.js');
|
|
|
-
|
|
|
- for (let i = 0; i < samplesCount; i++) {
|
|
|
- const obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
|
|
|
- code,
|
|
|
- {
|
|
|
- ...NO_ADDITIONAL_NODES_PRESET,
|
|
|
- identifierNamesGenerator: IdentifierNamesGenerator.HexadecimalIdentifierNamesGenerator,
|
|
|
- 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 #2: `Mangled` identifier names generator', () => {
|
|
|
- const samplesCount: number = 50;
|
|
|
- const expectedEvaluationResult: string = 'aaabbbcccdddeee';
|
|
|
- let isEvaluationSuccessful: boolean = true;
|
|
|
-
|
|
|
- before(() => {
|
|
|
- const code: string = readFileAsString(__dirname + '/fixtures/string-array-wrappers-chained-calls-1.js');
|
|
|
-
|
|
|
- for (let i = 0; i < samplesCount; i++) {
|
|
|
- const obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
|
|
|
- code,
|
|
|
- {
|
|
|
- ...NO_ADDITIONAL_NODES_PRESET,
|
|
|
- identifierNamesGenerator: IdentifierNamesGenerator.MangledIdentifierNamesGenerator,
|
|
|
- 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 #2: advanced', () => {
|
|
|
- describe('Variant #1: `Hexadecimal` identifier names generator', () => {
|
|
|
- const samplesCount: number = 50;
|
|
|
- const expectedEvaluationResult: string = 'aaabbbcccdddeee';
|
|
|
- let isEvaluationSuccessful: boolean = true;
|
|
|
-
|
|
|
- before(() => {
|
|
|
- const code: string = readFileAsString(__dirname + '/fixtures/string-array-wrappers-chained-calls-2.js');
|
|
|
-
|
|
|
- for (let i = 0; i < samplesCount; i++) {
|
|
|
- const obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
|
|
|
- code,
|
|
|
- {
|
|
|
- ...NO_ADDITIONAL_NODES_PRESET,
|
|
|
- identifierNamesGenerator: IdentifierNamesGenerator.HexadecimalIdentifierNamesGenerator,
|
|
|
- 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 #2: `Mangled` identifier names generator', () => {
|
|
|
- const samplesCount: number = 50;
|
|
|
- const expectedEvaluationResult: string = 'aaabbbcccdddeee';
|
|
|
- let isEvaluationSuccessful: boolean = true;
|
|
|
-
|
|
|
- before(() => {
|
|
|
- const code: string = readFileAsString(__dirname + '/fixtures/string-array-wrappers-chained-calls-2.js');
|
|
|
-
|
|
|
- for (let i = 0; i < samplesCount; i++) {
|
|
|
- const obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
|
|
|
- code,
|
|
|
- {
|
|
|
- ...NO_ADDITIONAL_NODES_PRESET,
|
|
|
- identifierNamesGenerator: IdentifierNamesGenerator.MangledIdentifierNamesGenerator,
|
|
|
- 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', () => {
|
|
|
+ describe('Variant #3: string contains non-latin and non-digit characters and `unicodeEscapeSequence` is disabled', () => {
|
|
|
let testFunc: () => void;
|
|
|
|
|
|
before(() => {
|
|
@@ -614,7 +84,7 @@ describe('StringArrayTransformer', function () {
|
|
|
});
|
|
|
});
|
|
|
|
|
|
- describe('Variant #5: same literal node values', () => {
|
|
|
+ describe('Variant #4: same literal node values', () => {
|
|
|
const stringArrayRegExp: RegExp = /^var _0x([a-f0-9]){4} *= *\['test'\];/;
|
|
|
const stringArrayCallRegExp: RegExp = /var test *= *_0x([a-f0-9]){4}\('0x0'\);/;
|
|
|
|
|
@@ -642,7 +112,7 @@ describe('StringArrayTransformer', function () {
|
|
|
});
|
|
|
});
|
|
|
|
|
|
- describe('Variant #6: `unicodeEscapeSequence` option is enabled', () => {
|
|
|
+ describe('Variant #5: `unicodeEscapeSequence` option is enabled', () => {
|
|
|
const regExp: RegExp = /^var test *= *'\\x74\\x65\\x73\\x74';$/;
|
|
|
|
|
|
let obfuscatedCode: string;
|
|
@@ -665,7 +135,7 @@ describe('StringArrayTransformer', function () {
|
|
|
});
|
|
|
});
|
|
|
|
|
|
- describe('Variant #7: `unicodeEscapeSequence` and `stringArray` options are enabled', () => {
|
|
|
+ describe('Variant #6: `unicodeEscapeSequence` and `stringArray` options are enabled', () => {
|
|
|
const stringArrayRegExp: RegExp = /^var _0x([a-f0-9]){4} *= *\['\\x74\\x65\\x73\\x74'\];/;
|
|
|
const stringArrayCallRegExp: RegExp = /var test *= *_0x([a-f0-9]){4}\('\\x30\\x78\\x30'\);/;
|
|
|
|
|
@@ -694,7 +164,7 @@ describe('StringArrayTransformer', function () {
|
|
|
});
|
|
|
});
|
|
|
|
|
|
- describe('Variant #8: short literal node value', () => {
|
|
|
+ describe('Variant #7: short literal node value', () => {
|
|
|
const regExp: RegExp = /var test *= *'te';/;
|
|
|
|
|
|
let obfuscatedCode: string;
|
|
@@ -717,7 +187,7 @@ describe('StringArrayTransformer', function () {
|
|
|
});
|
|
|
});
|
|
|
|
|
|
- describe('Variant #9: base64 encoding', () => {
|
|
|
+ describe('Variant #8: base64 encoding', () => {
|
|
|
const stringArrayRegExp: RegExp = new RegExp(`^var _0x([a-f0-9]){4} *= *\\['${swapLettersCase('dGVzdA==')}'];`);
|
|
|
const stringArrayCallRegExp: RegExp = /var test *= *_0x([a-f0-9]){4}\('0x0'\);/;
|
|
|
|
|
@@ -746,7 +216,7 @@ describe('StringArrayTransformer', function () {
|
|
|
});
|
|
|
});
|
|
|
|
|
|
- describe('Variant #10: rc4 encoding', () => {
|
|
|
+ describe('Variant #9: rc4 encoding', () => {
|
|
|
describe('Variant #1: single string literal', () => {
|
|
|
const regExp: RegExp = /var test *= *_0x([a-f0-9]){4}\('0x0', *'.{4}'\);/;
|
|
|
|
|
@@ -812,7 +282,7 @@ describe('StringArrayTransformer', function () {
|
|
|
});
|
|
|
});
|
|
|
|
|
|
- describe('Variant #11: none and base64 encoding', () => {
|
|
|
+ describe('Variant #10: none and base64 encoding', () => {
|
|
|
describe('Variant #1: string array values', () => {
|
|
|
const samplesCount: number = 300;
|
|
|
const expectedMatchesChance: number = 0.5;
|
|
@@ -866,169 +336,9 @@ describe('StringArrayTransformer', function () {
|
|
|
assert.closeTo(base64EncodingMatchesChance, expectedMatchesChance, expectedMatchesDelta);
|
|
|
});
|
|
|
});
|
|
|
-
|
|
|
- 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);
|
|
|
- });
|
|
|
- });
|
|
|
-
|
|
|
- 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);
|
|
|
- });
|
|
|
- });
|
|
|
- });
|
|
|
-
|
|
|
- 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 #11: none and rc4 encoding', () => {
|
|
|
describe('Variant #1: string array calls wrapper call', () => {
|
|
|
const samplesCount: number = 300;
|
|
|
const expectedMatchesChance: number = 0.5;
|
|
@@ -1082,40 +392,9 @@ 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 #12: base64 and rc4 encoding', () => {
|
|
|
describe('Variant #1: single string literal', () => {
|
|
|
const samplesCount: number = 300;
|
|
|
const expectedMatchesChance: number = 0.5;
|
|
@@ -1169,40 +448,9 @@ 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', () => {
|
|
|
+ describe('Variant #13: `stringArrayThreshold` option value', () => {
|
|
|
const samples: number = 1000;
|
|
|
const stringArrayThreshold: number = 0.5;
|
|
|
const delta: number = 0.1;
|
|
@@ -1245,7 +493,7 @@ describe('StringArrayTransformer', function () {
|
|
|
});
|
|
|
});
|
|
|
|
|
|
- describe('Variant #15: string array calls wrapper name', () => {
|
|
|
+ describe('Variant #14: string array calls wrapper name', () => {
|
|
|
const regExp: RegExp = /console\[b\('0x0'\)]\('a'\);/;
|
|
|
|
|
|
let obfuscatedCode: string;
|
|
@@ -1269,7 +517,7 @@ describe('StringArrayTransformer', function () {
|
|
|
});
|
|
|
});
|
|
|
|
|
|
- describe('Variant #16: `reservedStrings` option is enabled', () => {
|
|
|
+ describe('Variant #15: `reservedStrings` option is enabled', () => {
|
|
|
describe('Variant #1: base `reservedStrings` values', () => {
|
|
|
describe('Variant #1: single reserved string value', () => {
|
|
|
const stringLiteralRegExp1: RegExp = /const foo *= *'foo';/;
|
|
@@ -1441,7 +689,7 @@ describe('StringArrayTransformer', function () {
|
|
|
});
|
|
|
});
|
|
|
|
|
|
- describe('Variant #17: object expression key literal', () => {
|
|
|
+ describe('Variant #16: object expression key literal', () => {
|
|
|
describe('Variant #1: base key literal', () => {
|
|
|
const stringArrayRegExp: RegExp = /^var _0x([a-f0-9]){4} *= *\['bar'];/;
|
|
|
const objectExpressionRegExp: RegExp = /var test *= *{'foo' *: *_0x([a-f0-9]){4}\('0x0'\)};/;
|
|
@@ -1499,7 +747,7 @@ describe('StringArrayTransformer', function () {
|
|
|
});
|
|
|
});
|
|
|
|
|
|
- describe('Variant #18: import declaration source literal', () => {
|
|
|
+ describe('Variant #17: import declaration source literal', () => {
|
|
|
const importDeclarationRegExp: RegExp = /import *{ *bar *} *from *'foo';/;
|
|
|
|
|
|
let obfuscatedCode: string;
|
|
@@ -1522,7 +770,7 @@ describe('StringArrayTransformer', function () {
|
|
|
});
|
|
|
});
|
|
|
|
|
|
- describe('Variant #19: export all declaration source literal', () => {
|
|
|
+ describe('Variant #18: export all declaration source literal', () => {
|
|
|
const exportAllDeclarationRegExp: RegExp = /export *\* *from *'foo';/;
|
|
|
|
|
|
let obfuscatedCode: string;
|
|
@@ -1545,7 +793,7 @@ describe('StringArrayTransformer', function () {
|
|
|
});
|
|
|
});
|
|
|
|
|
|
- describe('Variant #20: export named declaration source literal', () => {
|
|
|
+ describe('Variant #19: export named declaration source literal', () => {
|
|
|
const exportNamedDeclarationRegExp: RegExp = /export *{ *bar *} *from *'foo';/;
|
|
|
|
|
|
let obfuscatedCode: string;
|