Added new ReservedStringObfuscatingGuard

This commit is contained in:
sanex3339
2020-01-02 15:37:13 +03:00
parent b969afea91
commit b5fa248fde
17 changed files with 187 additions and 42 deletions
+4 -4
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
@@ -16,6 +16,7 @@ import { EvalCallExpressionTransformer } from '../../../node-transformers/prepar
import { MetadataTransformer } from '../../../node-transformers/preparing-transformers/MetadataTransformer';
import { ObfuscatingGuardsTransformer } from '../../../node-transformers/preparing-transformers/ObfuscatingGuardsTransformer';
import { ParentificationTransformer } from '../../../node-transformers/preparing-transformers/ParentificationTransformer';
import { ReservedStringObfuscatingGuard } from '../../../node-transformers/preparing-transformers/obfuscating-guards/ReservedStringObfuscatingGuard';
import { VariablePreserveTransformer } from "../../../node-transformers/preparing-transformers/VariablePreserveTransformer";
export const preparingTransformersModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
@@ -48,12 +49,17 @@ export const preparingTransformersModule: interfaces.ContainerModule = new Conta
bind<IObfuscatingGuard>(ServiceIdentifiers.INodeGuard)
.to(BlackListObfuscatingGuard)
.inSingletonScope()
.whenTargetNamed(ObfuscatingGuard.BlackListNodeGuard);
.whenTargetNamed(ObfuscatingGuard.BlackListObfuscatingGuard);
bind<IObfuscatingGuard>(ServiceIdentifiers.INodeGuard)
.to(ConditionalCommentObfuscatingGuard)
.inSingletonScope()
.whenTargetNamed(ObfuscatingGuard.ConditionalCommentNodeGuard);
.whenTargetNamed(ObfuscatingGuard.ConditionalCommentObfuscatingGuard);
bind<IObfuscatingGuard>(ServiceIdentifiers.INodeGuard)
.to(ReservedStringObfuscatingGuard)
.inSingletonScope()
.whenTargetNamed(ObfuscatingGuard.ReservedStringObfuscatingGuard);
// obfuscating guards factory
bind<IObfuscatingGuard>(ServiceIdentifiers.Factory__INodeGuard)
@@ -1,4 +1,5 @@
export enum ObfuscatingGuard {
BlackListNodeGuard = 'BlackListNodeGuard',
ConditionalCommentNodeGuard = 'ConditionalCommentNodeGuard'
BlackListObfuscatingGuard = 'BlackListObfuscatingGuard',
ConditionalCommentObfuscatingGuard = 'ConditionalCommentObfuscatingGuard',
ReservedStringObfuscatingGuard = 'ReservedStringObfuscatingGuard'
}
@@ -133,10 +133,6 @@ export class StringLiteralObfuscatingReplacer extends AbstractObfuscatingReplace
* @returns {Node}
*/
public replace (nodeValue: string): ESTree.Node {
if (this.isReservedString(nodeValue)) {
return this.replaceWithReservedLiteralNode(nodeValue);
}
const useStringArray: boolean = this.canUseStringArray(nodeValue);
const cacheKey: string = `${nodeValue}-${String(useStringArray)}`;
const useCacheValue: boolean = this.nodesCache.has(cacheKey) && this.options.stringArrayEncoding !== StringArrayEncoding.Rc4;
@@ -227,16 +223,6 @@ export class StringLiteralObfuscatingReplacer extends AbstractObfuscatingReplace
);
}
/**
* @param {string} value
* @returns {Node}
*/
private replaceWithReservedLiteralNode (value: string): ESTree.Node {
return NodeFactory.literalNode(
this.escapeSequenceEncoder.encode(value, false)
);
}
/**
* @param {string} value
* @returns {Node}
@@ -277,19 +263,4 @@ export class StringLiteralObfuscatingReplacer extends AbstractObfuscatingReplace
callExpressionArgs
);
}
/**
* @param {string} value
* @returns {boolean}
*/
private isReservedString (value: string): boolean {
if (!this.options.reservedStrings.length) {
return false;
}
return this.options.reservedStrings
.some((reservedString: string) => {
return new RegExp(reservedString, 'g').exec(value) !== null;
});
}
}
@@ -25,8 +25,9 @@ export class ObfuscatingGuardsTransformer extends AbstractNodeTransformer {
* @type {ObfuscatingGuard[]}
*/
private static readonly obfuscatingGuardsList: ObfuscatingGuard[] = [
ObfuscatingGuard.BlackListNodeGuard,
ObfuscatingGuard.ConditionalCommentNodeGuard
ObfuscatingGuard.BlackListObfuscatingGuard,
ObfuscatingGuard.ConditionalCommentObfuscatingGuard,
ObfuscatingGuard.ReservedStringObfuscatingGuard
];
/**
@@ -0,0 +1,58 @@
import { inject, injectable } from 'inversify';
import * as ESTree from 'estree';
import { IObfuscatingGuard } from '../../../interfaces/node-transformers/preparing-transformers/obfuscating-guards/IObfuscatingGuard';
import { IOptions } from '../../../interfaces/options/IOptions';
import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers';
import { NodeGuards } from '../../../node/NodeGuards';
@injectable()
export class ReservedStringObfuscatingGuard implements IObfuscatingGuard {
/**
* @type {IOptions}
*/
private readonly options: IOptions;
/**
* @param {IOptions} options
*/
constructor (
@inject(ServiceIdentifiers.IOptions) options: IOptions
) {
this.options = options;
}
/**
* @returns {boolean}
* @param node
*/
public check (node: ESTree.Node): boolean {
if (
this.options.reservedStrings.length
&& NodeGuards.isLiteralNode(node)
&& typeof node.value === 'string'
) {
return !this.isReservedString(node.value);
}
return true;
}
/**
* @param {string} value
* @returns {boolean}
*/
private isReservedString (value: string): boolean {
if (!this.options.reservedStrings.length) {
return false;
}
return this.options.reservedStrings
.some((reservedString: string) => {
return new RegExp(reservedString, 'g').exec(value) !== null;
});
}
}
@@ -183,4 +183,25 @@ describe('SplitStringTransformer', () => {
);
});
});
describe('Variant #10: Integration with `reservedStrings` option', () => {
it('should correctly ignore strings from `reservedStrings` option', () => {
const code: string = readFileAsString(__dirname + '/fixtures/ignore-reserved-strings.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
splitStrings: true,
splitStringsChunkLength: 3,
reservedStrings: ['bar']
}
).getObfuscatedCode();
assert.match(
obfuscatedCode,
/^var *foo *= *'foo' *\+ *'foo'; *var *bar *= *'barbar'; *var *baz *= *'baz' *\+ *'baz';$/
);
});
});
});
@@ -0,0 +1,3 @@
var foo = 'foofoo';
var bar = 'barbar';
var baz = 'bazbaz';
@@ -195,5 +195,27 @@ describe('ClassDeclarationTransformer', () => {
assert.match(obfuscatedCode, defaultExportRegExp);
});
});
describe('Variant #7: default export inline', () => {
const defaultExportRegExp: RegExp = /export default class *{}/;
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/default-export-inline.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
renameGlobals: true
}
).getObfuscatedCode();
});
it('Match #1: should produce correct code', () => {
assert.match(obfuscatedCode, defaultExportRegExp);
});
});
});
});
@@ -220,5 +220,27 @@ describe('FunctionDeclarationTransformer', () => {
assert.match(obfuscatedCode, defaultExportRegExp);
});
});
describe('Variant #8: default export inline', () => {
const defaultExportRegExp: RegExp = /export default function *\(\) *{}/;
let obfuscatedCode: string;
before(() => {
const code: string = readFileAsString(__dirname + '/fixtures/default-export-inline.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
renameGlobals: true
}
).getObfuscatedCode();
});
it('Match #1: should produce correct code', () => {
assert.match(obfuscatedCode, defaultExportRegExp);
});
});
});
});
@@ -454,7 +454,7 @@ describe('LiteralTransformer', () => {
});
describe('Variant #4: correct escape of special characters', () => {
const stringLiteralRegExp: RegExp = /var baz *= *'Cannot\\x20find\\x20module\\x20\\x27' *\+ *foo *\+ *'\\x27';/;
const stringLiteralRegExp: RegExp = /var baz *= *'Cannot find module \\'' *\+ *foo *\+ *'\\x27';/;
let obfuscatedCode: string;
@@ -0,0 +1,35 @@
import { assert } from 'chai';
import { JavaScriptObfuscator } from '../../../../../../src/JavaScriptObfuscatorFacade';
import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../../src/options/presets/NoCustomNodes';
import { readFileAsString } from '../../../../../helpers/readFileAsString';
describe('ReservedStringObfuscatingGuard', () => {
describe('check', () => {
describe('`\'use strict\';` operator', () => {
const obfuscatingGuardRegExp: RegExp = /var test1 *= *'foo' *\+ *'foo'; *var test2 *= *'barbar'; *var test3 *= *'baz' *\+ *'baz';/;
let obfuscatedCode: string;
beforeEach(() => {
const code: string = readFileAsString(__dirname + '/fixtures/base-behaviour.js');
obfuscatedCode = JavaScriptObfuscator.obfuscate(
code,
{
...NO_ADDITIONAL_NODES_PRESET,
reservedStrings: ['bar'],
splitStrings: true,
splitStringsChunkLength: 3
}
).getObfuscatedCode();
});
it('match #1: shouldn\'t obfuscate reserved strings', () => {
assert.match(obfuscatedCode, obfuscatingGuardRegExp);
});
});
});
});
@@ -0,0 +1,3 @@
var test1 = 'foofoo';
var test2 = 'barbar';
var test3 = 'bazbaz';