javascript-obfuscator
Version:
JavaScript obfuscator
149 lines (124 loc) • 6.73 kB
text/typescript
import { inject, injectable } from 'inversify';
import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers';
import * as ESTree from 'estree';
import { TNodeWithStatements } from '../../../types/node/TNodeWithStatements';
import { TObjectExpressionKeysTransformerCustomNodeFactory } from '../../../types/container/custom-nodes/TObjectExpressionKeysTransformerCustomNodeFactory';
import { IObjectExpressionExtractorResult } from '../../../interfaces/node-transformers/converting-transformers/object-expression-extractors/IObjectExpressionExtractorResult';
import { TStatement } from '../../../types/node/TStatement';
import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode';
import { TInitialData } from '../../../types/TInitialData';
import { IObjectExpressionExtractor } from '../../../interfaces/node-transformers/converting-transformers/object-expression-extractors/IObjectExpressionExtractor';
import { ObjectExpressionKeysTransformerCustomNode } from '../../../enums/custom-nodes/ObjectExpressionKeysTransformerCustomNode';
import { ObjectExpressionVariableDeclarationHostNode } from '../../../custom-nodes/object-expression-keys-transformer-nodes/ObjectExpressionVariableDeclarationHostNode';
import { NodeAppender } from '../../../node/NodeAppender';
import { NodeGuards } from '../../../node/NodeGuards';
import { NodeStatementUtils } from '../../../node/NodeStatementUtils';
import { NodeUtils } from '../../../node/NodeUtils';
()
export class ObjectExpressionToVariableDeclarationExtractor implements IObjectExpressionExtractor {
/**
* @type {TObjectExpressionKeysTransformerCustomNodeFactory}
*/
private readonly objectExpressionKeysTransformerCustomNodeFactory: TObjectExpressionKeysTransformerCustomNodeFactory;
/**
* @param {TObjectExpressionKeysTransformerCustomNodeFactory} objectExpressionKeysTransformerCustomNodeFactory
*/
public constructor (
(ServiceIdentifiers.Factory__IObjectExpressionKeysTransformerCustomNode)
objectExpressionKeysTransformerCustomNodeFactory: TObjectExpressionKeysTransformerCustomNodeFactory,
) {
this.objectExpressionKeysTransformerCustomNodeFactory = objectExpressionKeysTransformerCustomNodeFactory;
}
/**
* extracts object expression:
* var object = {
* foo: 1,
* bar: 2
* };
*
* to:
* var _0xabc123 = {
* foo: 1,
* bar: 2
* };
* var object = _0xabc123;
*
* @param {ObjectExpression} objectExpressionNode
* @param {Statement} hostStatement
* @returns {IObjectExpressionExtractorResult}
*/
public extract (
objectExpressionNode: ESTree.ObjectExpression,
hostStatement: ESTree.Statement
): IObjectExpressionExtractorResult {
return this.transformObjectExpressionToVariableDeclaration(
objectExpressionNode,
hostStatement
);
}
/**
* @param {ObjectExpression} objectExpressionNode
* @param {Statement} hostStatement
* @returns {Node}
*/
private transformObjectExpressionToVariableDeclaration (
objectExpressionNode: ESTree.ObjectExpression,
hostStatement: ESTree.Statement
): IObjectExpressionExtractorResult {
const properties: ESTree.Property[] = objectExpressionNode.properties;
const newObjectExpressionHostStatement: ESTree.VariableDeclaration = this.getObjectExpressionHostNode(properties);
const newObjectExpressionIdentifier: ESTree.Identifier = this.getObjectExpressionIdentifierNode(newObjectExpressionHostStatement);
const newObjectExpressionNode: ESTree.ObjectExpression = this.getObjectExpressionNode(newObjectExpressionHostStatement);
const statementsToInsert: TStatement[] = [newObjectExpressionHostStatement];
const hostNodeWithStatements: TNodeWithStatements = NodeStatementUtils.getScopeOfNode(hostStatement);
NodeAppender.insertBefore(hostNodeWithStatements, statementsToInsert, hostStatement);
NodeUtils.parentizeAst(newObjectExpressionHostStatement);
NodeUtils.parentizeNode(newObjectExpressionHostStatement, hostNodeWithStatements);
return {
nodeToReplace: newObjectExpressionIdentifier,
objectExpressionHostStatement: newObjectExpressionHostStatement,
objectExpressionNode: newObjectExpressionNode
};
}
/**
* @param {Property[]} properties
* @returns {VariableDeclaration}
*/
private getObjectExpressionHostNode (properties: ESTree.Property[]): ESTree.VariableDeclaration {
const variableDeclarationHostNodeCustomNode: ICustomNode<TInitialData<ObjectExpressionVariableDeclarationHostNode>> =
this.objectExpressionKeysTransformerCustomNodeFactory(
ObjectExpressionKeysTransformerCustomNode.ObjectExpressionVariableDeclarationHostNode
);
variableDeclarationHostNodeCustomNode.initialize(properties);
const statementNode: TStatement = variableDeclarationHostNodeCustomNode.getNode()[0];
if (
!statementNode
|| !NodeGuards.isVariableDeclarationNode(statementNode)
) {
throw new Error('`objectExpressionHostCustomNode.getNode()[0]` should returns array with `VariableDeclaration` node');
}
return statementNode;
}
/**
* @param {VariableDeclaration} objectExpressionHostNode
* @returns {Identifier}
*/
private getObjectExpressionIdentifierNode (objectExpressionHostNode: ESTree.VariableDeclaration): ESTree.Identifier {
const newObjectExpressionIdentifierNode: ESTree.Pattern = objectExpressionHostNode.declarations[0].id;
if (!NodeGuards.isIdentifierNode(newObjectExpressionIdentifierNode)) {
throw new Error('`objectExpressionHostNode` should contain `VariableDeclarator` node with `Identifier` id property');
}
return newObjectExpressionIdentifierNode;
}
/**
* @param {VariableDeclaration} objectExpressionHostNode
* @returns {Identifier}
*/
private getObjectExpressionNode (objectExpressionHostNode: ESTree.VariableDeclaration): ESTree.ObjectExpression {
const newObjectExpressionNode: ESTree.Expression | null = objectExpressionHostNode.declarations[0].init ?? null;
if (!newObjectExpressionNode || !NodeGuards.isObjectExpressionNode(newObjectExpressionNode)) {
throw new Error('`objectExpressionHostNode` should contain `VariableDeclarator` node with `ObjectExpression` init property');
}
return newObjectExpressionNode;
}
}