Skip to content

Commit

Permalink
Improved rename of deadCodeInjection dead code identifiers. Fixed j…
Browse files Browse the repository at this point in the history
  • Loading branch information
sanex3339 committed Aug 18, 2020
1 parent dce3650 commit 0f2f0c2
Show file tree
Hide file tree
Showing 22 changed files with 378 additions and 112 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
Change Log

v1.11.0
---
* Improved rename of `deadCodeInjection` dead code identifiers. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/708

v1.10.2
---
* Fixed obfuscation of literals of `ExportNamedDeclaration` and `ExportAllDeclaration` nodes
Expand Down
14 changes: 7 additions & 7 deletions dist/index.browser.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/index.cli.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/index.js

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "javascript-obfuscator",
"version": "1.10.2",
"version": "1.11.0",
"description": "JavaScript obfuscator",
"keywords": [
"obfuscator",
Expand Down Expand Up @@ -55,25 +55,25 @@
"@types/estree": "0.0.44",
"@types/md5": "2.2.0",
"@types/mkdirp": "1.0.1",
"@types/mocha": "8.0.2",
"@types/mocha": "8.0.3",
"@types/multimatch": "4.0.0",
"@types/node": "14.0.27",
"@types/node": "14.6.0",
"@types/rimraf": "3.0.0",
"@types/sinon": "9.0.4",
"@types/string-template": "1.0.2",
"@types/webpack-env": "1.15.2",
"@typescript-eslint/eslint-plugin": "3.9.0",
"@typescript-eslint/parser": "3.9.0",
"@typescript-eslint/eslint-plugin": "3.9.1",
"@typescript-eslint/parser": "3.9.1",
"chai": "4.2.0",
"coveralls": "3.1.0",
"eslint": "7.7.0",
"eslint-plugin-import": "2.22.0",
"eslint-plugin-jsdoc": "30.2.3",
"eslint-plugin-jsdoc": "30.2.4",
"eslint-plugin-no-null": "1.0.2",
"eslint-plugin-prefer-arrow": "1.2.2",
"eslint-plugin-unicorn": "21.0.0",
"fork-ts-checker-notifier-webpack-plugin": "3.0.0",
"fork-ts-checker-webpack-plugin": "5.0.14",
"fork-ts-checker-webpack-plugin": "5.1.0",
"mocha": "8.1.1",
"nyc": "15.1.0",
"pjson": "1.0.9",
Expand Down
2 changes: 2 additions & 0 deletions src/container/InversifyContainerFacade.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { controlFlowTransformersModule } from './modules/node-transformers/Contr
import { convertingTransformersModule } from './modules/node-transformers/ConvertingTransformersModule';
import { customCodeHelpersModule } from './modules/custom-code-helpers/CustomCodeHelpersModule';
import { customNodesModule } from './modules/custom-nodes/CustomNodesModule';
import { deadCodeInjectionTransformersModule } from './modules/node-transformers/DeadCodeInjectionTransformersModule';
import { finalizingTransformersModule } from './modules/node-transformers/FinalizingTransformersModule';
import { generatorsModule } from './modules/generators/GeneratorsModule';
import { initializingTransformersModule } from './modules/node-transformers/InitializingTransformersModule';
Expand Down Expand Up @@ -209,6 +210,7 @@ export class InversifyContainerFacade implements IInversifyContainerFacade {
this.container.load(convertingTransformersModule);
this.container.load(customCodeHelpersModule);
this.container.load(customNodesModule);
this.container.load(deadCodeInjectionTransformersModule);
this.container.load(finalizingTransformersModule);
this.container.load(generatorsModule);
this.container.load(initializingTransformersModule);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { NodeTransformer } from '../../../enums/node-transformers/NodeTransforme
import { BinaryExpressionControlFlowReplacer } from '../../../node-transformers/control-flow-transformers/control-flow-replacers/BinaryExpressionControlFlowReplacer';
import { BlockStatementControlFlowTransformer } from '../../../node-transformers/control-flow-transformers/BlockStatementControlFlowTransformer';
import { CallExpressionControlFlowReplacer } from '../../../node-transformers/control-flow-transformers/control-flow-replacers/CallExpressionControlFlowReplacer';
import { DeadCodeInjectionTransformer } from '../../../node-transformers/dead-code-injection-transformers/DeadCodeInjectionTransformer';
import { FunctionControlFlowTransformer } from '../../../node-transformers/control-flow-transformers/FunctionControlFlowTransformer';
import { LogicalExpressionControlFlowReplacer } from '../../../node-transformers/control-flow-transformers/control-flow-replacers/LogicalExpressionControlFlowReplacer';
import { StringLiteralControlFlowReplacer } from '../../../node-transformers/control-flow-transformers/control-flow-replacers/StringLiteralControlFlowReplacer';
Expand All @@ -22,10 +21,6 @@ export const controlFlowTransformersModule: interfaces.ContainerModule = new Con
.to(BlockStatementControlFlowTransformer)
.whenTargetNamed(NodeTransformer.BlockStatementControlFlowTransformer);

bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(DeadCodeInjectionTransformer)
.whenTargetNamed(NodeTransformer.DeadCodeInjectionTransformer);

bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(FunctionControlFlowTransformer)
.whenTargetNamed(NodeTransformer.FunctionControlFlowTransformer);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { ContainerModule, interfaces } from 'inversify';
import { ServiceIdentifiers } from '../../ServiceIdentifiers';

import { INodeTransformer } from '../../../interfaces/node-transformers/INodeTransformer';

import { NodeTransformer } from '../../../enums/node-transformers/NodeTransformer';

import { DeadCodeInjectionTransformer } from '../../../node-transformers/dead-code-injection-transformers/DeadCodeInjectionTransformer';
import { ScopeThroughIdentifiersTransformer } from '../../../node-transformers/dead-code-injection-transformers/ScopeThroughIdentifiersTransformer';

export const deadCodeInjectionTransformersModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
// dead code injection
bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(DeadCodeInjectionTransformer)
.whenTargetNamed(NodeTransformer.DeadCodeInjectionTransformer);

bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
.to(ScopeThroughIdentifiersTransformer)
.whenTargetNamed(NodeTransformer.ScopeThroughIdentifiersTransformer);
});
1 change: 1 addition & 0 deletions src/enums/node-transformers/NodeTransformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export enum NodeTransformer {
ParentificationTransformer = 'ParentificationTransformer',
RenamePropertiesTransformer = 'RenamePropertiesTransformer',
ScopeIdentifiersTransformer = 'ScopeIdentifiersTransformer',
ScopeThroughIdentifiersTransformer = 'ScopeThroughIdentifiersTransformer',
SplitStringTransformer = 'SplitStringTransformer',
TemplateLiteralTransformer = 'TemplateLiteralTransformer',
VariableDeclarationsMergeTransformer = 'VariableDeclarationsMergeTransformer',
Expand Down
21 changes: 17 additions & 4 deletions src/interfaces/node/IScopeIdentifiersTraverser.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,30 @@
import * as ESTree from 'estree';

import { TScopeIdentifiersTraverserVariableCallback } from '../../types/node/TScopeIdentifiersTraverserVariableCallback';
import { TScopeIdentifiersTraverserCallback } from '../../types/node/TScopeIdentifiersTraverserCallback';
import { IScopeIdentifiersTraverserCallbackData } from './IScopeIdentifiersTraverserCallbackData';
import { IScopeThroughIdentifiersTraverserCallbackData } from './IScopeThroughIdentifiersTraverserCallbackData';

export interface IScopeIdentifiersTraverser {
/**
* @param {Program} programNode
* @param {Node | null} parentNode
* @param {TScopeIdentifiersTraverserVariableCallback} callback
* @param {TScopeIdentifiersTraverserCallback<IScopeIdentifiersTraverserCallbackData>} callback
*/
traverseScopeVariables (
traverseScopeIdentifiers (
programNode: ESTree.Program,
parentNode: ESTree.Node | null,
callback: TScopeIdentifiersTraverserVariableCallback
callback: TScopeIdentifiersTraverserCallback<IScopeIdentifiersTraverserCallbackData>
): void;

/**
* @param {Node} node
* @param {Node | null} parentNode
* @param {TScopeIdentifiersTraverserCallback<IScopeThroughIdentifiersTraverserCallbackData>} callback
*/
traverseScopeThroughIdentifiers (
node: ESTree.Node,
parentNode: ESTree.Node | null,
callback: TScopeIdentifiersTraverserCallback<IScopeThroughIdentifiersTraverserCallbackData>
): void;

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as eslintScope from 'eslint-scope';

import { TNodeWithLexicalScope } from '../../types/node/TNodeWithLexicalScope';

export interface IScopeIdentifiersTraverserVariableCallbackData {
export interface IScopeIdentifiersTraverserCallbackData {
isGlobalDeclaration: boolean;
isBubblingDeclaration: boolean;
rootScope: eslintScope.Scope;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import * as eslintScope from 'eslint-scope';

import { TNodeWithLexicalScope } from '../../types/node/TNodeWithLexicalScope';

export interface IScopeThroughIdentifiersTraverserCallbackData {
reference: eslintScope.Reference;
variableLexicalScopeNode: TNodeWithLexicalScope;
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ export class DeadCodeInjectionTransformer extends AbstractNodeTransformer {
*/
private static readonly transformersToRenameBlockScopeIdentifiers: NodeTransformer[] = [
NodeTransformer.LabeledStatementTransformer,
NodeTransformer.ScopeIdentifiersTransformer
NodeTransformer.ScopeIdentifiersTransformer,
NodeTransformer.ScopeThroughIdentifiersTransformer
];

/**
Expand Down Expand Up @@ -362,6 +363,12 @@ export class DeadCodeInjectionTransformer extends AbstractNodeTransformer {
NodeUtils.parentizeAst(hostNode);
NodeUtils.parentizeNode(hostNode, hostNode);

this.transformersRunner.transform(
hostNode,
DeadCodeInjectionTransformer.transformersToRenameBlockScopeIdentifiers,
NodeTransformationStage.DeadCodeInjection
);

this.transformersRunner.transform(
hostNode,
DeadCodeInjectionTransformer.transformersToRenameBlockScopeIdentifiers,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
import { inject, injectable, } from 'inversify';
import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';

import * as eslintScope from 'eslint-scope';
import * as ESTree from 'estree';

import { TIdentifierObfuscatingReplacerFactory } from '../../types/container/node-transformers/TIdentifierObfuscatingReplacerFactory';
import { TNodeWithLexicalScope } from '../../types/node/TNodeWithLexicalScope';

import { IIdentifierObfuscatingReplacer } from '../../interfaces/node-transformers/obfuscating-transformers/obfuscating-replacers/IIdentifierObfuscatingReplacer';
import { IOptions } from '../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
import { IScopeIdentifiersTraverser } from '../../interfaces/node/IScopeIdentifiersTraverser';
import { IScopeThroughIdentifiersTraverserCallbackData } from '../../interfaces/node/IScopeThroughIdentifiersTraverserCallbackData';
import { IVisitor } from '../../interfaces/node-transformers/IVisitor';

import { IdentifierObfuscatingReplacer } from '../../enums/node-transformers/obfuscating-transformers/obfuscating-replacers/IdentifierObfuscatingReplacer';
import { NodeTransformationStage } from '../../enums/node-transformers/NodeTransformationStage';

import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
import { NodeGuards } from '../../node/NodeGuards';

/**
* Renames all through identifiers for Dead Code Injection
*/
@injectable()
export class ScopeThroughIdentifiersTransformer extends AbstractNodeTransformer {
/**
* @type {IIdentifierObfuscatingReplacer}
*/
private readonly identifierObfuscatingReplacer: IIdentifierObfuscatingReplacer;

/**
* @type {IScopeIdentifiersTraverser}
*/
private readonly scopeIdentifiersTraverser: IScopeIdentifiersTraverser;

/**
* @param {TIdentifierObfuscatingReplacerFactory} identifierObfuscatingReplacerFactory
* @param {IRandomGenerator} randomGenerator
* @param {IOptions} options
* @param {IScopeIdentifiersTraverser} scopeIdentifiersTraverser
*/
public constructor (
@inject(ServiceIdentifiers.Factory__IIdentifierObfuscatingReplacer)
identifierObfuscatingReplacerFactory: TIdentifierObfuscatingReplacerFactory,
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
@inject(ServiceIdentifiers.IOptions) options: IOptions,
@inject(ServiceIdentifiers.IScopeIdentifiersTraverser) scopeIdentifiersTraverser: IScopeIdentifiersTraverser
) {
super(randomGenerator, options);

this.identifierObfuscatingReplacer = identifierObfuscatingReplacerFactory(
IdentifierObfuscatingReplacer.BaseIdentifierObfuscatingReplacer
);
this.scopeIdentifiersTraverser = scopeIdentifiersTraverser;
}

/**
* @param {NodeTransformationStage} nodeTransformationStage
* @returns {IVisitor | null}
*/
public getVisitor (nodeTransformationStage: NodeTransformationStage): IVisitor | null {
switch (nodeTransformationStage) {
case NodeTransformationStage.DeadCodeInjection:
return {
enter: (node: ESTree.Node, parentNode: ESTree.Node | null): ESTree.Node | undefined => {
if (parentNode && NodeGuards.isProgramNode(node)) {
return this.transformNode(node, parentNode);
}
}
};

default:
return null;
}
}

/**
* @param {VariableDeclaration} programNode
* @param {NodeGuards} parentNode
* @returns {NodeGuards}
*/
public transformNode (programNode: ESTree.Program, parentNode: ESTree.Node): ESTree.Node {
this.scopeIdentifiersTraverser.traverseScopeThroughIdentifiers(
programNode,
parentNode,
(data: IScopeThroughIdentifiersTraverserCallbackData) => {
const {
reference,
variableLexicalScopeNode
} = data;

this.transformScopeThroughIdentifiers(reference, variableLexicalScopeNode);
}
);

return programNode;
}

/**
* @param {Reference} reference
* @param {TNodeWithLexicalScope} lexicalScopeNode
*/
private transformScopeThroughIdentifiers (
reference: eslintScope.Reference,
lexicalScopeNode: TNodeWithLexicalScope,
): void {
if (reference.resolved) {
return;
}

const identifier: ESTree.Identifier = reference.identifier;

this.storeIdentifierName(identifier, lexicalScopeNode);
this.replaceIdentifierName(identifier, lexicalScopeNode, reference);
}

/**
* @param {Identifier} identifierNode
* @param {TNodeWithLexicalScope} lexicalScopeNode
*/
private storeIdentifierName (
identifierNode: ESTree.Identifier,
lexicalScopeNode: TNodeWithLexicalScope
): void {
this.identifierObfuscatingReplacer.storeLocalName(identifierNode, lexicalScopeNode);
}

/**
* @param {Identifier} identifierNode
* @param {TNodeWithLexicalScope} lexicalScopeNode
* @param {Variable} reference
*/
private replaceIdentifierName (
identifierNode: ESTree.Identifier,
lexicalScopeNode: TNodeWithLexicalScope,
reference: eslintScope.Reference
): void {
const newIdentifier: ESTree.Identifier = this.identifierObfuscatingReplacer
.replace(identifierNode, lexicalScopeNode);

// rename of identifier
reference.identifier.name = newIdentifier.name;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { IIdentifierObfuscatingReplacer } from '../../interfaces/node-transforme
import { IOptions } from '../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
import { IScopeIdentifiersTraverser } from '../../interfaces/node/IScopeIdentifiersTraverser';
import { IScopeIdentifiersTraverserVariableCallbackData } from '../../interfaces/node/IScopeIdentifiersTraverserVariableCallbackData';
import { IScopeIdentifiersTraverserCallbackData } from '../../interfaces/node/IScopeIdentifiersTraverserCallbackData';
import { IVisitor } from '../../interfaces/node-transformers/IVisitor';

import { IdentifierObfuscatingReplacer } from '../../enums/node-transformers/obfuscating-transformers/obfuscating-replacers/IdentifierObfuscatingReplacer';
Expand Down Expand Up @@ -89,10 +89,10 @@ export class ScopeIdentifiersTransformer extends AbstractNodeTransformer {
* @returns {NodeGuards}
*/
public transformNode (programNode: ESTree.Program, parentNode: ESTree.Node): ESTree.Node {
this.scopeIdentifiersTraverser.traverseScopeVariables(
this.scopeIdentifiersTraverser.traverseScopeIdentifiers(
programNode,
parentNode,
(data: IScopeIdentifiersTraverserVariableCallbackData) => {
(data: IScopeIdentifiersTraverserCallbackData) => {
const {
isGlobalDeclaration,
variable,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { IIdentifierObfuscatingReplacer } from '../../interfaces/node-transforme
import { IOptions } from '../../interfaces/options/IOptions';
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
import { IScopeIdentifiersTraverser } from '../../interfaces/node/IScopeIdentifiersTraverser';
import { IScopeIdentifiersTraverserVariableCallbackData } from '../../interfaces/node/IScopeIdentifiersTraverserVariableCallbackData';
import { IScopeIdentifiersTraverserCallbackData } from '../../interfaces/node/IScopeIdentifiersTraverserCallbackData';
import { IVisitor } from '../../interfaces/node-transformers/IVisitor';

import { NodeTransformer } from '../../enums/node-transformers/NodeTransformer';
Expand Down Expand Up @@ -93,7 +93,7 @@ export class VariablePreserveTransformer extends AbstractNodeTransformer {
* @returns {NodeGuards}
*/
public transformNode (programNode: ESTree.Program, parentNode: ESTree.Node): ESTree.Node {
this.scopeIdentifiersTraverser.traverseScopeVariables(
this.scopeIdentifiersTraverser.traverseScopeIdentifiers(
programNode,
parentNode,
this.preserveScopeVariableIdentifiers
Expand All @@ -103,9 +103,9 @@ export class VariablePreserveTransformer extends AbstractNodeTransformer {
}

/**
* @param {IScopeIdentifiersTraverserVariableCallbackData} data
* @param {IScopeIdentifiersTraverserCallbackData} data
*/
private preserveScopeVariableIdentifiers (data: IScopeIdentifiersTraverserVariableCallbackData): void {
private preserveScopeVariableIdentifiers (data: IScopeIdentifiersTraverserCallbackData): void {
const {
isGlobalDeclaration,
isBubblingDeclaration,
Expand Down
Loading

0 comments on commit 0f2f0c2

Please sign in to comment.