Selaa lähdekoodia

Base mangle properties realisation

sanex3339 5 vuotta sitten
vanhempi
commit
f0465fc8f8

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist/index.cli.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist/index.js


+ 2 - 0
src/JavaScriptObfuscator.ts

@@ -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);

+ 2 - 0
src/container/InversifyContainerFacade.ts

@@ -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);

+ 1 - 0
src/container/ServiceIdentifiers.ts

@@ -33,6 +33,7 @@ export enum ServiceIdentifiers {
     IJavaScriptObfuscator = 'IJavaScriptObfuscator',
     ILevelledTopologicalSorter = 'ILevelledTopologicalSorter',
     ILogger = 'ILogger',
+    IManglePropertiesObfuscatingReplacer = 'IManglePropertiesObfuscatingReplacer',
     INodeGuard = 'INodeGuard',
     INodeTransformer = 'INodeTransformer',
     INodeTransformerNamesGroupsBuilder = 'INodeTransformerNamesGroupsBuilder',

+ 21 - 0
src/container/modules/node-transformers/ManglePropertiesTransformersModule.ts

@@ -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);
+});

+ 1 - 1
src/container/modules/node-transformers/ObfuscatingTransformersModule.ts

@@ -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 - 0
src/enums/node-transformers/NodeTransformationStage.ts

@@ -1,6 +1,7 @@
 export enum NodeTransformationStage {
     Initializing = 'Initializing',
     Preparing = 'Preparing',
+    MangleProperties = 'MangleProperties',
     DeadCodeInjection = 'DeadCodeInjection',
     ControlFlowFlattening = 'ControlFlowFlattening',
     Converting = 'Converting',

+ 1 - 0
src/enums/node-transformers/NodeTransformer.ts

@@ -7,6 +7,7 @@ export enum NodeTransformer {
     FunctionControlFlowTransformer = 'FunctionControlFlowTransformer',
     LabeledStatementTransformer = 'LabeledStatementTransformer',
     LiteralTransformer = 'LiteralTransformer',
+    ManglePropertiesTransformer = 'ManglePropertiesTransformer',
     MemberExpressionTransformer = 'MemberExpressionTransformer',
     MetadataTransformer = 'MetadataTransformer',
     MethodDefinitionTransformer = 'MethodDefinitionTransformer',

+ 9 - 0
src/interfaces/node-transformers/mangle-properties-transformers/replacer/IManglePropertiesReplacer.ts

@@ -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;
+}

+ 136 - 0
src/node-transformers/mangle-properties-transformers/ManglePropertiesTransformer.ts

@@ -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
src/node-transformers/mangle-properties-transformers/replacer/ManglePropertiesReplacer.ts

@@ -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);
+    }
+}

+ 22 - 4
test/dev/dev.ts

@@ -7,13 +7,31 @@ import { NO_ADDITIONAL_NODES_PRESET } from '../../src/options/presets/NoCustomNo
 
     let obfuscatedCode: string = JavaScriptObfuscator.obfuscate(
         `
-            var foo = 10n;
+            const foo = {
+                prop1: {
+                    prop2: 'bar'
+                }
+            };
+            
+            foo.prop1.prop2;
+            
+            const {prop1} = foo;
+            console.log(prop1.prop2);
+            
+            class Foo {
+                prop1 () {}
+            }
+            
+            const s = new Foo();
+
+            s.prop1();
         `,
         {
             ...NO_ADDITIONAL_NODES_PRESET,
-            renameGlobals: true,
-            stringArray: true,
-            stringArrayThreshold: 1
+            compact: false,
+            identifierNamesGenerator: 'mangled',
+            splitStrings: true,
+            splitStringsChunkLength: 3
         }
     ).getObfuscatedCode();
 

Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä