New option: stringArrayIntermediateCalls sets the passed amount of intermediate variables for the string array

This commit is contained in:
sanex
2020-09-07 10:05:31 +03:00
parent 48eccacd5c
commit 1b656d7386
34 changed files with 351 additions and 59 deletions
+9 -5
View File
@@ -1,24 +1,28 @@
'use strict';
import { NO_ADDITIONAL_NODES_PRESET } from '../../src/options/presets/NoCustomNodes';
import { StringArrayEncoding } from '../../src/enums/StringArrayEncoding';
(function () {
const JavaScriptObfuscator: any = require('../../index');
let obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
`
var string1 = '👋🏼';
const foo = 'foo';
const bar = 'bar';
const baz = 'baz';
console.log(string1);
console.log(foo, bar, baz);
`,
{
...NO_ADDITIONAL_NODES_PRESET,
compact: false,
stringArray: true,
stringArrayThreshold: 1,
splitStrings: true,
splitStringsChunkLength: 1,
unicodeEscapeSequence: true
stringArrayIntermediateCalls: 2,
stringArrayEncoding: [
StringArrayEncoding.Rc4
]
}
).getObfuscatedCode();
@@ -53,6 +53,37 @@ describe('StringArrayCallsWrapperCodeHelper', () => {
});
});
describe('`stringArrayIntermediateCalls` option is set', () => {
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\'\\);'
);
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/simple-input.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
stringArray: true,
stringArrayThreshold: 1,
stringArrayIntermediateCalls: 3
}
).getObfuscatedCode();
});
it('should correctly append `StringArrayCallsWrapperIntermediateTemplate` template into the obfuscated code', () => {
assert.match(obfuscatedCode, stringArrayCallRegExp);
});
});
describe('Preserve string array name', () => {
const callsWrapperRegExp: RegExp = new RegExp(`` +
`var b *= *function *\\(c, *d\\) *{ *` +
@@ -719,7 +719,10 @@ describe('JavaScriptObfuscator', () => {
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
identifierNamesGenerator: IdentifierNamesGenerator.MangledIdentifierNamesGenerator
...NO_ADDITIONAL_NODES_PRESET,
identifierNamesGenerator: IdentifierNamesGenerator.MangledIdentifierNamesGenerator,
stringArray: true,
stringArrayThreshold: 1
}
).getObfuscatedCode();
});
@@ -845,6 +848,7 @@ describe('JavaScriptObfuscator', () => {
StringArrayEncoding.Base64,
StringArrayEncoding.Rc4
],
stringArrayIntermediateCalls: 10,
stringArrayThreshold: 1,
transformObjectKeys: true,
unicodeEscapeSequence: false
@@ -938,7 +942,6 @@ describe('JavaScriptObfuscator', () => {
stringArrayEncoding: [StringArrayEncoding.Rc4]
}
).getObfuscatedCode();
});
it('does not break on run', () => {
@@ -63,7 +63,65 @@ describe('StringArrayTransformer', function () {
});
});
describe('Variant #3: string contains non-latin and non-digit characters and `unicodeEscapeSequence` is disabled', () => {
describe('Variant #3: `stringArrayIntermediateCalls` option is enabled', () => {
describe('Variant #1: correct amount of intermediate calls', () => {
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\'\\);'
);
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/simple-input.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
stringArray: true,
stringArrayThreshold: 1,
stringArrayIntermediateCalls: 3
}
).getObfuscatedCode();
});
it('should add intermediate calls to the string array calls wrapper', () => {
assert.match(obfuscatedCode, stringArrayCallRegExp);
});
});
describe('Variant #2: correct evaluation of the intermediate calls', () => {
const expectedEvaluationResult: number = 15;
let evaluationResult: number;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/intermediate-calls-eval.js');
const obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
stringArray: true,
stringArrayThreshold: 1,
stringArrayIntermediateCalls: 5
}
).getObfuscatedCode();
evaluationResult = eval(obfuscatedCode);
});
it('should correctly evaluate intermediate calls', () => {
assert.equal(evaluationResult, expectedEvaluationResult);
});
});
});
describe('Variant #4: string contains non-latin and non-digit characters and `unicodeEscapeSequence` is disabled', () => {
let testFunc: () => void;
before(() => {
@@ -84,7 +142,7 @@ describe('StringArrayTransformer', function () {
});
});
describe('Variant #4: same literal node values', () => {
describe('Variant #5: 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'\);/;
@@ -112,7 +170,7 @@ describe('StringArrayTransformer', function () {
});
});
describe('Variant #5: `unicodeEscapeSequence` option is enabled', () => {
describe('Variant #6: `unicodeEscapeSequence` option is enabled', () => {
const regExp: RegExp = /^var test *= *'\\x74\\x65\\x73\\x74';$/;
let obfuscatedCode: string;
@@ -135,7 +193,7 @@ describe('StringArrayTransformer', function () {
});
});
describe('Variant #6: `unicodeEscapeSequence` and `stringArray` options are enabled', () => {
describe('Variant #7: `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'\);/;
@@ -164,7 +222,7 @@ describe('StringArrayTransformer', function () {
});
});
describe('Variant #7: short literal node value', () => {
describe('Variant #8: short literal node value', () => {
const regExp: RegExp = /var test *= *'te';/;
let obfuscatedCode: string;
@@ -187,7 +245,7 @@ describe('StringArrayTransformer', function () {
});
});
describe('Variant #8: base64 encoding', () => {
describe('Variant #9: 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'\);/;
@@ -216,7 +274,7 @@ describe('StringArrayTransformer', function () {
});
});
describe('Variant #9: rc4 encoding', () => {
describe('Variant #10: rc4 encoding', () => {
describe('Variant #1: single string literal', () => {
const regExp: RegExp = /var test *= *_0x([a-f0-9]){4}\('0x0', *'.{4}'\);/;
@@ -282,7 +340,7 @@ describe('StringArrayTransformer', function () {
});
});
describe('Variant #10: none and base64 encoding', () => {
describe('Variant #11: none and base64 encoding', () => {
describe('Variant #1: string array values', () => {
const samplesCount: number = 100;
const expectedMatchesChance: number = 0.5;
@@ -336,9 +394,47 @@ describe('StringArrayTransformer', function () {
assert.closeTo(base64EncodingMatchesChance, expectedMatchesChance, expectedMatchesDelta);
});
});
describe('Variant #2: `stringArrayIntermediateCalls` 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');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
stringArray: true,
stringArrayEncoding: [
StringArrayEncoding.None,
StringArrayEncoding.Base64
],
stringArrayIntermediateCalls: 3,
stringArrayThreshold: 1
}
).getObfuscatedCode();
});
it('should add intermediate variables for both `none` and `base64` string array wrappers', () => {
assert.match(obfuscatedCode, stringArrayIntermediateCallRegExp);
});
});
});
describe('Variant #11: none and rc4 encoding', () => {
describe('Variant #12: none and rc4 encoding', () => {
describe('Variant #1: string array calls wrapper call', () => {
const samplesCount: number = 100;
const expectedMatchesChance: number = 0.5;
@@ -394,7 +490,7 @@ describe('StringArrayTransformer', function () {
});
});
describe('Variant #12: base64 and rc4 encoding', () => {
describe('Variant #13: base64 and rc4 encoding', () => {
describe('Variant #1: single string literal', () => {
const samplesCount: number = 100;
const expectedMatchesChance: number = 0.5;
@@ -450,7 +546,7 @@ describe('StringArrayTransformer', function () {
});
});
describe('Variant #13: `stringArrayThreshold` option value', () => {
describe('Variant #14: `stringArrayThreshold` option value', () => {
const samples: number = 1000;
const stringArrayThreshold: number = 0.5;
const delta: number = 0.1;
@@ -493,7 +589,7 @@ describe('StringArrayTransformer', function () {
});
});
describe('Variant #14: string array calls wrapper name', () => {
describe('Variant #15: string array calls wrapper name', () => {
const regExp: RegExp = /console\[b\('0x0'\)]\('a'\);/;
let obfuscatedCode: string;
@@ -517,7 +613,7 @@ describe('StringArrayTransformer', function () {
});
});
describe('Variant #15: `reservedStrings` option is enabled', () => {
describe('Variant #16: `reservedStrings` option is enabled', () => {
describe('Variant #1: base `reservedStrings` values', () => {
describe('Variant #1: single reserved string value', () => {
const stringLiteralRegExp1: RegExp = /const foo *= *'foo';/;
@@ -689,7 +785,7 @@ describe('StringArrayTransformer', function () {
});
});
describe('Variant #16: object expression key literal', () => {
describe('Variant #17: 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'\)};/;
@@ -747,7 +843,7 @@ describe('StringArrayTransformer', function () {
});
});
describe('Variant #17: import declaration source literal', () => {
describe('Variant #18: import declaration source literal', () => {
const importDeclarationRegExp: RegExp = /import *{ *bar *} *from *'foo';/;
let obfuscatedCode: string;
@@ -770,7 +866,7 @@ describe('StringArrayTransformer', function () {
});
});
describe('Variant #18: export all declaration source literal', () => {
describe('Variant #19: export all declaration source literal', () => {
const exportAllDeclarationRegExp: RegExp = /export *\* *from *'foo';/;
let obfuscatedCode: string;
@@ -793,7 +889,7 @@ describe('StringArrayTransformer', function () {
});
});
describe('Variant #19: export named declaration source literal', () => {
describe('Variant #20: export named declaration source literal', () => {
const exportNamedDeclarationRegExp: RegExp = /export *{ *bar *} *from *'foo';/;
let obfuscatedCode: string;
@@ -0,0 +1,11 @@
function func () {
var foo = 1;
var bar = 2;
var baz = 3;
var bark = 4;
var hawk = 5;
return foo + bar + baz + bark + hawk;
}
func();
@@ -544,6 +544,7 @@ describe('OptionsNormalizer', () => {
shuffleStringArray: true,
stringArray: false,
stringArrayEncoding: [StringArrayEncoding.Rc4],
stringArrayIntermediateCalls: 5,
stringArrayThreshold: 0.5,
rotateStringArray: true
});
@@ -553,6 +554,7 @@ describe('OptionsNormalizer', () => {
shuffleStringArray: false,
stringArray: false,
stringArrayEncoding: [StringArrayEncoding.None],
stringArrayIntermediateCalls: 0,
stringArrayThreshold: 0,
rotateStringArray: false
};
@@ -590,6 +592,7 @@ describe('OptionsNormalizer', () => {
rotateStringArray: true,
shuffleStringArray: true,
stringArray: true,
stringArrayIntermediateCalls: 5,
stringArrayThreshold: 0
});
@@ -598,6 +601,7 @@ describe('OptionsNormalizer', () => {
rotateStringArray: false,
shuffleStringArray: false,
stringArray: false,
stringArrayIntermediateCalls: 0,
stringArrayThreshold: 0
};
});
+1 -1
View File
@@ -64,7 +64,7 @@ import './functional-tests/custom-code-helpers/string-array/StringArrayCallsWrap
import './functional-tests/custom-code-helpers/string-array/StringArrayCodeHelper.spec';
import './functional-tests/custom-code-helpers/string-array/StringArrayRotateFunctionCodeHelper.spec';
import './functional-tests/custom-code-helpers/string-array/group/StringArrayCodeHelperGroup.spec';
import './functional-tests/custom-code-helpers/string-array/templates/string-array-calls-wrapper-node-template/StringArrayCallsWrapperNodeTemplate.spec';
import './functional-tests/custom-code-helpers/string-array/templates/string-array-calls-wrapper-node-template/StringArrayCallsWrapperTemplate.spec';
import './functional-tests/custom-code-helpers/string-array/templates/string-array-rotate-function-template/StringArrayRotateFunctionTemplate.spec';
import './functional-tests/custom-code-helpers/string-array/templates/string-array-template/StringArrayTemplate.spec';
import './functional-tests/generators/identifier-names-generators/dictionary-identifier-names-generator/DictionaryIdentifierNamesGenerator.spec';
@@ -39,6 +39,7 @@ describe('JavaScriptObfuscator runtime eval', function () {
StringArrayEncoding.Base64,
StringArrayEncoding.Rc4
],
stringArrayIntermediateCalls: 20,
stringArrayThreshold: 1,
transformObjectKeys: true,
unicodeEscapeSequence: true