mirror of
https://github.com/javascript-obfuscator/javascript-obfuscator
synced 2026-08-09 12:42:29 +00:00
Merge pull request #470 from javascript-obfuscator/split-strings-reserved-striings-fix
Added new ReservedStringObfuscatingGuard
This commit is contained in:
@@ -2,6 +2,8 @@ Change Log
|
||||
|
||||
v0.20.2
|
||||
---
|
||||
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/pull/442
|
||||
* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/468
|
||||
* Added funding button
|
||||
* Internal dependencies update, Happy New Year 2020!
|
||||
|
||||
|
||||
Vendored
+4
-4
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
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)
|
||||
|
||||
+3
-2
@@ -1,4 +1,5 @@
|
||||
export enum ObfuscatingGuard {
|
||||
BlackListNodeGuard = 'BlackListNodeGuard',
|
||||
ConditionalCommentNodeGuard = 'ConditionalCommentNodeGuard'
|
||||
BlackListObfuscatingGuard = 'BlackListObfuscatingGuard',
|
||||
ConditionalCommentObfuscatingGuard = 'ConditionalCommentObfuscatingGuard',
|
||||
ReservedStringObfuscatingGuard = 'ReservedStringObfuscatingGuard'
|
||||
}
|
||||
|
||||
-29
@@ -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
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
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 {
|
||||
return this.options.reservedStrings
|
||||
.some((reservedString: string) => {
|
||||
return new RegExp(reservedString, 'g').exec(value) !== null;
|
||||
});
|
||||
}
|
||||
}
|
||||
+21
@@ -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';$/
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
var foo = 'foofoo';
|
||||
var bar = 'barbar';
|
||||
var baz = 'bazbaz';
|
||||
+22
@@ -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);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
export default class {}
|
||||
+22
@@ -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);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
export default function () {}
|
||||
+1
-1
@@ -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;
|
||||
|
||||
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
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('`reservedStrings` option is enabled', () => {
|
||||
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);
|
||||
});
|
||||
});
|
||||
|
||||
describe('`reservedStrings` option is disabled', () => {
|
||||
const obfuscatingGuardRegExp: RegExp = /var test1 *= *'foo' *\+ *'foo'; *var test2 *= *'bar' *\+ *'bar'; *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: [],
|
||||
splitStrings: true,
|
||||
splitStringsChunkLength: 3
|
||||
}
|
||||
).getObfuscatedCode();
|
||||
});
|
||||
|
||||
it('match #1: should obfuscate all strings', () => {
|
||||
assert.match(obfuscatedCode, obfuscatingGuardRegExp);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
var test1 = 'foofoo';
|
||||
var test2 = 'barbar';
|
||||
var test3 = 'bazbaz';
|
||||
@@ -76,6 +76,7 @@ import './functional-tests/node-transformers/preparing-transformers/eval-call-ex
|
||||
import './functional-tests/node-transformers/preparing-transformers/comments-transformer/CommentsTransformer.spec';
|
||||
import './functional-tests/node-transformers/preparing-transformers/obfuscating-guards/black-list-obfuscating-guard/BlackListObfuscatingGuard.spec';
|
||||
import './functional-tests/node-transformers/preparing-transformers/obfuscating-guards/conditional-comment-obfuscating-guard/ConditionalCommentObfuscatingGuard.spec';
|
||||
import './functional-tests/node-transformers/preparing-transformers/obfuscating-guards/reserved-string-obfuscating-guard/ReservedStringObfuscatingGuard.spec';
|
||||
import './functional-tests/options/OptionsNormalizer.spec';
|
||||
import './functional-tests/templates/debug-protection-nodes/DebugProtectionFunctionCallTemplate.spec';
|
||||
import './functional-tests/templates/domain-lock-nodes/DomainLockNodeTemplate.spec';
|
||||
|
||||
Reference in New Issue
Block a user