voluptasvelit
Version:
JavaScript obfuscator
550 lines (450 loc) • 20.4 kB
text/typescript
import { assert } from 'chai';
import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../src/options/presets/NoCustomNodes';
import { readFileAsString } from '../../../../helpers/readFileAsString';
import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
describe('ObjectExpressionKeysTransformer', () => {
const variableMatch: string = '_0x([a-f0-9]){4,6}';
describe('transformation of object keys', () => {
describe('Variant #1: simple', () => {
const match: string = `` +
`var *${variableMatch} *= *{};` +
`${variableMatch}\\['foo'] *= *'bar';` +
`${variableMatch}\\['baz'] *= *'bark';` +
``;
const regExp: RegExp = new RegExp(match);
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/simple.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
transformObjectKeys: true
}
).getObfuscatedCode();
});
it('should correctly transform object keys', () => {
assert.match(obfuscatedCode, regExp);
});
});
describe('Variant #2: nested objects #1', () => {
const match: string = `` +
`var *${variableMatch} *= *{};` +
`${variableMatch}\\['foo'] *= *'bar';` +
`${variableMatch}\\['inner'] *= *{};` +
`${variableMatch}\\['inner']\\['inner1'] *= *{};` +
`${variableMatch}\\['inner']\\['inner1']\\['baz'] *= *'bark';` +
``;
const regExp: RegExp = new RegExp(match);
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/nested-objects-1.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
transformObjectKeys: true
}
).getObfuscatedCode();
});
it('should correctly transform object keys', () => {
assert.match(obfuscatedCode, regExp);
});
});
describe('Variant #3: nested objects #2', () => {
const match: string = `` +
`var *${variableMatch} *= *{};` +
`${variableMatch}\\['foo'] *= *'bar';` +
`${variableMatch}\\['inner'] *= *{};` +
`${variableMatch}\\['ball'] *= *'door';` +
`${variableMatch}\\['inner']\\['baz'] *= *'bark';` +
`${variableMatch}\\['inner']\\['inner1'] *= *{};` +
`${variableMatch}\\['inner']\\['cow'] *= *'bear';` +
`${variableMatch}\\['inner']\\['inner1']\\['hawk'] *= *'geek';` +
``;
const regExp: RegExp = new RegExp(match);
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/nested-objects-2.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
transformObjectKeys: true
}
).getObfuscatedCode();
});
it('should correctly transform object keys', () => {
assert.match(obfuscatedCode, regExp);
});
});
describe('Variant #4: correct integration with control flow flattening object', () => {
const match: string = `` +
`var *${variableMatch} *= *{};` +
`${variableMatch}\\['\\w{5}'] *= *function *\\(${variableMatch}, *${variableMatch}\\) *{` +
`return *${variableMatch} *\\+ *${variableMatch};` +
`};` +
`var *${variableMatch} *= *${variableMatch}\\['\\w{5}']\\(0x1, *0x2\\);` +
``;
const regExp: RegExp = new RegExp(match);
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/integration-with-control-flow-flattening.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
controlFlowFlattening: true,
controlFlowFlatteningThreshold: 1,
transformObjectKeys: true
}
).getObfuscatedCode();
});
it('should correctly transform object keys', () => {
assert.match(obfuscatedCode, regExp);
});
});
describe('Variant #5: variable declaration without initialization', () => {
const match: string = `` +
`var *${variableMatch};` +
`${variableMatch} *= *{};` +
`${variableMatch}\\['foo'] *= *'bar';` +
`${variableMatch}\\['baz'] *= *'bark';` +
``;
const regExp: RegExp = new RegExp(match);
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/variable-declaration-without-initialization.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
transformObjectKeys: true
}
).getObfuscatedCode();
});
it('shouldn\'t transform object keys', () => {
assert.match(obfuscatedCode, regExp);
});
});
});
describe('member expression as host of object expression', () => {
describe('Variant #1: simple', () => {
const match: string = `` +
`this\\['state'] *= *{};` +
`this\\['state']\\['foo'] *= *'bar';` +
`this\\['state']\\['baz'] *= *'bark';` +
``;
const regExp: RegExp = new RegExp(match);
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/member-expression-host-1.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
transformObjectKeys: true
}
).getObfuscatedCode();
});
it('should correctly transform object keys', () => {
assert.match(obfuscatedCode, regExp);
});
});
describe('Variant #2: long members chain', () => {
const match: string = `` +
`this\\['state']\\['foo'] *= *{};` +
`this\\['state']\\['foo']\\['foo'] *= *'bar';` +
`this\\['state']\\['foo']\\['baz'] *= *'bark';` +
``;
const regExp: RegExp = new RegExp(match);
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/member-expression-host-2.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
transformObjectKeys: true
}
).getObfuscatedCode();
});
it('should correctly transform object keys', () => {
assert.match(obfuscatedCode, regExp);
});
});
});
describe('correct placement of expression statements', () => {
describe('Variant #1: if statement', () => {
const match: string = `` +
`if *\\(!!\\[]\\) *{` +
`var *${variableMatch} *= *{};` +
`${variableMatch}\\['foo'] *= *'bar';` +
`}` +
``;
const regExp: RegExp = new RegExp(match);
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/placement-inside-if-statement.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
transformObjectKeys: true
}
).getObfuscatedCode();
});
it('should correctly transform object keys', () => {
assert.match(obfuscatedCode, regExp);
});
});
describe('Variant #2: try statement', () => {
const match: string = `` +
`try *{` +
`var *${variableMatch} *= *{};` +
`${variableMatch}\\['foo'] *= *'bar';` +
`} *catch *\\(${variableMatch}\\) *{` +
`}` +
``;
const regExp: RegExp = new RegExp(match);
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/placement-inside-try-statement.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
transformObjectKeys: true
}
).getObfuscatedCode();
});
it('should correctly transform object keys', () => {
assert.match(obfuscatedCode, regExp);
});
});
describe('Variant #3: catch clause statement', () => {
const match: string = `` +
`try *{` +
`} *catch *\\(${variableMatch}\\) *{` +
`var *${variableMatch} *= *{};` +
`${variableMatch}\\['foo'] *= *'bar';` +
`}` +
``;
const regExp: RegExp = new RegExp(match);
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/placement-inside-catch-clause.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
transformObjectKeys: true
}
).getObfuscatedCode();
});
it('should correctly transform object keys', () => {
assert.match(obfuscatedCode, regExp);
});
});
describe('Variant #4: switch catch statement', () => {
const match: string = `` +
`switch *\\(!!\\[]\\) *{` +
`case *!!\\[]:` +
`var *${variableMatch} *= *{};` +
`${variableMatch}\\['foo'] *= *'bar';` +
`}` +
``;
const regExp: RegExp = new RegExp(match);
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/placement-inside-switch-case.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
transformObjectKeys: true
}
).getObfuscatedCode();
});
it('should transform object keys', () => {
assert.match(obfuscatedCode, regExp);
});
});
describe('Variant #5: variable declarator with object call', () => {
describe('Variant #1', () => {
const match: string = `` +
`const *${variableMatch} *= *{}; *` +
`${variableMatch}\\['foo'] *= *'foo'; *` +
`const *${variableMatch} *= *${variableMatch}\\['foo'];` +
``;
const regExp: RegExp = new RegExp(match);
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/variable-declarator-with-object-call-1.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
transformObjectKeys: true
}
).getObfuscatedCode();
});
it('should correctly transform object keys', () => {
assert.match(obfuscatedCode, regExp);
});
});
describe('Variant #2', () => {
const match: string = `` +
`const *${variableMatch} *= *0x1, *` +
`${variableMatch} *= *{}; *` +
`${variableMatch}\\['foo'] *= *'foo'; *` +
`const *${variableMatch} *= *${variableMatch}\\['foo'];` +
``;
const regExp: RegExp = new RegExp(match);
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/variable-declarator-with-object-call-2.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
transformObjectKeys: true
}
).getObfuscatedCode();
});
it('should correctly transform object keys', () => {
assert.match(obfuscatedCode, regExp);
});
});
describe('Variant #3: two objects', () => {
const match: string = `` +
`const *${variableMatch} *= *{}, *` +
`${variableMatch} *= *{'bar': *'bar'}, *` +
`${variableMatch} *= *${variableMatch}\\['bar']; *` +
`${variableMatch}\\['foo'] *= *'foo';` +
``;
const regExp: RegExp = new RegExp(match);
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/variable-declarator-with-object-call-3.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
transformObjectKeys: true
}
).getObfuscatedCode();
});
it('should correctly transform first object keys and ignore second object keys', () => {
assert.match(obfuscatedCode, regExp);
});
});
});
});
describe('Ignore transformation', () => {
describe('Variant #1: disabled option', () => {
const match: string = `` +
`var *${variableMatch} *= *{` +
`'foo': *'bar',` +
`'baz': *'bark'` +
`}` +
``;
const regExp: RegExp = new RegExp(match);
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/simple.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET
}
).getObfuscatedCode();
});
it('shouldn\'t transform object keys', () => {
assert.match(obfuscatedCode, regExp);
});
});
describe('Variant #2: empty object expression', () => {
const match: string = `var *${variableMatch} *= *{};`;
const regExp: RegExp = new RegExp(match);
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/empty-object-expression.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET
}
).getObfuscatedCode();
});
it('shouldn\'t transform object keys', () => {
assert.match(obfuscatedCode, regExp);
});
});
describe('Variant #3: variable declarator object call inside other variable declarator', () => {
describe('Variant #1', () => {
const match: string = `` +
`const *${variableMatch} *= *{'foo': *'foo'}, *` +
`${variableMatch} *= *${variableMatch}\\['foo'];` +
``;
const regExp: RegExp = new RegExp(match);
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/variable-declarator-with-object-call-ignore-1.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
transformObjectKeys: true
}
).getObfuscatedCode();
});
it('shouldn\'t transform object keys', () => {
assert.match(obfuscatedCode, regExp);
});
});
describe('Variant #2', () => {
const match: string = `` +
`const *${variableMatch} *= *{'foo': *'foo'}, *` +
`${variableMatch} *= *\\[${variableMatch}\\['foo']];` +
``;
const regExp: RegExp = new RegExp(match);
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/variable-declarator-with-object-call-ignore-2.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
transformObjectKeys: true
}
).getObfuscatedCode();
});
it('shouldn\'t transform object keys', () => {
assert.match(obfuscatedCode, regExp);
});
});
});
describe('Variant #4: assignment expression and member expression', () => {
const match: string = `` +
`var ${variableMatch}; *` +
`\\(${variableMatch} *= *{'foo': *'bar'}\\)\\['baz'] *= *${variableMatch}\\['foo'];` +
``;
const regExp: RegExp = new RegExp(match);
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/assignment-expression-and-member-expression.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
transformObjectKeys: true
}
).getObfuscatedCode();
});
it('shouldn\'t transform object keys', () => {
assert.match(obfuscatedCode, regExp);
});
});
});
});