mirror of
https://github.com/javascript-obfuscator/javascript-obfuscator
synced 2026-08-09 12:42:29 +00:00
Fixed conflict between control flow storage and mangled identifiers
This commit is contained in:
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -48,21 +48,22 @@ export class BinaryExpressionFunctionNode extends AbstractCustomNode {
|
||||
* @returns {TStatement[]}
|
||||
*/
|
||||
protected getNodeStructure (): TStatement[] {
|
||||
const structure: TStatement = Nodes.getFunctionDeclarationNode(
|
||||
this.randomGenerator.getRandomString(3),
|
||||
[
|
||||
Nodes.getIdentifierNode('x'),
|
||||
Nodes.getIdentifierNode('y')
|
||||
],
|
||||
Nodes.getBlockStatementNode([
|
||||
Nodes.getReturnStatementNode(
|
||||
Nodes.getBinaryExpressionNode(
|
||||
this.operator,
|
||||
Nodes.getIdentifierNode('x'),
|
||||
Nodes.getIdentifierNode('y')
|
||||
const structure: TStatement = Nodes.getExpressionStatementNode(
|
||||
Nodes.getFunctionExpressionNode(
|
||||
[
|
||||
Nodes.getIdentifierNode('x'),
|
||||
Nodes.getIdentifierNode('y')
|
||||
],
|
||||
Nodes.getBlockStatementNode([
|
||||
Nodes.getReturnStatementNode(
|
||||
Nodes.getBinaryExpressionNode(
|
||||
this.operator,
|
||||
Nodes.getIdentifierNode('x'),
|
||||
Nodes.getIdentifierNode('y')
|
||||
)
|
||||
)
|
||||
)
|
||||
])
|
||||
])
|
||||
)
|
||||
);
|
||||
|
||||
NodeUtils.parentize(structure);
|
||||
|
||||
@@ -56,20 +56,21 @@ export class CallExpressionFunctionNode extends AbstractCustomNode {
|
||||
params.push(Nodes.getIdentifierNode(`param${i + 1}`));
|
||||
}
|
||||
|
||||
const structure: TStatement = Nodes.getFunctionDeclarationNode(
|
||||
this.randomGenerator.getRandomString(3),
|
||||
[
|
||||
calleeIdentifier,
|
||||
...params
|
||||
],
|
||||
Nodes.getBlockStatementNode([
|
||||
Nodes.getReturnStatementNode(
|
||||
Nodes.getCallExpressionNode(
|
||||
calleeIdentifier,
|
||||
params
|
||||
const structure: TStatement = Nodes.getExpressionStatementNode(
|
||||
Nodes.getFunctionExpressionNode(
|
||||
[
|
||||
calleeIdentifier,
|
||||
...params
|
||||
],
|
||||
Nodes.getBlockStatementNode([
|
||||
Nodes.getReturnStatementNode(
|
||||
Nodes.getCallExpressionNode(
|
||||
calleeIdentifier,
|
||||
params
|
||||
)
|
||||
)
|
||||
)
|
||||
])
|
||||
])
|
||||
)
|
||||
);
|
||||
|
||||
NodeUtils.parentize(structure);
|
||||
|
||||
@@ -48,21 +48,22 @@ export class LogicalExpressionFunctionNode extends AbstractCustomNode {
|
||||
* @returns {TStatement[]}
|
||||
*/
|
||||
protected getNodeStructure (): TStatement[] {
|
||||
const structure: TStatement = Nodes.getFunctionDeclarationNode(
|
||||
this.randomGenerator.getRandomString(3),
|
||||
[
|
||||
Nodes.getIdentifierNode('x'),
|
||||
Nodes.getIdentifierNode('y')
|
||||
],
|
||||
Nodes.getBlockStatementNode([
|
||||
Nodes.getReturnStatementNode(
|
||||
Nodes.getLogicalExpressionNode(
|
||||
this.operator,
|
||||
Nodes.getIdentifierNode('x'),
|
||||
Nodes.getIdentifierNode('y')
|
||||
const structure: TStatement = Nodes.getExpressionStatementNode(
|
||||
Nodes.getFunctionExpressionNode(
|
||||
[
|
||||
Nodes.getIdentifierNode('x'),
|
||||
Nodes.getIdentifierNode('y')
|
||||
],
|
||||
Nodes.getBlockStatementNode([
|
||||
Nodes.getReturnStatementNode(
|
||||
Nodes.getLogicalExpressionNode(
|
||||
this.operator,
|
||||
Nodes.getIdentifierNode('x'),
|
||||
Nodes.getIdentifierNode('y')
|
||||
)
|
||||
)
|
||||
)
|
||||
])
|
||||
])
|
||||
)
|
||||
);
|
||||
|
||||
NodeUtils.parentize(structure);
|
||||
|
||||
@@ -45,7 +45,9 @@ export class StringLiteralNode extends AbstractCustomNode {
|
||||
* @returns {TStatement[]}
|
||||
*/
|
||||
protected getNodeStructure (): TStatement[] {
|
||||
const structure: TStatement = <any>Nodes.getLiteralNode(this.literalValue);
|
||||
const structure: TStatement = Nodes.getExpressionStatementNode(
|
||||
Nodes.getLiteralNode(this.literalValue)
|
||||
);
|
||||
|
||||
return [structure];
|
||||
}
|
||||
|
||||
+17
-10
@@ -14,6 +14,7 @@ import { IStorage } from '../../../interfaces/storages/IStorage';
|
||||
import { initializable } from '../../../decorators/Initializable';
|
||||
|
||||
import { AbstractCustomNode } from '../../AbstractCustomNode';
|
||||
import { NodeGuards } from '../../../node/NodeGuards';
|
||||
import { Nodes } from '../../../node/Nodes';
|
||||
import { NodeUtils } from '../../../node/NodeUtils';
|
||||
|
||||
@@ -50,19 +51,25 @@ export class ControlFlowStorageNode extends AbstractCustomNode {
|
||||
* @returns {TStatement[]}
|
||||
*/
|
||||
protected getNodeStructure (): TStatement[] {
|
||||
const propertyNodes: ESTree.Property[] = Array
|
||||
.from<[string, ICustomNode]>(this.controlFlowStorage.getStorage())
|
||||
.map(([key, value]: [string, ICustomNode]) => {
|
||||
const node: ESTree.Node = value.getNode()[0];
|
||||
|
||||
if (!NodeGuards.isExpressionStatementNode(node)) {
|
||||
throw new Error('Function node for control flow storage object should be passed inside the `ExpressionStatement` node!');
|
||||
}
|
||||
|
||||
return Nodes.getPropertyNode(
|
||||
Nodes.getIdentifierNode(key),
|
||||
node.expression
|
||||
);
|
||||
});
|
||||
|
||||
let structure: ESTree.Node = Nodes.getVariableDeclarationNode([
|
||||
Nodes.getVariableDeclaratorNode(
|
||||
Nodes.getIdentifierNode(this.controlFlowStorage.getStorageId()),
|
||||
Nodes.getObjectExpressionNode(
|
||||
Array
|
||||
.from<[string, ICustomNode]>(this.controlFlowStorage.getStorage())
|
||||
.map(([key, value]: [string, ICustomNode]) => {
|
||||
return Nodes.getPropertyNode(
|
||||
Nodes.getIdentifierNode(key),
|
||||
<any>value.getNode()[0]
|
||||
);
|
||||
})
|
||||
)
|
||||
Nodes.getObjectExpressionNode(propertyNodes)
|
||||
)
|
||||
]);
|
||||
|
||||
|
||||
+2
-2
@@ -244,7 +244,7 @@ export class DeadCodeInjectionTransformer extends AbstractNodeTransformer {
|
||||
parentNode: ESTree.Node
|
||||
): ESTree.BlockStatement {
|
||||
/**
|
||||
* we should wrap original random block statement node into the parent block statement node (ast root host node)
|
||||
* Should wrap original random block statement node into the parent block statement node (ast root host node)
|
||||
* with function declaration node. This function declaration node will create block scope for all identifiers
|
||||
* inside random block statement node and this identifiers won't affect identifiers of the rest AST tree.
|
||||
*/
|
||||
@@ -257,7 +257,7 @@ export class DeadCodeInjectionTransformer extends AbstractNodeTransformer {
|
||||
]);
|
||||
|
||||
/**
|
||||
* we should store that host node and then extract random block statement node on the `finalizing` stage
|
||||
* Should store that host node and then extract random block statement node on the `finalizing` stage
|
||||
*/
|
||||
this.deadCodeInjectionRootAstHostNodeSet.add(deadCodeInjectionRootAstHostNode);
|
||||
|
||||
|
||||
+5
-5
@@ -14,14 +14,14 @@ describe('FunctionControlFlowTransformer', function () {
|
||||
const variableMatch: string = '_0x([a-f0-9]){4,6}';
|
||||
const rootControlFlowStorageNodeMatch: string = `` +
|
||||
`var *${variableMatch} *= *\\{` +
|
||||
`'\\w{5}' *: *function *${variableMatch} *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
|
||||
`'\\w{5}' *: *function *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
|
||||
`return *${variableMatch} *\\+ *${variableMatch};` +
|
||||
`\\}` +
|
||||
`\\};` +
|
||||
``;
|
||||
const innerControlFlowStorageNodeMatch: string = `` +
|
||||
`var *${variableMatch} *= *\\{` +
|
||||
`'\\w{5}' *: *function *${variableMatch} *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
|
||||
`'\\w{5}' *: *function *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
|
||||
`return *${variableMatch}\\['\\w{5}'\\]\\(${variableMatch}, *${variableMatch}\\);` +
|
||||
`\\}` +
|
||||
`\\};` +
|
||||
@@ -107,10 +107,10 @@ describe('FunctionControlFlowTransformer', function () {
|
||||
describe('variant #3 - single `control flow storage` node with multiple items', () => {
|
||||
const regexp: RegExp = new RegExp(
|
||||
`var *${variableMatch} *= *\\{` +
|
||||
`'\\w{5}' *: *function *${variableMatch} *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
|
||||
`'\\w{5}' *: *function *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
|
||||
`return *${variableMatch} *\\+ *${variableMatch};` +
|
||||
`\\}, *` +
|
||||
`'\\w{5}' *: *function *${variableMatch} *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
|
||||
`'\\w{5}' *: *function *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
|
||||
`return *${variableMatch} *- *${variableMatch};` +
|
||||
`\\}` +
|
||||
`\\};`
|
||||
@@ -167,7 +167,7 @@ describe('FunctionControlFlowTransformer', function () {
|
||||
|
||||
const regExp: RegExp = new RegExp(
|
||||
`var *[a-zA-Z]{6} *= *\\{` +
|
||||
`'\\w{5}' *: *function *_0x[0-9] *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
|
||||
`'\\w{5}' *: *function *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
|
||||
`return *${variableMatch} *\\+ *${variableMatch};` +
|
||||
`\\}` +
|
||||
`\\};`
|
||||
|
||||
+1
-1
@@ -106,7 +106,7 @@ describe('ObjectExpressionKeysTransformer', () => {
|
||||
describe('variant #4: correct integration with control flow flattening object', () => {
|
||||
const match: string = `` +
|
||||
`var *${variableMatch} *= *{};` +
|
||||
`${variableMatch}\\['\\w{5}'] *= *function *${variableMatch} *\\(${variableMatch}, *${variableMatch}\\) *{` +
|
||||
`${variableMatch}\\['\\w{5}'] *= *function *\\(${variableMatch}, *${variableMatch}\\) *{` +
|
||||
`return *${variableMatch} *\\+ *${variableMatch};` +
|
||||
`};` +
|
||||
`var *${variableMatch} *= *${variableMatch}\\['\\w{5}']\\(0x1, *0x2\\);` +
|
||||
|
||||
+1
-1
@@ -291,7 +291,7 @@ describe('EvalCallExpressionTransformer', () => {
|
||||
const variableMatch: string = '_0x([a-f0-9]){4,6}';
|
||||
const controlFlowStorageNodeMatch: string = `` +
|
||||
`var *${variableMatch} *= *\\{` +
|
||||
`'\\w{5}' *: *function *${variableMatch} *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
|
||||
`'\\w{5}' *: *function *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
|
||||
`return *${variableMatch} *\\+ *${variableMatch};` +
|
||||
`\\}` +
|
||||
`\\};` +
|
||||
|
||||
Reference in New Issue
Block a user