mirror of
https://github.com/javascript-obfuscator/javascript-obfuscator
synced 2026-08-09 12:42:29 +00:00
This commit is contained in:
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+34
-16
@@ -8,8 +8,10 @@ import { TNodeWithBlockStatement } from '../../types/node/TNodeWithBlockStatemen
|
||||
|
||||
import { IOptions } from '../../interfaces/options/IOptions';
|
||||
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
|
||||
import { ITransformersRunner } from '../../interfaces/node-transformers/ITransformersRunner';
|
||||
import { IVisitor } from '../../interfaces/node-transformers/IVisitor';
|
||||
|
||||
import { NodeTransformer } from '../../enums/node-transformers/NodeTransformer';
|
||||
import { NodeType } from '../../enums/node/NodeType';
|
||||
|
||||
import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
|
||||
@@ -29,6 +31,18 @@ export class DeadCodeInjectionTransformer extends AbstractNodeTransformer {
|
||||
*/
|
||||
private static readonly minCollectedBlockStatementsCount: number = 5;
|
||||
|
||||
/**
|
||||
* @type {NodeTransformer[]}
|
||||
*/
|
||||
private static readonly transformersToRenameBlockScopeIdentifiers: NodeTransformer[] = [
|
||||
NodeTransformer.CatchClauseTransformer,
|
||||
NodeTransformer.ClassDeclarationTransformer,
|
||||
NodeTransformer.FunctionDeclarationTransformer,
|
||||
NodeTransformer.FunctionTransformer,
|
||||
NodeTransformer.LabeledStatementTransformer,
|
||||
NodeTransformer.VariableDeclarationTransformer
|
||||
];
|
||||
|
||||
/**
|
||||
* @type {ESTree.BlockStatement[]}
|
||||
*/
|
||||
@@ -40,14 +54,23 @@ export class DeadCodeInjectionTransformer extends AbstractNodeTransformer {
|
||||
private collectedBlockStatementsLength: number;
|
||||
|
||||
/**
|
||||
* @type {ITransformersRunner}
|
||||
*/
|
||||
private readonly transformersRunner: ITransformersRunner;
|
||||
|
||||
/**
|
||||
* @param {ITransformersRunner} transformersRunner
|
||||
* @param {IRandomGenerator} randomGenerator
|
||||
* @param {IOptions} options
|
||||
*/
|
||||
constructor (
|
||||
@inject(ServiceIdentifiers.ITransformersRunner) transformersRunner: ITransformersRunner,
|
||||
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
|
||||
@inject(ServiceIdentifiers.IOptions) options: IOptions
|
||||
) {
|
||||
super(randomGenerator, options);
|
||||
|
||||
this.transformersRunner = transformersRunner;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,15 +154,14 @@ export class DeadCodeInjectionTransformer extends AbstractNodeTransformer {
|
||||
blockStatementNode: ESTree.BlockStatement,
|
||||
collectedBlockStatements: ESTree.BlockStatement[]
|
||||
): void {
|
||||
const clonedBlockStatementNode: ESTree.BlockStatement = NodeUtils.clone(blockStatementNode);
|
||||
|
||||
let nestedBlockStatementsCount: number = 0,
|
||||
let clonedBlockStatementNode: ESTree.BlockStatement = NodeUtils.clone(blockStatementNode),
|
||||
nestedBlockStatementsCount: number = 0,
|
||||
isValidBlockStatementNode: boolean = true;
|
||||
|
||||
estraverse.replace(clonedBlockStatementNode, {
|
||||
enter: (node: ESTree.Node, parentNode: ESTree.Node | null): any => {
|
||||
/**
|
||||
* First step: count nested block statements in current block statement
|
||||
* Count nested block statements in current block statement
|
||||
*/
|
||||
if (NodeGuards.isBlockStatementNode(node)) {
|
||||
nestedBlockStatementsCount++;
|
||||
@@ -159,18 +181,6 @@ export class DeadCodeInjectionTransformer extends AbstractNodeTransformer {
|
||||
return estraverse.VisitorOption.Break;
|
||||
}
|
||||
|
||||
/**
|
||||
* Second step: rename all identifiers (except identifiers in member expressions)
|
||||
* in current block statement
|
||||
*/
|
||||
if (
|
||||
NodeGuards.isIdentifierNode(node) &&
|
||||
parentNode &&
|
||||
!NodeGuards.isMemberExpressionNode(parentNode)
|
||||
) {
|
||||
node.name = this.randomGenerator.getRandomVariableName(6);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
});
|
||||
@@ -179,6 +189,14 @@ export class DeadCodeInjectionTransformer extends AbstractNodeTransformer {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* We should transform identifiers in the dead code block statement to avoid conflicts with original code
|
||||
*/
|
||||
clonedBlockStatementNode = this.transformersRunner.transform(
|
||||
clonedBlockStatementNode,
|
||||
DeadCodeInjectionTransformer.transformersToRenameBlockScopeIdentifiers
|
||||
);
|
||||
|
||||
collectedBlockStatements.push(clonedBlockStatementNode);
|
||||
}
|
||||
|
||||
|
||||
+29
-4
@@ -190,26 +190,26 @@ describe('DeadCodeInjectionTransformer', () => {
|
||||
`if *\\(${variableMatch}\\('${hexMatch}'\\) *=== *${variableMatch}\\('${hexMatch}'\\)\\) *\\{` +
|
||||
`console.*` +
|
||||
`\\} *else *\\{` +
|
||||
`${variableMatch}.*` +
|
||||
`alert.*` +
|
||||
`\\}` +
|
||||
``;
|
||||
const match2: string = `` +
|
||||
`if *\\(${variableMatch}\\('${hexMatch}'\\) *!== *${variableMatch}\\('${hexMatch}'\\)\\) *\\{` +
|
||||
`console.*` +
|
||||
`\\} *else *\\{` +
|
||||
`${variableMatch}.*` +
|
||||
`alert.*` +
|
||||
`\\}` +
|
||||
``;
|
||||
const match3: string = `` +
|
||||
`if *\\(${variableMatch}\\('${hexMatch}'\\) *=== *${variableMatch}\\('${hexMatch}'\\)\\) *\\{` +
|
||||
`${variableMatch}.*` +
|
||||
`alert.*` +
|
||||
`\\} *else *\\{` +
|
||||
`console.*` +
|
||||
`\\}` +
|
||||
``;
|
||||
const match4: string = `` +
|
||||
`if *\\(${variableMatch}\\('${hexMatch}'\\) *!== *${variableMatch}\\('${hexMatch}'\\)\\) *\\{` +
|
||||
`${variableMatch}.*` +
|
||||
`alert.*` +
|
||||
`\\} *else *\\{` +
|
||||
`console.*` +
|
||||
`\\}` +
|
||||
@@ -309,5 +309,30 @@ describe('DeadCodeInjectionTransformer', () => {
|
||||
assert.match(obfuscatedCode, regExp);
|
||||
});
|
||||
});
|
||||
|
||||
describe('variant #7 - correct obfuscation of dead-code block statements', () => {
|
||||
const variableName: string = 'importantVariableName';
|
||||
|
||||
let obfuscatedCode: string;
|
||||
|
||||
before(() => {
|
||||
const code: string = readFileAsString(__dirname + '/fixtures/obfuscation-of-dead-code-block-statements.js');
|
||||
const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
|
||||
code,
|
||||
{
|
||||
...NO_CUSTOM_NODES_PRESET,
|
||||
deadCodeInjection: true,
|
||||
deadCodeInjectionThreshold: 1,
|
||||
debugProtection: true
|
||||
}
|
||||
);
|
||||
|
||||
obfuscatedCode = obfuscationResult.getObfuscatedCode();
|
||||
});
|
||||
|
||||
it('should correctly obfuscate dead-code block statements and prevent any exposing of internal variable names', () => {
|
||||
assert.notInclude(obfuscatedCode, variableName);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
function test() {
|
||||
var importantVariableName = 'test';
|
||||
|
||||
return importantVariableName.indexOf('test');
|
||||
}
|
||||
Reference in New Issue
Block a user