Преглед изворни кода

Additional tests for eval expressions obfuscation. Added new `finalizing` transformers category

sanex3339 пре 7 година
родитељ
комит
21a2fd65b5
16 измењених фајлова са 83 додато и 29 уклоњено
  1. 0 0
      dist/index.js
  2. 13 13
      src/JavaScriptObfuscator.ts
  3. 2 0
      src/container/InversifyContainerFacade.ts
  4. 0 10
      src/container/modules/node-transformers/ConvertingTransformersModule.ts
  5. 15 0
      src/container/modules/node-transformers/FinalizingTransformersModule.ts
  6. 5 0
      src/container/modules/node-transformers/PreparingTransformersModule.ts
  7. 0 0
      src/node-transformers/finalizing-transformers/AstToEvalCallExpressionTransformer.ts
  8. 0 0
      src/node-transformers/preparing-transformers/EvaCallExpressionToAstTransformer.ts
  9. 42 5
      test/functional-tests/node-transformers/finalizing-transformers/ast-to-eval-call-expression-transformer/AstToEvalCallExpressionTransformer.spec.ts
  10. 0 0
      test/functional-tests/node-transformers/finalizing-transformers/ast-to-eval-call-expression-transformer/fixtures/call-expression-identifier-reference.js
  11. 5 0
      test/functional-tests/node-transformers/finalizing-transformers/ast-to-eval-call-expression-transformer/fixtures/control-flow-flattening-integration.js
  12. 0 0
      test/functional-tests/node-transformers/finalizing-transformers/ast-to-eval-call-expression-transformer/fixtures/eval-expression-as-argument.js
  13. 0 0
      test/functional-tests/node-transformers/finalizing-transformers/ast-to-eval-call-expression-transformer/fixtures/identifier-reference.js
  14. 0 0
      test/functional-tests/node-transformers/finalizing-transformers/ast-to-eval-call-expression-transformer/fixtures/multiple-statements-eval.js
  15. 0 0
      test/functional-tests/node-transformers/finalizing-transformers/ast-to-eval-call-expression-transformer/fixtures/string-array-calls-wrapper-call.js
  16. 1 1
      test/index.spec.ts

Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
dist/index.js


+ 13 - 13
src/JavaScriptObfuscator.ts

@@ -48,15 +48,7 @@ export class JavaScriptObfuscator implements IJavaScriptObfuscator {
     /**
      * @type {NodeTransformer[]}
      */
-    private static readonly postObfuscationConvertingTransformersList: NodeTransformer[] = [
-        NodeTransformer.AstToEvalCallExpressionTransformer
-    ];
-
-    /**
-     * @type {NodeTransformer[]}
-     */
-    private static readonly preObfuscationConvertingTransformersList: NodeTransformer[] = [
-        NodeTransformer.EvalCallExpressionToAstTransformer,
+    private static readonly convertingTransformersList: NodeTransformer[] = [
         NodeTransformer.MemberExpressionTransformer,
         NodeTransformer.MethodDefinitionTransformer,
         NodeTransformer.ObjectExpressionKeysTransformer,
@@ -70,6 +62,13 @@ export class JavaScriptObfuscator implements IJavaScriptObfuscator {
         NodeTransformer.DeadCodeInjectionTransformer
     ];
 
+    /**
+     * @type {NodeTransformer[]}
+     */
+    private static readonly finalizingTransformersList: NodeTransformer[] = [
+        NodeTransformer.AstToEvalCallExpressionTransformer
+    ];
+
     /**
      * @type {NodeTransformer[]}
      */
@@ -89,6 +88,7 @@ export class JavaScriptObfuscator implements IJavaScriptObfuscator {
      */
     private static readonly preparingTransformersList: NodeTransformer[] = [
         NodeTransformer.CommentsTransformer,
+        NodeTransformer.EvalCallExpressionToAstTransformer,
         NodeTransformer.ObfuscatingGuardsTransformer,
         NodeTransformer.ParentificationTransformer
     ];
@@ -259,11 +259,11 @@ export class JavaScriptObfuscator implements IJavaScriptObfuscator {
             );
         }
 
-        // fifth pass: pre-obfuscation converting transformers
+        // fifth pass: converting transformers
         this.logger.info(LoggingMessage.StagePreObfuscation);
         astTree = this.transformersRunner.transform(
             astTree,
-            JavaScriptObfuscator.preObfuscationConvertingTransformersList
+            JavaScriptObfuscator.convertingTransformersList
         );
 
         // sixth pass: obfuscating transformers
@@ -273,11 +273,11 @@ export class JavaScriptObfuscator implements IJavaScriptObfuscator {
             JavaScriptObfuscator.obfuscatingTransformersList
         );
 
-        // seventh pass: post-obfuscation converting transformers
+        // seventh pass: finalizing transformers
         this.logger.info(LoggingMessage.StagePostObfuscation);
         astTree = this.transformersRunner.transform(
             astTree,
-            JavaScriptObfuscator.postObfuscationConvertingTransformersList
+            JavaScriptObfuscator.finalizingTransformersList
         );
 
         this.obfuscationEventEmitter.emit(ObfuscationEvent.AfterObfuscation, astTree, stackTraceData);

+ 2 - 0
src/container/InversifyContainerFacade.ts

@@ -5,6 +5,7 @@ import { analyzersModule } from './modules/analyzers/AnalyzersModule';
 import { controlFlowTransformersModule } from './modules/node-transformers/ControlFlowTransformersModule';
 import { convertingTransformersModule } from './modules/node-transformers/ConvertingTransformersModule';
 import { customNodesModule } from './modules/custom-nodes/CustomNodesModule';
+import { finalizingTransformersModule } from './modules/node-transformers/FinalizingTransformersModule';
 import { generatorsModule } from './modules/generators/GeneratorsModule';
 import { nodeTransformersModule } from './modules/node-transformers/NodeTransformersModule';
 import { obfuscatingTransformersModule } from './modules/node-transformers/ObfuscatingTransformersModule';
@@ -198,6 +199,7 @@ export class InversifyContainerFacade implements IInversifyContainerFacade {
         this.container.load(controlFlowTransformersModule);
         this.container.load(convertingTransformersModule);
         this.container.load(customNodesModule);
+        this.container.load(finalizingTransformersModule);
         this.container.load(generatorsModule);
         this.container.load(nodeTransformersModule);
         this.container.load(obfuscatingTransformersModule);

+ 0 - 10
src/container/modules/node-transformers/ConvertingTransformersModule.ts

@@ -5,8 +5,6 @@ import { INodeTransformer } from '../../../interfaces/node-transformers/INodeTra
 
 import { NodeTransformer } from '../../../enums/node-transformers/NodeTransformer';
 
-import { AstToEvalCallExpressionTransformer } from '../../../node-transformers/converting-transformers/AstToEvalCallExpressionTransformer';
-import { EvalCallExpressionToAstTransformer } from '../../../node-transformers/converting-transformers/EvaCallExpressionToAstTransformer';
 import { MemberExpressionTransformer } from '../../../node-transformers/converting-transformers/MemberExpressionTransformer';
 import { MethodDefinitionTransformer } from '../../../node-transformers/converting-transformers/MethodDefinitionTransformer';
 import { ObjectExpressionKeysTransformer } from '../../../node-transformers/converting-transformers/ObjectExpressionKeysTransformer';
@@ -14,14 +12,6 @@ import { TemplateLiteralTransformer } from '../../../node-transformers/convertin
 
 export const convertingTransformersModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
     // converting transformers
-    bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
-        .to(AstToEvalCallExpressionTransformer)
-        .whenTargetNamed(NodeTransformer.AstToEvalCallExpressionTransformer);
-
-    bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
-        .to(EvalCallExpressionToAstTransformer)
-        .whenTargetNamed(NodeTransformer.EvalCallExpressionToAstTransformer);
-
     bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
         .to(MemberExpressionTransformer)
         .whenTargetNamed(NodeTransformer.MemberExpressionTransformer);

+ 15 - 0
src/container/modules/node-transformers/FinalizingTransformersModule.ts

@@ -0,0 +1,15 @@
+import { ContainerModule, interfaces } from 'inversify';
+import { ServiceIdentifiers } from '../../ServiceIdentifiers';
+
+import { INodeTransformer } from '../../../interfaces/node-transformers/INodeTransformer';
+
+import { NodeTransformer } from '../../../enums/node-transformers/NodeTransformer';
+
+import { AstToEvalCallExpressionTransformer } from '../../../node-transformers/finalizing-transformers/AstToEvalCallExpressionTransformer';
+
+export const finalizingTransformersModule: interfaces.ContainerModule = new ContainerModule((bind: interfaces.Bind) => {
+    // finalizing transformers
+    bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
+        .to(AstToEvalCallExpressionTransformer)
+        .whenTargetNamed(NodeTransformer.AstToEvalCallExpressionTransformer);
+});

+ 5 - 0
src/container/modules/node-transformers/PreparingTransformersModule.ts

@@ -11,6 +11,7 @@ import { ObfuscatingGuard } from '../../../enums/node-transformers/preparing-tra
 import { BlackListObfuscatingGuard } from '../../../node-transformers/preparing-transformers/obfuscating-guards/BlackListObfuscatingGuard';
 import { CommentsTransformer } from '../../../node-transformers/preparing-transformers/CommentsTransformer';
 import { ConditionalCommentObfuscatingGuard } from '../../../node-transformers/preparing-transformers/obfuscating-guards/ConditionalCommentObfuscatingGuard';
+import { EvalCallExpressionToAstTransformer } from '../../../node-transformers/preparing-transformers/EvaCallExpressionToAstTransformer';
 import { ObfuscatingGuardsTransformer } from '../../../node-transformers/preparing-transformers/ObfuscatingGuardsTransformer';
 import { ParentificationTransformer } from '../../../node-transformers/preparing-transformers/ParentificationTransformer';
 
@@ -20,6 +21,10 @@ export const preparingTransformersModule: interfaces.ContainerModule = new Conta
         .to(CommentsTransformer)
         .whenTargetNamed(NodeTransformer.CommentsTransformer);
 
+    bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
+        .to(EvalCallExpressionToAstTransformer)
+        .whenTargetNamed(NodeTransformer.EvalCallExpressionToAstTransformer);
+
     bind<INodeTransformer>(ServiceIdentifiers.INodeTransformer)
         .to(ObfuscatingGuardsTransformer)
         .whenTargetNamed(NodeTransformer.ObfuscatingGuardsTransformer);

+ 0 - 0
src/node-transformers/converting-transformers/AstToEvalCallExpressionTransformer.ts → src/node-transformers/finalizing-transformers/AstToEvalCallExpressionTransformer.ts


+ 0 - 0
src/node-transformers/converting-transformers/EvaCallExpressionToAstTransformer.ts → src/node-transformers/preparing-transformers/EvaCallExpressionToAstTransformer.ts


+ 42 - 5
test/functional-tests/node-transformers/converting-transformers/ast-to-eval-call-expression-transformer/AstToEvalCallExpressionTransformer.spec.ts → test/functional-tests/node-transformers/finalizing-transformers/ast-to-eval-call-expression-transformer/AstToEvalCallExpressionTransformer.spec.ts

@@ -66,7 +66,7 @@ describe('AstToEvalCallExpressionTransformer', () => {
         });
 
         it('should obfuscate eval string', () => {
-            assert.match(obfuscatedCode,  variableReferenceIdentifierRegExp);
+            assert.match(obfuscatedCode, variableReferenceIdentifierRegExp);
         });
 
         it('should correctly transform function parameter inside eval expression', () => {
@@ -92,7 +92,7 @@ describe('AstToEvalCallExpressionTransformer', () => {
         });
 
         it('should obfuscate eval string', () => {
-            assert.match(obfuscatedCode,  regExp);
+            assert.match(obfuscatedCode, regExp);
         });
     });
 
@@ -117,11 +117,11 @@ describe('AstToEvalCallExpressionTransformer', () => {
         });
 
         it('match #1: should add strings from eval expression to the string array', () => {
-            assert.match(obfuscatedCode,  stringArrayRegExp);
+            assert.match(obfuscatedCode, stringArrayRegExp);
         });
 
         it('match #1: should replace string with call to the string array calls wrapper', () => {
-            assert.match(obfuscatedCode,  stringArrayCallsWrapperRegExp);
+            assert.match(obfuscatedCode, stringArrayCallsWrapperRegExp);
         });
     });
 
@@ -149,11 +149,48 @@ describe('AstToEvalCallExpressionTransformer', () => {
         });
 
         it('should obfuscate eval string', () => {
-            assert.match(obfuscatedCode,  variableReferenceIdentifierRegExp);
+            assert.match(obfuscatedCode, variableReferenceIdentifierRegExp);
         });
 
         it('should correctly transform function parameter inside eval expression', () => {
             assert.equal(functionIdentifierName, variableReferenceIdentifierName);
         });
     });
+
+    describe('variant #6: integration with control flow flattening', () => {
+        const variableMatch: string = '_0x([a-f0-9]){4,6}';
+        const controlFlowStorageNodeMatch: string = `` +
+            `var *${variableMatch} *= *\\{` +
+                `'\\w{5}' *: *function *${variableMatch} *\\(${variableMatch}, *${variableMatch}\\) *\\{` +
+                    `return *${variableMatch} *\\+ *${variableMatch};` +
+                `\\}` +
+            `\\};` +
+        ``;
+        const controlFlowStorageNodeRegExp: RegExp = new RegExp(controlFlowStorageNodeMatch);
+        const evalExpressionRegExp: RegExp = /eval *\('_0x([a-f0-9]){4,6}\[\\'\w{5}\\']\(_0x([a-f0-9]){4,6}, *_0x([a-f0-9]){4,6}\);'\);/;
+
+        let obfuscatedCode: string;
+
+        before(() => {
+            const code: string = readFileAsString(__dirname + '/fixtures/control-flow-flattening-integration.js');
+            const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
+                code,
+                {
+                    ...NO_ADDITIONAL_NODES_PRESET,
+                    controlFlowFlattening: true,
+                    controlFlowFlatteningThreshold: 1
+                }
+            );
+
+            obfuscatedCode = obfuscationResult.getObfuscatedCode();
+        });
+
+        it('should add control flow storage node', () => {
+            assert.match(obfuscatedCode, controlFlowStorageNodeRegExp);
+        });
+
+        it('should obfuscate eval string', () => {
+            assert.match(obfuscatedCode, evalExpressionRegExp);
+        });
+    });
 });

+ 0 - 0
test/functional-tests/node-transformers/converting-transformers/ast-to-eval-call-expression-transformer/fixtures/call-expression-identifier-reference.js → test/functional-tests/node-transformers/finalizing-transformers/ast-to-eval-call-expression-transformer/fixtures/call-expression-identifier-reference.js


+ 5 - 0
test/functional-tests/node-transformers/finalizing-transformers/ast-to-eval-call-expression-transformer/fixtures/control-flow-flattening-integration.js

@@ -0,0 +1,5 @@
+(function(){
+    function foo (a, b) {
+        eval('a + b');
+    }
+})();

+ 0 - 0
test/functional-tests/node-transformers/converting-transformers/ast-to-eval-call-expression-transformer/fixtures/eval-expression-as-argument.js → test/functional-tests/node-transformers/finalizing-transformers/ast-to-eval-call-expression-transformer/fixtures/eval-expression-as-argument.js


+ 0 - 0
test/functional-tests/node-transformers/converting-transformers/ast-to-eval-call-expression-transformer/fixtures/identifier-reference.js → test/functional-tests/node-transformers/finalizing-transformers/ast-to-eval-call-expression-transformer/fixtures/identifier-reference.js


+ 0 - 0
test/functional-tests/node-transformers/converting-transformers/ast-to-eval-call-expression-transformer/fixtures/multiple-statements-eval.js → test/functional-tests/node-transformers/finalizing-transformers/ast-to-eval-call-expression-transformer/fixtures/multiple-statements-eval.js


+ 0 - 0
test/functional-tests/node-transformers/converting-transformers/ast-to-eval-call-expression-transformer/fixtures/string-array-calls-wrapper-call.js → test/functional-tests/node-transformers/finalizing-transformers/ast-to-eval-call-expression-transformer/fixtures/string-array-calls-wrapper-call.js


+ 1 - 1
test/index.spec.ts

@@ -51,12 +51,12 @@ import './functional-tests/node-transformers/control-flow-transformers/control-f
 import './functional-tests/node-transformers/control-flow-transformers/control-flow-replacers/call-expression-control-flow-replacer/CallExpressionControlFlowReplacer.spec';
 import './functional-tests/node-transformers/control-flow-transformers/control-flow-replacers/logical-expression-control-flow-replacer/LogicalExpressionControlFlowReplacer.spec';
 import './functional-tests/node-transformers/control-flow-transformers/control-flow-replacers/string-litertal-control-flow-replacer/StringLiteralControlFlowReplacer.spec';
-import './functional-tests/node-transformers/converting-transformers/ast-to-eval-call-expression-transformer/AstToEvalCallExpressionTransformer.spec';
 import './functional-tests/node-transformers/converting-transformers/member-expression-transformer/MemberExpressionTransformer.spec';
 import './functional-tests/node-transformers/converting-transformers/method-definition-transformer/MethodDefinitionTransformer.spec';
 import './functional-tests/node-transformers/converting-transformers/object-expression-keys-transformer/ObjectExpressionKeysTransformer.spec';
 import './functional-tests/node-transformers/converting-transformers/template-literal-transformer/TemplateLiteralTransformer.spec';
 import './functional-tests/node-transformers/dead-code-injection-transformers/DeadCodeInjectionTransformer.spec';
+import './functional-tests/node-transformers/finalizing-transformers/ast-to-eval-call-expression-transformer/AstToEvalCallExpressionTransformer.spec';
 import './functional-tests/node-transformers/obfuscating-transformers/catch-clause-transformer/CatchClauseTransformer.spec';
 import './functional-tests/node-transformers/obfuscating-transformers/class-declaration-transformer/ClassDeclarationTransformer.spec';
 import './functional-tests/node-transformers/obfuscating-transformers/function-declaration-transformer/FunctionDeclarationTransformer.spec';

Неке датотеке нису приказане због велике количине промена