Przeglądaj źródła

performance boost

sanex3339 8 lat temu
rodzic
commit
d2d5517dd1

Plik diff jest za duży
+ 191 - 183
dist/index.js


+ 19 - 0
src/container/modules/custom-nodes/CustomNodesModule.ts

@@ -3,6 +3,7 @@ import { ServiceIdentifiers } from '../../ServiceIdentifiers';
 
 import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode';
 import { ICustomNodeGroup } from '../../../interfaces/custom-nodes/ICustomNodeGroup';
+import { IOptions } from '../../../interfaces/options/IOptions';
 
 import { CustomNodes } from '../../../enums/container/CustomNodes';
 import { CustomNodeGroups } from '../../../enums/container/CustomNodeGroups';
@@ -105,7 +106,25 @@ export const customNodesModule: interfaces.ContainerModule = new ContainerModule
     // customNode factory
     bind<ICustomNode>(ServiceIdentifiers['Factory<ICustomNode>'])
         .toFactory<ICustomNode>((context: interfaces.Context) => {
+            let cachedOptions: IOptions;
+
             return (customNodeName: CustomNodes) => {
+                if (!cachedOptions) {
+                    cachedOptions = context.container.get<IOptions>(ServiceIdentifiers.IOptions);
+                }
+
+                // we should avoid automatic resolve for custom nodes which will resolve during traverse over AST tree
+                switch (customNodeName) {
+                    case CustomNodes.BinaryExpressionFunctionNode:
+                        return new BinaryExpressionFunctionNode(cachedOptions);
+
+                    case CustomNodes.ControlFlowStorageCallNode:
+                        return new ControlFlowStorageCallNode(cachedOptions);
+
+                    case CustomNodes.ControlFlowStorageNode:
+                        return new ControlFlowStorageNode(cachedOptions);
+                }
+
                 return context.container.getNamed<ICustomNode>(
                     ServiceIdentifiers.ICustomNode,
                     customNodeName

+ 1 - 1
src/container/modules/storages/StoragesModule.ts

@@ -26,7 +26,7 @@ export const storagesModule: interfaces.ContainerModule = new ContainerModule((b
     bind<IStorage<ICustomNode>>(ServiceIdentifiers['Factory<IStorage<ICustomNode>>'])
         .toFactory<IStorage<ICustomNode>>((context: interfaces.Context) => {
             return () => {
-                return context.container.get<IStorage<ICustomNode>>(ServiceIdentifiers['IStorage<ICustomNode>']);
+                return new ControlFlowStorage();
             };
         });
 });

+ 1 - 1
src/custom-nodes/string-array-nodes/group/StringArrayCustomNodeGroup.ts

@@ -108,7 +108,7 @@ export class StringArrayCustomNodeGroup extends AbstractCustomNodeGroup {
         const stringArrayStorageId: string = this.stringArrayStorage.getStorageId();
 
         const stringArrayName: string = `_${Utils.hexadecimalPrefix}${stringArrayStorageId}`;
-        const stringArrayCallsWrapperName: string = `_${Utils.hexadecimalPrefix}${Utils.stringRotate(stringArrayStorageId, 2)}`;
+        const stringArrayCallsWrapperName: string = `_${Utils.hexadecimalPrefix}${Utils.stringRotate(stringArrayStorageId, 1)}`;
 
         let stringArrayRotateValue: number;
 

+ 8 - 10
src/node-transformers/node-control-flow-transformers/FunctionControlFlowTransformer.ts

@@ -129,9 +129,7 @@ export class FunctionControlFlowTransformer extends AbstractNodeTransformer {
         const controlFlowStorage: IStorage <ICustomNode> = this.controlFlowStorageFactory();
         const hostNode: TNodeWithBlockStatement = FunctionControlFlowTransformer.getHostNode(functionNode);
 
-        if (!this.controlFlowData.has(hostNode)) {
-            this.controlFlowData.set(hostNode, controlFlowStorage);
-        } else {
+        if (this.controlFlowData.has(hostNode)) {
             if (this.hostNodesWithControlFlowNode.indexOf(hostNode) !== -1) {
                 hostNode.body.shift();
             }
@@ -139,23 +137,23 @@ export class FunctionControlFlowTransformer extends AbstractNodeTransformer {
             const hostControlFlowStorage: IStorage<ICustomNode> = <IStorage<ICustomNode>>this.controlFlowData.get(hostNode);
 
             controlFlowStorage.mergeWith(hostControlFlowStorage, true);
-
-            this.controlFlowData.set(hostNode, controlFlowStorage);
         }
 
+        this.controlFlowData.set(hostNode, controlFlowStorage);
+
         estraverse.replace(functionNode.body, {
             enter: (node: ESTree.Node, parentNode: ESTree.Node): any => {
-                if (RandomGeneratorUtils.getRandomFloat(0, 1) > this.options.controlFlowFlatteningThreshold) {
+                if (!FunctionControlFlowTransformer.controlFlowReplacersMap.has(node.type)) {
                     return;
                 }
 
-                const controlFlowReplacerName: NodeControlFlowReplacers | undefined = FunctionControlFlowTransformer
-                    .controlFlowReplacersMap.get(node.type);
-
-                if (controlFlowReplacerName === undefined) {
+                if (RandomGeneratorUtils.getRandomFloat(0, 1) > this.options.controlFlowFlatteningThreshold) {
                     return;
                 }
 
+                const controlFlowReplacerName: NodeControlFlowReplacers = <NodeControlFlowReplacers>FunctionControlFlowTransformer
+                    .controlFlowReplacersMap.get(node.type);
+
                 return {
                     ...this.controlFlowReplacerFactory(controlFlowReplacerName)
                         .replace(node, parentNode, controlFlowStorage),

+ 23 - 31
src/node-transformers/node-obfuscators/MemberExpressionObfuscator.ts

@@ -2,7 +2,6 @@ import { injectable, inject } from 'inversify';
 import { ServiceIdentifiers } from '../../container/ServiceIdentifiers';
 
 import * as escodegen from 'escodegen';
-import * as estraverse from 'estraverse';
 import * as ESTree from 'estree';
 
 import { IOptions } from '../../interfaces/options/IOptions';
@@ -38,24 +37,18 @@ export class MemberExpressionObfuscator extends AbstractNodeTransformer {
      * @param memberExpressionNode
      */
     public transformNode (memberExpressionNode: ESTree.MemberExpression): void {
-        estraverse.traverse(memberExpressionNode.property, {
-            enter: (node: ESTree.Node, parentNode: ESTree.Node): any => {
-                if (Node.isLiteralNode(node)) {
-                    this.obfuscateLiteralProperty(node);
-
-                    return;
-                }
-
-                if (Node.isIdentifierNode(node)) {
-                    if (memberExpressionNode.computed) {
-                        return;
-                    }
+        if (Node.isLiteralNode(memberExpressionNode.property)) {
+            memberExpressionNode.property = this.obfuscateLiteralProperty(memberExpressionNode.property);
+        }
 
-                    memberExpressionNode.computed = true;
-                    this.obfuscateIdentifierProperty(node);
-                }
+        if (Node.isIdentifierNode(memberExpressionNode.property)) {
+            if (memberExpressionNode.computed) {
+                return;
             }
-        });
+
+            memberExpressionNode.computed = true;
+            memberExpressionNode.property = this.obfuscateIdentifierProperty(memberExpressionNode.property);
+        }
     }
 
     /**
@@ -69,22 +62,18 @@ export class MemberExpressionObfuscator extends AbstractNodeTransformer {
      *     object[identifier] = 1;
      *
      * @param node
+     * @returns {ESTree.Literal}
      */
-    private obfuscateIdentifierProperty (node: ESTree.Identifier): void {
-        const nodeValue: string = node.name;
-        const literalNode: ESTree.Literal = {
-            raw: `'${nodeValue}'`,
+    private obfuscateIdentifierProperty (node: ESTree.Identifier): ESTree.Literal {
+        return {
+            type: NodeType.Literal,
+            value: node.name,
+            raw: `'${node.name}'`,
             'x-verbatim-property': {
-                content: this.stringLiteralReplacer.replace(nodeValue),
+                content: this.stringLiteralReplacer.replace(node.name),
                 precedence: escodegen.Precedence.Primary
-            },
-            type: NodeType.Literal,
-            value: nodeValue
+            }
         };
-
-        delete node.name;
-
-        Object.assign(node, literalNode);
     }
 
     /**
@@ -95,13 +84,16 @@ export class MemberExpressionObfuscator extends AbstractNodeTransformer {
      *     object[_0x23d45[25]] = 1;
      *
      * @param node
+     * @returns {ESTree.Literal}
      */
-    private obfuscateLiteralProperty (node: ESTree.Literal): void {
+    private obfuscateLiteralProperty (node: ESTree.Literal): ESTree.Literal {
         if (typeof node.value === 'string' && !node['x-verbatim-property']) {
             node['x-verbatim-property'] = {
-                content : this.stringLiteralReplacer.replace(node.value),
+                content: this.stringLiteralReplacer.replace(node.value),
                 precedence: escodegen.Precedence.Primary
             };
         }
+
+        return node;
     }
 }

+ 1 - 1
src/node-transformers/node-obfuscators/replacers/StringLiteralReplacer.ts

@@ -103,7 +103,7 @@ export class StringLiteralReplacer extends AbstractReplacer {
             this.stringArrayStorage.set(null, value);
         }
 
-        const rotatedStringArrayStorageId: string = Utils.stringRotate(this.stringArrayStorage.getStorageId(), 2);
+        const rotatedStringArrayStorageId: string = Utils.stringRotate(this.stringArrayStorage.getStorageId(), 1);
         const stringArrayStorageCallsWrapperName: string = `_${Utils.hexadecimalPrefix}${rotatedStringArrayStorageId}`;
         const hexadecimalIndex: string = `${Utils.hexadecimalPrefix}${Utils.decToHex(indexOfValue)}`;
 

+ 1 - 1
src/storages/MapStorage.ts

@@ -47,7 +47,7 @@ export abstract class MapStorage <T> implements IStorage <T> {
      * @returns {number}
      */
     public getLength (): number {
-        return Array.from(this.storage).length;
+        return this.storage.size;
     }
 
     /**

+ 10 - 2
src/utils/Utils.ts

@@ -98,7 +98,15 @@ export class Utils {
      * @returns {string}
      */
     public static stringRotate (string: string, times: number): string {
-        return Utils.arrayRotate(Array.from(string), times).join('');
+        if (!string) {
+            throw new ReferenceError(`Cannot rotate empty string.`);
+        }
+
+        for (let i = 0; i < times; i++) {
+            string = string[string.length - 1] + string.substring(0, string.length - 1);
+        }
+
+        return string;
     }
 
     /**
@@ -133,7 +141,7 @@ export class Utils {
                 prefix = '\\u';
                 template = '0'.repeat(4);
             }
-
+            
             return `${prefix}${(template + escape.charCodeAt(0).toString(radix)).slice(-template.length)}`;
         })}`;
     }

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików