|
@@ -11,7 +11,9 @@ import { swapLettersCase } from '../../../../helpers/swapLettersCase';
|
|
|
|
|
|
import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
|
|
|
|
|
|
-describe('StringArrayTransformer', () => {
|
|
|
+describe('StringArrayTransformer', function () {
|
|
|
+ this.timeout(60000);
|
|
|
+
|
|
|
describe('Variant #1: default behaviour', () => {
|
|
|
const stringArrayRegExp: RegExp = /^var _0x([a-f0-9]){4} *= *\['test'\];/;
|
|
|
const stringArrayCallRegExp: RegExp = /var test *= *_0x([a-f0-9]){4}\('0x0'\);/;
|
|
@@ -199,7 +201,7 @@ describe('StringArrayTransformer', () => {
|
|
|
{
|
|
|
...NO_ADDITIONAL_NODES_PRESET,
|
|
|
stringArray: true,
|
|
|
- stringArrayEncoding: StringArrayEncoding.Base64,
|
|
|
+ stringArrayEncoding: [StringArrayEncoding.Base64],
|
|
|
stringArrayThreshold: 1
|
|
|
}
|
|
|
).getObfuscatedCode();
|
|
@@ -228,7 +230,7 @@ describe('StringArrayTransformer', () => {
|
|
|
{
|
|
|
...NO_ADDITIONAL_NODES_PRESET,
|
|
|
stringArray: true,
|
|
|
- stringArrayEncoding: StringArrayEncoding.Rc4,
|
|
|
+ stringArrayEncoding: [StringArrayEncoding.Rc4],
|
|
|
stringArrayThreshold: 1
|
|
|
}
|
|
|
).getObfuscatedCode();
|
|
@@ -257,7 +259,7 @@ describe('StringArrayTransformer', () => {
|
|
|
...NO_ADDITIONAL_NODES_PRESET,
|
|
|
seed: 1, // set seed to prevent rare case when all encoded values are the same
|
|
|
stringArray: true,
|
|
|
- stringArrayEncoding: StringArrayEncoding.Rc4,
|
|
|
+ stringArrayEncoding: [StringArrayEncoding.Rc4],
|
|
|
stringArrayThreshold: 1
|
|
|
}
|
|
|
).getObfuscatedCode();
|
|
@@ -280,7 +282,175 @@ describe('StringArrayTransformer', () => {
|
|
|
});
|
|
|
});
|
|
|
|
|
|
- describe('Variant #10: `stringArrayThreshold` option value', () => {
|
|
|
+ describe('Variant #10: none and base64 encoding', () => {
|
|
|
+ describe('Variant #1: string array values', () => {
|
|
|
+ const samplesCount: number = 100;
|
|
|
+ const expectedMatchesChance: number = 0.5;
|
|
|
+ const expectedMatchesDelta: number = 0.15;
|
|
|
+
|
|
|
+ const noneEncodingRegExp: RegExp = /^var _0x([a-f0-9]){4} *= *\['test'\];/;
|
|
|
+ const base64EncodingRegExp: RegExp = /^var _0x([a-f0-9]){4} *= *\['DgvZDa=='\];/;
|
|
|
+
|
|
|
+ let noneEncodingMatchesCount: number = 0;
|
|
|
+ let base64EncodingMatchesCount: number = 0;
|
|
|
+ let obfuscatedCode: string;
|
|
|
+
|
|
|
+ let noneEncodingMatchesChance: number;
|
|
|
+ let base64EncodingMatchesChance: number;
|
|
|
+
|
|
|
+ before(() => {
|
|
|
+ const code: string = readFileAsString(__dirname + '/fixtures/simple-input.js');
|
|
|
+
|
|
|
+ for (let i = 0; i < samplesCount; i++) {
|
|
|
+ obfuscatedCode = JavaScriptObfuscator.obfuscate(
|
|
|
+ code,
|
|
|
+ {
|
|
|
+ ...NO_ADDITIONAL_NODES_PRESET,
|
|
|
+ stringArray: true,
|
|
|
+ stringArrayEncoding: [
|
|
|
+ StringArrayEncoding.None,
|
|
|
+ StringArrayEncoding.Base64
|
|
|
+ ],
|
|
|
+ stringArrayThreshold: 1
|
|
|
+ }
|
|
|
+ ).getObfuscatedCode();
|
|
|
+
|
|
|
+ if (obfuscatedCode.match(noneEncodingRegExp)) {
|
|
|
+ noneEncodingMatchesCount = noneEncodingMatchesCount + 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (obfuscatedCode.match(base64EncodingRegExp)) {
|
|
|
+ base64EncodingMatchesCount = base64EncodingMatchesCount + 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ noneEncodingMatchesChance = noneEncodingMatchesCount / samplesCount;
|
|
|
+ base64EncodingMatchesChance = base64EncodingMatchesCount / samplesCount;
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should add literal node value to the string array without encoding', () => {
|
|
|
+ assert.closeTo(noneEncodingMatchesChance, expectedMatchesChance, expectedMatchesDelta);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should add literal node value to the string array encoded using base64', () => {
|
|
|
+ assert.closeTo(base64EncodingMatchesChance, expectedMatchesChance, expectedMatchesDelta);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ describe('Variant #11: none and rc4 encoding', () => {
|
|
|
+ describe('Variant #1: string array calls wrapper call', () => {
|
|
|
+ const samplesCount: number = 100;
|
|
|
+ const expectedMatchesChance: number = 0.5;
|
|
|
+ const expectedMatchesDelta: number = 0.15;
|
|
|
+
|
|
|
+ const noneEncodingRegExp: RegExp = /var test *= *_0x([a-f0-9]){4}\('0x0'\);/;
|
|
|
+ const rc4EncodingRegExp: RegExp = /var test *= *_0x([a-f0-9]){4}\('0x0', *'.{4}'\);/;
|
|
|
+
|
|
|
+ let noneEncodingMatchesCount: number = 0;
|
|
|
+ let rc4EncodingMatchesCount: number = 0;
|
|
|
+ let obfuscatedCode: string;
|
|
|
+
|
|
|
+ let noneEncodingMatchesChance: number;
|
|
|
+ let rc4EncodingMatchesChance: number;
|
|
|
+
|
|
|
+ before(() => {
|
|
|
+ const code: string = readFileAsString(__dirname + '/fixtures/simple-input.js');
|
|
|
+
|
|
|
+ for (let i = 0; i < samplesCount; i++) {
|
|
|
+ obfuscatedCode = JavaScriptObfuscator.obfuscate(
|
|
|
+ code,
|
|
|
+ {
|
|
|
+ ...NO_ADDITIONAL_NODES_PRESET,
|
|
|
+ stringArray: true,
|
|
|
+ stringArrayEncoding: [
|
|
|
+ StringArrayEncoding.None,
|
|
|
+ StringArrayEncoding.Rc4
|
|
|
+ ],
|
|
|
+ stringArrayThreshold: 1
|
|
|
+ }
|
|
|
+ ).getObfuscatedCode();
|
|
|
+
|
|
|
+ if (obfuscatedCode.match(noneEncodingRegExp)) {
|
|
|
+ noneEncodingMatchesCount = noneEncodingMatchesCount + 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (obfuscatedCode.match(rc4EncodingRegExp)) {
|
|
|
+ rc4EncodingMatchesCount = rc4EncodingMatchesCount + 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ noneEncodingMatchesChance = noneEncodingMatchesCount / samplesCount;
|
|
|
+ rc4EncodingMatchesChance = rc4EncodingMatchesCount / samplesCount;
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should replace literal node value with value from string array without encoding', () => {
|
|
|
+ assert.closeTo(noneEncodingMatchesChance, expectedMatchesChance, expectedMatchesDelta);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should replace literal node value with value from string array encoded using rc4', () => {
|
|
|
+ assert.closeTo(rc4EncodingMatchesChance, expectedMatchesChance, expectedMatchesDelta);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ describe('Variant #12: base64 and rc4 encoding', () => {
|
|
|
+ describe('Variant #1: single string literal', () => {
|
|
|
+ const samplesCount: number = 100;
|
|
|
+ const expectedMatchesChance: number = 0.5;
|
|
|
+ const expectedMatchesDelta: number = 0.15;
|
|
|
+
|
|
|
+ const base64EncodingRegExp: RegExp = /var test *= *_0x([a-f0-9]){4}\('0x0'\);/;
|
|
|
+ const rc4EncodingRegExp: RegExp = /var test *= *_0x([a-f0-9]){4}\('0x0', *'.{4}'\);/;
|
|
|
+
|
|
|
+ let base64EncodingMatchesCount: number = 0;
|
|
|
+ let rc4EncodingMatchesCount: number = 0;
|
|
|
+ let obfuscatedCode: string;
|
|
|
+
|
|
|
+ let base64EncodingMatchesChance: number;
|
|
|
+ let rc4EncodingMatchesChance: number;
|
|
|
+
|
|
|
+ before(() => {
|
|
|
+ const code: string = readFileAsString(__dirname + '/fixtures/simple-input.js');
|
|
|
+
|
|
|
+ for (let i = 0; i < samplesCount; i++) {
|
|
|
+ obfuscatedCode = JavaScriptObfuscator.obfuscate(
|
|
|
+ code,
|
|
|
+ {
|
|
|
+ ...NO_ADDITIONAL_NODES_PRESET,
|
|
|
+ stringArray: true,
|
|
|
+ stringArrayEncoding: [
|
|
|
+ StringArrayEncoding.Base64,
|
|
|
+ StringArrayEncoding.Rc4
|
|
|
+ ],
|
|
|
+ stringArrayThreshold: 1
|
|
|
+ }
|
|
|
+ ).getObfuscatedCode();
|
|
|
+
|
|
|
+ if (obfuscatedCode.match(base64EncodingRegExp)) {
|
|
|
+ base64EncodingMatchesCount = base64EncodingMatchesCount + 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (obfuscatedCode.match(rc4EncodingRegExp)) {
|
|
|
+ rc4EncodingMatchesCount = rc4EncodingMatchesCount + 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ base64EncodingMatchesChance = base64EncodingMatchesCount / samplesCount;
|
|
|
+ rc4EncodingMatchesChance = rc4EncodingMatchesCount / samplesCount;
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should replace literal node value with value from string array encoded using base64', () => {
|
|
|
+ assert.closeTo(base64EncodingMatchesChance, expectedMatchesChance, expectedMatchesDelta);
|
|
|
+ });
|
|
|
+
|
|
|
+ it('should replace literal node value with value from string array encoded using rc4', () => {
|
|
|
+ assert.closeTo(rc4EncodingMatchesChance, expectedMatchesChance, expectedMatchesDelta);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ describe('Variant #13: `stringArrayThreshold` option value', () => {
|
|
|
const samples: number = 1000;
|
|
|
const stringArrayThreshold: number = 0.5;
|
|
|
const delta: number = 0.1;
|
|
@@ -323,7 +493,7 @@ describe('StringArrayTransformer', () => {
|
|
|
});
|
|
|
});
|
|
|
|
|
|
- describe('Variant #11: string array calls wrapper name', () => {
|
|
|
+ describe('Variant #14: string array calls wrapper name', () => {
|
|
|
const regExp: RegExp = /console\[b\('0x0'\)]\('a'\);/;
|
|
|
|
|
|
let obfuscatedCode: string;
|
|
@@ -347,7 +517,7 @@ describe('StringArrayTransformer', () => {
|
|
|
});
|
|
|
});
|
|
|
|
|
|
- describe('Variant #12: `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';/;
|
|
@@ -519,7 +689,7 @@ describe('StringArrayTransformer', () => {
|
|
|
});
|
|
|
});
|
|
|
|
|
|
- describe('Variant #13: 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'\)};/;
|
|
@@ -577,7 +747,7 @@ describe('StringArrayTransformer', () => {
|
|
|
});
|
|
|
});
|
|
|
|
|
|
- describe('Variant #14: import declaration source literal', () => {
|
|
|
+ describe('Variant #17: import declaration source literal', () => {
|
|
|
const importDeclarationRegExp: RegExp = /import *{ *bar *} *from *'foo';/;
|
|
|
|
|
|
let obfuscatedCode: string;
|
|
@@ -600,7 +770,7 @@ describe('StringArrayTransformer', () => {
|
|
|
});
|
|
|
});
|
|
|
|
|
|
- describe('Variant #15: export all declaration source literal', () => {
|
|
|
+ describe('Variant #18: export all declaration source literal', () => {
|
|
|
const exportAllDeclarationRegExp: RegExp = /export *\* *from *'foo';/;
|
|
|
|
|
|
let obfuscatedCode: string;
|
|
@@ -623,7 +793,7 @@ describe('StringArrayTransformer', () => {
|
|
|
});
|
|
|
});
|
|
|
|
|
|
- describe('Variant #16: export named declaration source literal', () => {
|
|
|
+ describe('Variant #19: export named declaration source literal', () => {
|
|
|
const exportNamedDeclarationRegExp: RegExp = /export *{ *bar *} *from *'foo';/;
|
|
|
|
|
|
let obfuscatedCode: string;
|