mirror of
https://github.com/javascript-obfuscator/javascript-obfuscator
synced 2026-08-09 12:42:29 +00:00
Base mangle properties realisation
This commit is contained in:
@@ -70,6 +70,7 @@ export class JavaScriptObfuscator implements IJavaScriptObfuscator {
|
||||
NodeTransformer.FunctionControlFlowTransformer,
|
||||
NodeTransformer.LabeledStatementTransformer,
|
||||
NodeTransformer.LiteralTransformer,
|
||||
NodeTransformer.ManglePropertiesTransformer,
|
||||
NodeTransformer.MemberExpressionTransformer,
|
||||
NodeTransformer.MetadataTransformer,
|
||||
NodeTransformer.MethodDefinitionTransformer,
|
||||
@@ -208,6 +209,7 @@ export class JavaScriptObfuscator implements IJavaScriptObfuscator {
|
||||
astTree = this.runNodeTransformationStage(astTree, NodeTransformationStage.ControlFlowFlattening);
|
||||
}
|
||||
|
||||
astTree = this.runNodeTransformationStage(astTree, NodeTransformationStage.MangleProperties);
|
||||
astTree = this.runNodeTransformationStage(astTree, NodeTransformationStage.Converting);
|
||||
astTree = this.runNodeTransformationStage(astTree, NodeTransformationStage.Obfuscating);
|
||||
astTree = this.runNodeTransformationStage(astTree, NodeTransformationStage.Finalizing);
|
||||
|
||||
@@ -10,6 +10,7 @@ import { customNodesModule } from './modules/custom-nodes/CustomNodesModule';
|
||||
import { finalizingTransformersModule } from './modules/node-transformers/FinalizingTransformersModule';
|
||||
import { generatorsModule } from './modules/generators/GeneratorsModule';
|
||||
import { initializingTransformersModule } from './modules/node-transformers/InitializingTransformersModule';
|
||||
import { manglePropertiesTransformersModule } from './modules/node-transformers/ManglePropertiesTransformersModule';
|
||||
import { nodeModule } from './modules/node/NodeModule';
|
||||
import { nodeTransformersModule } from './modules/node-transformers/NodeTransformersModule';
|
||||
import { obfuscatingTransformersModule } from './modules/node-transformers/ObfuscatingTransformersModule';
|
||||
@@ -210,6 +211,7 @@ export class InversifyContainerFacade implements IInversifyContainerFacade {
|
||||
this.container.load(finalizingTransformersModule);
|
||||
this.container.load(generatorsModule);
|
||||
this.container.load(initializingTransformersModule);
|
||||
this.container.load(manglePropertiesTransformersModule);
|
||||
this.container.load(nodeModule);
|
||||
this.container.load(nodeTransformersModule);
|
||||
this.container.load(obfuscatingTransformersModule);
|
||||
|
||||
@@ -33,6 +33,7 @@ export enum ServiceIdentifiers {
|
||||
IJavaScriptObfuscator = 'IJavaScriptObfuscator',
|
||||
ILevelledTopologicalSorter = 'ILevelledTopologicalSorter',
|
||||
ILogger = 'ILogger',
|
||||
IManglePropertiesObfuscatingReplacer = 'IManglePropertiesObfuscatingReplacer',
|
||||
INodeGuard = 'INodeGuard',
|
||||
INodeTransformer = 'INodeTransformer',
|
||||
INodeTransformerNamesGroupsBuilder = 'INodeTransformerNamesGroupsBuilder',
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import { ContainerModule, interfaces } from 'inversify';
|
||||
import { ServiceIdentifiers } from '../../ServiceIdentifiers';
|
||||
|
||||
import { IManglePropertiesReplacer } from '../../../interfaces/node-transformers/mangle-properties-transformers/replacer/IManglePropertiesReplacer';
|
||||
import { INodeTransformer } from '../../../interfaces/node-transformers/INodeTransformer';
|
||||
|
||||
import { NodeTransformer } from '../../../enums/node-transformers/NodeTransformer';
|
||||
|
||||
import { ManglePropertiesReplacer } from '../../../node-transformers/mangle-properties-transformers/replacer/ManglePropertiesReplacer';
|
||||
import { ManglePropertiesTransformer } from '../../../node-transformers/mangle-properties-transformers/ManglePropertiesTransformer';
|
||||
|
||||
export const manglePropertiesTransformersModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
|
||||
// mangle properties transformers
|
||||
bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
|
||||
.to(ManglePropertiesTransformer)
|
||||
.whenTargetNamed(NodeTransformer.ManglePropertiesTransformer);
|
||||
|
||||
// mangle properties obfuscating replacer
|
||||
bind<IManglePropertiesReplacer>(ServiceIdentifiers.IManglePropertiesObfuscatingReplacer)
|
||||
.to(ManglePropertiesReplacer);
|
||||
});
|
||||
@@ -45,7 +45,7 @@ export const obfuscatingTransformersModule: interfaces.ContainerModule = new Con
|
||||
.to(StringLiteralObfuscatingReplacer)
|
||||
.whenTargetNamed(LiteralObfuscatingReplacer.StringLiteralObfuscatingReplacer);
|
||||
|
||||
// identifier obfuscating replacers
|
||||
// identifier obfuscating replacer
|
||||
bind<IIdentifierObfuscatingReplacer>(ServiceIdentifiers.IIdentifierObfuscatingReplacer)
|
||||
.to(BaseIdentifierObfuscatingReplacer)
|
||||
.whenTargetNamed(IdentifierObfuscatingReplacer.BaseIdentifierObfuscatingReplacer);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
export enum NodeTransformationStage {
|
||||
Initializing = 'Initializing',
|
||||
Preparing = 'Preparing',
|
||||
MangleProperties = 'MangleProperties',
|
||||
DeadCodeInjection = 'DeadCodeInjection',
|
||||
ControlFlowFlattening = 'ControlFlowFlattening',
|
||||
Converting = 'Converting',
|
||||
|
||||
@@ -7,6 +7,7 @@ export enum NodeTransformer {
|
||||
FunctionControlFlowTransformer = 'FunctionControlFlowTransformer',
|
||||
LabeledStatementTransformer = 'LabeledStatementTransformer',
|
||||
LiteralTransformer = 'LiteralTransformer',
|
||||
ManglePropertiesTransformer = 'ManglePropertiesTransformer',
|
||||
MemberExpressionTransformer = 'MemberExpressionTransformer',
|
||||
MetadataTransformer = 'MetadataTransformer',
|
||||
MethodDefinitionTransformer = 'MethodDefinitionTransformer',
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
export interface IManglePropertiesReplacer {
|
||||
/**
|
||||
* @param {TNode} node
|
||||
* @returns {TNode}
|
||||
*/
|
||||
replace <TNode extends ESTree.Identifier | ESTree.Literal> (node: TNode): TNode;
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
import { inject, injectable, } from 'inversify';
|
||||
import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
|
||||
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { IManglePropertiesReplacer } from '../../interfaces/node-transformers/mangle-properties-transformers/replacer/IManglePropertiesReplacer';
|
||||
import { IOptions } from '../../interfaces/options/IOptions';
|
||||
import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
|
||||
import { IVisitor } from '../../interfaces/node-transformers/IVisitor';
|
||||
|
||||
import { NodeTransformationStage } from '../../enums/node-transformers/NodeTransformationStage';
|
||||
|
||||
import { AbstractNodeTransformer } from '../AbstractNodeTransformer';
|
||||
import { NodeGuards } from '../../node/NodeGuards';
|
||||
|
||||
@injectable()
|
||||
export class ManglePropertiesTransformer extends AbstractNodeTransformer {
|
||||
/**
|
||||
* @type {IManglePropertiesReplacer}
|
||||
*/
|
||||
private readonly manglePropertiesObfuscatingReplacer: IManglePropertiesReplacer;
|
||||
|
||||
/**
|
||||
* @param {IManglePropertiesReplacer} manglePropertiesObfuscatingReplacer
|
||||
* @param {IRandomGenerator} randomGenerator
|
||||
* @param {IOptions} options
|
||||
*/
|
||||
public constructor (
|
||||
@inject(ServiceIdentifiers.IManglePropertiesObfuscatingReplacer)
|
||||
manglePropertiesObfuscatingReplacer: IManglePropertiesReplacer,
|
||||
@inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
|
||||
@inject(ServiceIdentifiers.IOptions) options: IOptions
|
||||
) {
|
||||
super(randomGenerator, options);
|
||||
|
||||
this.manglePropertiesObfuscatingReplacer = manglePropertiesObfuscatingReplacer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {NodeTransformationStage} nodeTransformationStage
|
||||
* @returns {IVisitor | null}
|
||||
*/
|
||||
public getVisitor (nodeTransformationStage: NodeTransformationStage): IVisitor | null {
|
||||
switch (nodeTransformationStage) {
|
||||
case NodeTransformationStage.MangleProperties:
|
||||
return {
|
||||
enter: (node: ESTree.Node, parentNode: ESTree.Node | null): ESTree.Node | undefined => {
|
||||
if (parentNode) {
|
||||
return this.transformNode(node, parentNode);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
};
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Node} node
|
||||
* @param {NodeGuards} parentNode
|
||||
* @returns {Node}
|
||||
*/
|
||||
public transformNode (node: ESTree.Node, parentNode: ESTree.Node): ESTree.Node {
|
||||
if (NodeGuards.isPropertyNode(node)) {
|
||||
return this.transformPropertyNode(node);
|
||||
}
|
||||
|
||||
if (NodeGuards.isMemberExpressionNode(node)) {
|
||||
return this.transformMemberExpressionNode(node);
|
||||
}
|
||||
|
||||
if (NodeGuards.isMethodDefinitionNode(node)) {
|
||||
return this.transformMethodDefinitionNode(node);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Property} propertyNode
|
||||
* @returns {Property}
|
||||
*/
|
||||
private transformPropertyNode (propertyNode: ESTree.Property): ESTree.Property {
|
||||
const propertyKeyNode: ESTree.Expression = propertyNode.key;
|
||||
|
||||
if (NodeGuards.isIdentifierNode(propertyKeyNode) && propertyNode.computed) {
|
||||
return propertyNode;
|
||||
}
|
||||
|
||||
if (NodeGuards.isIdentifierNode(propertyKeyNode) || NodeGuards.isLiteralNode(propertyKeyNode)) {
|
||||
propertyNode.key = this.manglePropertiesObfuscatingReplacer.replace(propertyKeyNode);
|
||||
propertyNode.shorthand = false;
|
||||
}
|
||||
|
||||
return propertyNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Property} memberExpressionNode
|
||||
* @returns {Property}
|
||||
*/
|
||||
private transformMemberExpressionNode (memberExpressionNode: ESTree.MemberExpression): ESTree.MemberExpression {
|
||||
const propertyKeyNode: ESTree.Expression = memberExpressionNode.property;
|
||||
|
||||
if (NodeGuards.isIdentifierNode(propertyKeyNode) && memberExpressionNode.computed) {
|
||||
return memberExpressionNode;
|
||||
}
|
||||
|
||||
if (NodeGuards.isIdentifierNode(propertyKeyNode) || NodeGuards.isLiteralNode(propertyKeyNode)) {
|
||||
memberExpressionNode.property = this.manglePropertiesObfuscatingReplacer.replace(propertyKeyNode);
|
||||
}
|
||||
|
||||
return memberExpressionNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {MethodDefinition} methodDefinitionNode
|
||||
* @returns {MethodDefinition}
|
||||
*/
|
||||
private transformMethodDefinitionNode (methodDefinitionNode: ESTree.MethodDefinition): ESTree.MethodDefinition {
|
||||
const propertyKeyNode: ESTree.Expression = methodDefinitionNode.key;
|
||||
|
||||
if (NodeGuards.isIdentifierNode(propertyKeyNode) && methodDefinitionNode.computed) {
|
||||
return methodDefinitionNode;
|
||||
}
|
||||
|
||||
if (NodeGuards.isIdentifierNode(propertyKeyNode) || NodeGuards.isLiteralNode(propertyKeyNode)) {
|
||||
methodDefinitionNode.key = this.manglePropertiesObfuscatingReplacer.replace(propertyKeyNode);
|
||||
}
|
||||
|
||||
return methodDefinitionNode;
|
||||
}
|
||||
}
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
import { inject, injectable, } from 'inversify';
|
||||
import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers';
|
||||
|
||||
import * as ESTree from 'estree';
|
||||
|
||||
import { TIdentifierNamesGeneratorFactory } from '../../../types/container/generators/TIdentifierNamesGeneratorFactory';
|
||||
|
||||
import { IIdentifierNamesGenerator } from '../../../interfaces/generators/identifier-names-generators/IIdentifierNamesGenerator';
|
||||
import { IManglePropertiesReplacer } from '../../../interfaces/node-transformers/mangle-properties-transformers/replacer/IManglePropertiesReplacer';
|
||||
import { IOptions } from '../../../interfaces/options/IOptions';
|
||||
|
||||
import { ReservedDomProperties } from '../../../constants/ReservedDomProperties';
|
||||
|
||||
import { NodeGuards } from '../../../node/NodeGuards';
|
||||
import { NodeFactory } from '../../../node/NodeFactory';
|
||||
|
||||
@injectable()
|
||||
export class ManglePropertiesReplacer implements IManglePropertiesReplacer {
|
||||
/**
|
||||
* @type {IIdentifierNamesGenerator}
|
||||
*/
|
||||
private readonly identifierNamesGenerator: IIdentifierNamesGenerator;
|
||||
|
||||
/**
|
||||
* @type {Map<string, string>}
|
||||
* @private
|
||||
*/
|
||||
private readonly mangledPropertyNamesMap: Map<string, string> = new Map();
|
||||
|
||||
/**
|
||||
* @type {IOptions}
|
||||
*/
|
||||
private readonly options: IOptions;
|
||||
|
||||
/**
|
||||
* @type {Set<string>}
|
||||
*/
|
||||
private readonly reservedDomPropertiesList: Set<string> = new Set(ReservedDomProperties);
|
||||
|
||||
|
||||
/**
|
||||
* @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
|
||||
* @param {IOptions} options
|
||||
*/
|
||||
public constructor (
|
||||
@inject(ServiceIdentifiers.Factory__IIdentifierNamesGenerator)
|
||||
identifierNamesGeneratorFactory: TIdentifierNamesGeneratorFactory,
|
||||
@inject(ServiceIdentifiers.IOptions) options: IOptions
|
||||
) {
|
||||
this.identifierNamesGenerator = identifierNamesGeneratorFactory(options);
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} node
|
||||
* @returns {string}
|
||||
*/
|
||||
public replace <TNode extends ESTree.Identifier | ESTree.Literal> (node: TNode): TNode {
|
||||
if (NodeGuards.isIdentifierNode(node)) {
|
||||
return <TNode>NodeFactory.identifierNode(
|
||||
this.replacePropertyName(node.name)
|
||||
);
|
||||
}
|
||||
|
||||
if (NodeGuards.isLiteralNode(node) && typeof node.value === 'string') {
|
||||
return <TNode>NodeFactory.literalNode(
|
||||
this.replacePropertyName(node.value)
|
||||
);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} propertyName
|
||||
* @returns {string}
|
||||
* @private
|
||||
*/
|
||||
private replacePropertyName (propertyName: string): string {
|
||||
if (this.isReservedName(propertyName)) {
|
||||
return propertyName;
|
||||
}
|
||||
|
||||
let mangledPropertyName: string;
|
||||
|
||||
if (this.mangledPropertyNamesMap.has(propertyName)) {
|
||||
mangledPropertyName = <string>this.mangledPropertyNamesMap.get(propertyName);
|
||||
} else {
|
||||
mangledPropertyName = this.identifierNamesGenerator.generateNext();
|
||||
this.mangledPropertyNamesMap.set(propertyName, mangledPropertyName);
|
||||
}
|
||||
|
||||
return mangledPropertyName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} name
|
||||
* @returns {boolean}
|
||||
*/
|
||||
private isReservedName (name: string): boolean {
|
||||
return this.isReservedOptionName(name)
|
||||
|| this.isReservedDomPropertyName(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} name
|
||||
* @returns {boolean}
|
||||
*/
|
||||
private isReservedOptionName (name: string): boolean {
|
||||
if (!this.options.reservedNames.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.options.reservedNames
|
||||
.some((reservedName: string) => {
|
||||
return new RegExp(reservedName, 'g').exec(name) !== null;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} name
|
||||
* @returns {boolean}
|
||||
*/
|
||||
private isReservedDomPropertyName (name: string): boolean {
|
||||
return this.reservedDomPropertiesList.has(name);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user