Explorar o código

Added `target` option

sanex3339 %!s(int64=7) %!d(string=hai) anos
pai
achega
2fa1c95f5a
Modificáronse 65 ficheiros con 389 adicións e 221 borrados
  1. 1 0
      CHANGELOG.md
  2. 15 0
      README.md
  3. 0 0
      dist/index.js
  4. 1 1
      package.json
  5. 6 0
      src/cli/JavaScriptObfuscatorCLI.ts
  6. 21 0
      src/cli/sanitizers/ObfuscatingTargetSanitizer.ts
  7. 2 2
      src/cli/sanitizers/SourceMapModeSanitizer.ts
  8. 31 1
      src/custom-nodes/AbstractCustomNode.ts
  9. 10 9
      src/custom-nodes/console-output-nodes/ConsoleOutputDisableExpressionNode.ts
  10. 1 8
      src/custom-nodes/control-flow-flattening-nodes/BinaryExpressionFunctionNode.ts
  11. 1 8
      src/custom-nodes/control-flow-flattening-nodes/BlockStatementControlFlowFlatteningNode.ts
  12. 1 8
      src/custom-nodes/control-flow-flattening-nodes/CallExpressionFunctionNode.ts
  13. 1 8
      src/custom-nodes/control-flow-flattening-nodes/LogicalExpressionFunctionNode.ts
  14. 1 8
      src/custom-nodes/control-flow-flattening-nodes/StringLiteralNode.ts
  15. 1 8
      src/custom-nodes/control-flow-flattening-nodes/control-flow-storage-nodes/CallExpressionControlFlowStorageCallNode.ts
  16. 1 8
      src/custom-nodes/control-flow-flattening-nodes/control-flow-storage-nodes/ControlFlowStorageNode.ts
  17. 1 8
      src/custom-nodes/control-flow-flattening-nodes/control-flow-storage-nodes/ExpressionWithOperatorControlFlowStorageCallNode.ts
  18. 1 8
      src/custom-nodes/control-flow-flattening-nodes/control-flow-storage-nodes/StringLiteralControlFlowStorageCallNode.ts
  19. 5 2
      src/custom-nodes/debug-protection-nodes/DebugProtectionFunctionCallNode.ts
  20. 5 2
      src/custom-nodes/debug-protection-nodes/DebugProtectionFunctionIntervalNode.ts
  21. 14 2
      src/custom-nodes/debug-protection-nodes/DebugProtectionFunctionNode.ts
  22. 9 8
      src/custom-nodes/domain-lock-nodes/DomainLockNode.ts
  23. 5 2
      src/custom-nodes/node-calls-controller-nodes/NodeCallsControllerFunctionNode.ts
  24. 2 8
      src/custom-nodes/self-defending-nodes/SelfDefendingUnicodeNode.ts
  25. 19 9
      src/custom-nodes/string-array-nodes/StringArrayCallsWrapper.ts
  26. 5 2
      src/custom-nodes/string-array-nodes/StringArrayNode.ts
  27. 3 9
      src/custom-nodes/string-array-nodes/StringArrayRotateFunctionNode.ts
  28. 5 0
      src/enums/ObfuscationTarget.ts
  29. 5 2
      src/interfaces/options/IOptions.d.ts
  30. 14 6
      src/options/Options.ts
  31. 3 1
      src/options/normalizer-rules/StringArrayEncodingRule.ts
  32. 2 0
      src/options/presets/Default.ts
  33. 2 0
      src/options/presets/NoCustomNodes.ts
  34. 3 11
      src/templates/AtobTemplate.ts
  35. 14 0
      src/templates/GlobalVariableNoEvalTemplate.ts
  36. 16 0
      src/templates/GlobalVariableTemplate1.ts
  37. 19 0
      src/templates/GlobalVariableTemplate2.ts
  38. 0 0
      src/templates/Rc4Template.ts
  39. 0 0
      src/templates/SingleNodeCallControllerTemplate.ts
  40. 1 8
      src/templates/console-output-nodes/console-output-disable-expression-node/ConsoleOutputDisableExpressionTemplate.ts
  41. 0 31
      src/templates/custom-nodes/debug-protection-nodes/debug-protection-function-node/DebugProtectionFunctionTemplate.ts
  42. 0 0
      src/templates/debug-protection-nodes/debug-protection-function-call-node/DebufProtectionFunctionCallTemplate.ts
  43. 0 0
      src/templates/debug-protection-nodes/debug-protection-function-interval-node/DebugProtectionFunctionIntervalTemplate.ts
  44. 23 0
      src/templates/debug-protection-nodes/debug-protection-function-node/DebugProtectionFunctionTemplate.ts
  45. 17 0
      src/templates/debug-protection-nodes/debug-protection-function-node/DebuggerTemplate.ts
  46. 21 0
      src/templates/debug-protection-nodes/debug-protection-function-node/DebuggerTemplateNoEval.ts
  47. 2 11
      src/templates/domain-lock-nodes/domain-lock-node/DomainLockNodeTemplate.ts
  48. 1 1
      src/templates/self-defending-nodes/self-defending-unicode-node/SelfDefendingTemplate.ts
  49. 1 1
      src/templates/string-array-nodes/string-array-calls-wrapper/SelfDefendingTemplate.ts
  50. 0 0
      src/templates/string-array-nodes/string-array-calls-wrapper/StringArrayBase64DecodeNodeTemplate.ts
  51. 0 0
      src/templates/string-array-nodes/string-array-calls-wrapper/StringArrayCallsWrapperTemplate.ts
  52. 0 0
      src/templates/string-array-nodes/string-array-calls-wrapper/StringArrayRC4DecodeNodeTemplate.ts
  53. 0 0
      src/templates/string-array-nodes/string-array-node/StringArrayTemplate.ts
  54. 1 1
      src/templates/string-array-nodes/string-array-rotate-function-node/SelfDefendingTemplate.ts
  55. 0 0
      src/templates/string-array-nodes/string-array-rotate-function-node/StringArrayRotateFunctionTemplate.ts
  56. 3 1
      src/types/options/TStringArrayEncoding.d.ts
  57. 5 2
      test/functional-tests/javascript-obfuscator/JavaScriptObfuscator.spec.ts
  58. 4 2
      test/functional-tests/node-transformers/obfuscating-transformers/literal-transformer/LiteralTransformer.spec.ts
  59. 5 1
      test/functional-tests/templates/custom-nodes/domain-lock-nodes/DomainLockNodeTemplate.spec.ts
  60. 14 7
      test/functional-tests/templates/custom-nodes/string-array-nodes/StringArrayCallsWrapperNodeTemplate.spec.ts
  61. 1 0
      test/index.spec.ts
  62. 3 1
      test/runtime-tests/JavaScriptObfuscatorRuntime.spec.ts
  63. 36 0
      test/unit-tests/cli/sanitizers/ObfuscationTargetSanitizer.spec.ts
  64. 4 2
      test/unit-tests/options/OptionsNormalizer.spec.ts
  65. 1 3
      test/unit-tests/source-map/SourceMapCorrector.spec.ts

+ 1 - 0
CHANGELOG.md

@@ -2,6 +2,7 @@ Change Log
 ===
 v0.12.0
 ---
+* **New option:** `target` allows to set target environment for obfuscated code.
 * Added ability to disable and enable obfuscation for specific parts of the code by adding conditional comments. 
 * Added obfuscation of `es2015` class names.
 * CLI: added directory obfuscation.

+ 15 - 0
README.md

@@ -266,6 +266,7 @@ Following options are available for the JS Obfuscator:
     stringArray: true,
     stringArrayEncoding: false,
     stringArrayThreshold: 0.75,
+    target: 'browser',
     unicodeEscapeSequence: false
 }
 ```
@@ -301,6 +302,7 @@ Following options are available for the JS Obfuscator:
     --stringArray <boolean>
     --stringArrayEncoding <boolean|string> [true, false, base64, rc4]
     --stringArrayThreshold <number>
+    --target <string> [browser, extension, node]
     --unicodeEscapeSequence <boolean>
 ```
 
@@ -664,6 +666,19 @@ This setting is especially useful for large code size because it repeatedly call
 
 `stringArrayThreshold: 0` equals to `stringArray: false`.
 
+### `target`
+Type: `string` Default: `browser`
+
+Allows to set target environment for obfuscated code.
+
+Available values: 
+* `browser`;
+* `extension`;
+* `node`.
+
+Currently output code for `browser` and `node` targets is identical.
+Output code for `extension` target is not using `eval`.
+
 ### `unicodeEscapeSequence`
 Type: `boolean` Default: `false`
 

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
dist/index.js


+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "javascript-obfuscator",
-  "version": "0.12.0-dev.2",
+  "version": "0.12.0-beta.1",
   "description": "JavaScript obfuscator",
   "keywords": [
     "obfuscator",

+ 6 - 0
src/cli/JavaScriptObfuscatorCLI.ts

@@ -16,6 +16,7 @@ import { DEFAULT_PRESET } from '../options/presets/Default';
 
 import { ArraySanitizer } from './sanitizers/ArraySanitizer';
 import { BooleanSanitizer } from './sanitizers/BooleanSanitizer';
+import { ObfuscationTargetSanitizer } from './sanitizers/ObfuscatingTargetSanitizer';
 import { SourceMapModeSanitizer } from './sanitizers/SourceMapModeSanitizer';
 import { StringArrayEncodingSanitizer } from './sanitizers/StringArrayEncodingSanitizer';
 
@@ -301,6 +302,11 @@ export class JavaScriptObfuscatorCLI implements IInitializable {
                 'The probability that the literal string will be inserted into stringArray (Default: 0.8, Min: 0, Max: 1)',
                 parseFloat
             )
+            .option(
+                '--target <string>',
+                'Allows to set target environment for obfuscated code.',
+                ObfuscationTargetSanitizer
+            )
             .option(
                 '--unicodeEscapeSequence <boolean>',
                 'Allows to enable/disable string conversion to unicode escape sequence',

+ 21 - 0
src/cli/sanitizers/ObfuscatingTargetSanitizer.ts

@@ -0,0 +1,21 @@
+import { TCLISanitizer } from '../../types/cli/TCLISanitizer';
+
+import { ObfuscationTarget } from '../../enums/ObfuscationTarget';
+
+/**
+ * @param {string} value
+ * @returns {string}
+ */
+export const ObfuscationTargetSanitizer: TCLISanitizer = (value: string): string => {
+    const isCorrectTarget: boolean = Object
+        .keys(ObfuscationTarget)
+        .some((key: any): boolean => {
+            return ObfuscationTarget[key] === value;
+        });
+
+    if (!isCorrectTarget) {
+        throw new ReferenceError('Invalid value of `--target` option');
+    }
+
+    return value;
+};

+ 2 - 2
src/cli/sanitizers/SourceMapModeSanitizer.ts

@@ -7,13 +7,13 @@ import { SourceMapMode } from '../../enums/source-map/SourceMapMode';
  * @returns {string}
  */
 export const SourceMapModeSanitizer: TCLISanitizer = (value: string): string => {
-    const availableMode: boolean = Object
+    const isCorrectSourceMapMode: boolean = Object
         .keys(SourceMapMode)
         .some((key: any): boolean => {
             return SourceMapMode[key] === value;
         });
 
-    if (!availableMode) {
+    if (!isCorrectSourceMapMode) {
         throw new ReferenceError('Invalid value of `--sourceMapMode` option');
     }
 

+ 31 - 1
src/custom-nodes/AbstractCustomNode.ts

@@ -1,14 +1,27 @@
 import { injectable, inject } from 'inversify';
 import { ServiceIdentifiers } from '../container/ServiceIdentifiers';
 
+import { TStatement } from '../types/node/TStatement';
+
 import { ICustomNode } from '../interfaces/custom-nodes/ICustomNode';
 import { IOptions } from '../interfaces/options/IOptions';
-import { TStatement } from '../types/node/TStatement';
+import { IRandomGenerator } from '../interfaces/utils/IRandomGenerator';
+
+import { GlobalVariableTemplate1 } from '../templates/GlobalVariableTemplate1';
+import { GlobalVariableTemplate2 } from '../templates/GlobalVariableTemplate2';
 
 import { NodeUtils } from '../node/NodeUtils';
 
 @injectable()
 export abstract class AbstractCustomNode implements ICustomNode {
+    /**
+     * @type {string[]}
+     */
+    private static globalVariableTemplateFunctions: string[] = [
+        GlobalVariableTemplate1(),
+        GlobalVariableTemplate2()
+    ];
+
     /**
      * @type {string}
      */
@@ -25,11 +38,19 @@ export abstract class AbstractCustomNode implements ICustomNode {
     protected readonly options: IOptions;
 
     /**
+     * @type {IRandomGenerator}
+     */
+    protected readonly randomGenerator: IRandomGenerator;
+
+    /**
+     * @param {IRandomGenerator} randomGenerator
      * @param {IOptions} options
      */
     constructor (
+        @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
         @inject(ServiceIdentifiers.IOptions) options: IOptions
     ) {
+        this.randomGenerator = randomGenerator;
         this.options = options;
     }
 
@@ -60,6 +81,15 @@ export abstract class AbstractCustomNode implements ICustomNode {
         return this.cachedNode;
     }
 
+    /**
+     * @returns {string}
+     */
+    protected getGlobalVariableTemplate (): string {
+        return this.randomGenerator
+            .getRandomGenerator()
+            .pickone(AbstractCustomNode.globalVariableTemplateFunctions);
+    }
+
     /**
      * @returns {TStatement[]}
      */

+ 10 - 9
src/custom-nodes/console-output-nodes/ConsoleOutputDisableExpressionNode.ts

@@ -8,7 +8,10 @@ import { TStatement } from '../../types/node/TStatement';
 import { IOptions } from '../../interfaces/options/IOptions';
 import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
 
-import { ConsoleOutputDisableExpressionTemplate } from '../../templates/custom-nodes/console-output-nodes/console-output-disable-expression-node/ConsoleOutputDisableExpressionTemplate';
+import { ObfuscationTarget } from '../../enums/ObfuscationTarget';
+
+import { ConsoleOutputDisableExpressionTemplate } from '../../templates/console-output-nodes/console-output-disable-expression-node/ConsoleOutputDisableExpressionTemplate';
+import { GlobalVariableNoEvalTemplate } from '../../templates/GlobalVariableNoEvalTemplate';
 
 import { initializable } from '../../decorators/Initializable';
 
@@ -23,11 +26,6 @@ export class ConsoleOutputDisableExpressionNode extends AbstractCustomNode {
     @initializable()
     private callsControllerFunctionName: string;
 
-    /**
-     * @type {IRandomGenerator}
-     */
-    private readonly randomGenerator: IRandomGenerator;
-
     /**
      * @param {IRandomGenerator} randomGenerator
      * @param {IOptions} options
@@ -36,9 +34,7 @@ export class ConsoleOutputDisableExpressionNode extends AbstractCustomNode {
         @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
         @inject(ServiceIdentifiers.IOptions) options: IOptions
     ) {
-        super(options);
-
-        this.randomGenerator = randomGenerator;
+        super(randomGenerator, options);
     }
 
     /**
@@ -59,8 +55,13 @@ export class ConsoleOutputDisableExpressionNode extends AbstractCustomNode {
      * @returns {string}
      */
     protected getTemplate (): string {
+        const globalVariableTemplate: string = this.options.target !== ObfuscationTarget.Extension
+            ? this.getGlobalVariableTemplate()
+            : GlobalVariableNoEvalTemplate();
+
         return format(ConsoleOutputDisableExpressionTemplate(), {
             consoleLogDisableFunctionName: this.randomGenerator.getRandomVariableName(6),
+            globalVariableTemplate,
             singleNodeCallControllerFunctionName: this.callsControllerFunctionName
         });
     }

+ 1 - 8
src/custom-nodes/control-flow-flattening-nodes/BinaryExpressionFunctionNode.ts

@@ -22,11 +22,6 @@ export class BinaryExpressionFunctionNode extends AbstractCustomNode {
     @initializable()
     private operator: BinaryOperator;
 
-    /**
-     * @type {IRandomGenerator}
-     */
-    private readonly randomGenerator: IRandomGenerator;
-
     /**
      * @param {IRandomGenerator} randomGenerator
      * @param {IOptions} options
@@ -35,9 +30,7 @@ export class BinaryExpressionFunctionNode extends AbstractCustomNode {
         @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
         @inject(ServiceIdentifiers.IOptions) options: IOptions
     ) {
-        super(options);
-
-        this.randomGenerator = randomGenerator;
+        super(randomGenerator, options);
     }
 
     /**

+ 1 - 8
src/custom-nodes/control-flow-flattening-nodes/BlockStatementControlFlowFlatteningNode.ts

@@ -28,11 +28,6 @@ export class BlockStatementControlFlowFlatteningNode extends AbstractCustomNode
     @initializable()
     private originalKeysIndexesInShuffledArray: number[];
 
-    /**
-     * @type {IRandomGenerator}
-     */
-    private readonly randomGenerator: IRandomGenerator;
-
     /**
      * @type {number[]}
      */
@@ -47,9 +42,7 @@ export class BlockStatementControlFlowFlatteningNode extends AbstractCustomNode
         @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
         @inject(ServiceIdentifiers.IOptions) options: IOptions
     ) {
-        super(options);
-
-        this.randomGenerator = randomGenerator;
+        super(randomGenerator, options);
     }
 
     /**

+ 1 - 8
src/custom-nodes/control-flow-flattening-nodes/CallExpressionFunctionNode.ts

@@ -22,11 +22,6 @@ export class CallExpressionFunctionNode extends AbstractCustomNode {
     @initializable()
     private expressionArguments: (ESTree.Expression | ESTree.SpreadElement)[];
 
-    /**
-     * @type {IRandomGenerator}
-     */
-    private readonly randomGenerator: IRandomGenerator;
-
     /**
      * @param {IRandomGenerator} randomGenerator
      * @param {IOptions} options
@@ -35,9 +30,7 @@ export class CallExpressionFunctionNode extends AbstractCustomNode {
         @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
         @inject(ServiceIdentifiers.IOptions) options: IOptions
     ) {
-        super(options);
-
-        this.randomGenerator = randomGenerator;
+        super(randomGenerator, options);
     }
 
     /**

+ 1 - 8
src/custom-nodes/control-flow-flattening-nodes/LogicalExpressionFunctionNode.ts

@@ -22,11 +22,6 @@ export class LogicalExpressionFunctionNode extends AbstractCustomNode {
     @initializable()
     private operator: LogicalOperator;
 
-    /**
-     * @type {IRandomGenerator}
-     */
-    private readonly randomGenerator: IRandomGenerator;
-
     /**
      * @param {IRandomGenerator} randomGenerator
      * @param {IOptions} options
@@ -35,9 +30,7 @@ export class LogicalExpressionFunctionNode extends AbstractCustomNode {
         @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
         @inject(ServiceIdentifiers.IOptions) options: IOptions
     ) {
-        super(options);
-
-        this.randomGenerator = randomGenerator;
+        super(randomGenerator, options);
     }
 
     /**

+ 1 - 8
src/custom-nodes/control-flow-flattening-nodes/StringLiteralNode.ts

@@ -19,11 +19,6 @@ export class StringLiteralNode extends AbstractCustomNode {
     @initializable()
     private literalValue: string;
 
-    /**
-     * @type {IRandomGenerator}
-     */
-    private readonly randomGenerator: IRandomGenerator;
-
     /**
      * @param {IRandomGenerator} randomGenerator
      * @param {IOptions} options
@@ -32,9 +27,7 @@ export class StringLiteralNode extends AbstractCustomNode {
         @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
         @inject(ServiceIdentifiers.IOptions) options: IOptions
     ) {
-        super(options);
-
-        this.randomGenerator = randomGenerator;
+        super(randomGenerator, options);
     }
 
     /**

+ 1 - 8
src/custom-nodes/control-flow-flattening-nodes/control-flow-storage-nodes/CallExpressionControlFlowStorageCallNode.ts

@@ -41,11 +41,6 @@ export class CallExpressionControlFlowStorageCallNode extends AbstractCustomNode
     @initializable()
     private expressionArguments: (ESTree.Expression | ESTree.SpreadElement)[];
 
-    /**
-     * @type {IRandomGenerator}
-     */
-    private readonly randomGenerator: IRandomGenerator;
-
     /**
      * @param {IRandomGenerator} randomGenerator
      * @param {IOptions} options
@@ -54,9 +49,7 @@ export class CallExpressionControlFlowStorageCallNode extends AbstractCustomNode
         @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
         @inject(ServiceIdentifiers.IOptions) options: IOptions
     ) {
-        super(options);
-
-        this.randomGenerator = randomGenerator;
+        super(randomGenerator, options);
     }
 
     /**

+ 1 - 8
src/custom-nodes/control-flow-flattening-nodes/control-flow-storage-nodes/ControlFlowStorageNode.ts

@@ -24,11 +24,6 @@ export class ControlFlowStorageNode extends AbstractCustomNode {
     @initializable()
     private controlFlowStorage: IStorage <ICustomNode>;
 
-    /**
-     * @type {IRandomGenerator}
-     */
-    private readonly randomGenerator: IRandomGenerator;
-
     /**
      * @param {IRandomGenerator} randomGenerator
      * @param {IOptions} options
@@ -37,9 +32,7 @@ export class ControlFlowStorageNode extends AbstractCustomNode {
         @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
         @inject(ServiceIdentifiers.IOptions) options: IOptions
     ) {
-        super(options);
-
-        this.randomGenerator = randomGenerator;
+        super(randomGenerator, options);
     }
 
     /**

+ 1 - 8
src/custom-nodes/control-flow-flattening-nodes/control-flow-storage-nodes/ExpressionWithOperatorControlFlowStorageCallNode.ts

@@ -34,11 +34,6 @@ export class ExpressionWithOperatorControlFlowStorageCallNode extends AbstractCu
     @initializable()
     private leftValue: Expression;
 
-    /**
-     * @type {IRandomGenerator}
-     */
-    private readonly randomGenerator: IRandomGenerator;
-
     /**
      * @type {ESTree.Expression}
      */
@@ -53,9 +48,7 @@ export class ExpressionWithOperatorControlFlowStorageCallNode extends AbstractCu
         @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
         @inject(ServiceIdentifiers.IOptions) options: IOptions
     ) {
-        super(options);
-
-        this.randomGenerator = randomGenerator;
+        super(randomGenerator, options);
     }
 
     /**

+ 1 - 8
src/custom-nodes/control-flow-flattening-nodes/control-flow-storage-nodes/StringLiteralControlFlowStorageCallNode.ts

@@ -26,11 +26,6 @@ export class StringLiteralControlFlowStorageCallNode extends AbstractCustomNode
     @initializable()
     private controlFlowStorageName: string;
 
-    /**
-     * @type {IRandomGenerator}
-     */
-    private readonly randomGenerator: IRandomGenerator;
-
     /**
      * @param {IRandomGenerator} randomGenerator
      * @param {IOptions} options
@@ -39,9 +34,7 @@ export class StringLiteralControlFlowStorageCallNode extends AbstractCustomNode
         @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
         @inject(ServiceIdentifiers.IOptions) options: IOptions
     ) {
-        super(options);
-
-        this.randomGenerator = randomGenerator;
+        super(randomGenerator, options);
     }
 
     /**

+ 5 - 2
src/custom-nodes/debug-protection-nodes/DebugProtectionFunctionCallNode.ts

@@ -6,10 +6,11 @@ import * as format from 'string-template';
 import { TStatement } from '../../types/node/TStatement';
 
 import { IOptions } from '../../interfaces/options/IOptions';
+import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
 
 import { initializable } from '../../decorators/Initializable';
 
-import { DebugProtectionFunctionCallTemplate } from '../../templates/custom-nodes/debug-protection-nodes/debug-protection-function-call-node/DebufProtectionFunctionCallTemplate';
+import { DebugProtectionFunctionCallTemplate } from '../../templates/debug-protection-nodes/debug-protection-function-call-node/DebufProtectionFunctionCallTemplate';
 
 import { AbstractCustomNode } from '../AbstractCustomNode';
 import { NodeUtils } from '../../node/NodeUtils';
@@ -23,12 +24,14 @@ export class DebugProtectionFunctionCallNode extends AbstractCustomNode {
     private debugProtectionFunctionName: string;
 
     /**
+     * @param {IRandomGenerator} randomGenerator
      * @param {IOptions} options
      */
     constructor (
+        @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
         @inject(ServiceIdentifiers.IOptions) options: IOptions
     ) {
-        super(options);
+        super(randomGenerator, options);
     }
 
     /**

+ 5 - 2
src/custom-nodes/debug-protection-nodes/DebugProtectionFunctionIntervalNode.ts

@@ -6,10 +6,11 @@ import * as format from 'string-template';
 import { TStatement } from '../../types/node/TStatement';
 
 import { IOptions } from '../../interfaces/options/IOptions';
+import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
 
 import { initializable } from '../../decorators/Initializable';
 
-import { DebugProtectionFunctionIntervalTemplate } from '../../templates/custom-nodes/debug-protection-nodes/debug-protection-function-interval-node/DebugProtectionFunctionIntervalTemplate';
+import { DebugProtectionFunctionIntervalTemplate } from '../../templates/debug-protection-nodes/debug-protection-function-interval-node/DebugProtectionFunctionIntervalTemplate';
 
 import { AbstractCustomNode } from '../AbstractCustomNode';
 import { NodeUtils } from '../../node/NodeUtils';
@@ -23,12 +24,14 @@ export class DebugProtectionFunctionIntervalNode extends AbstractCustomNode {
     private debugProtectionFunctionName: string;
 
     /**
+     * @param {IRandomGenerator} randomGenerator
      * @param {IOptions} options
      */
     constructor (
+        @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
         @inject(ServiceIdentifiers.IOptions) options: IOptions
     ) {
-        super(options);
+        super(randomGenerator, options);
     }
 
     /**

+ 14 - 2
src/custom-nodes/debug-protection-nodes/DebugProtectionFunctionNode.ts

@@ -6,10 +6,15 @@ import * as format from 'string-template';
 import { TStatement } from '../../types/node/TStatement';
 
 import { IOptions } from '../../interfaces/options/IOptions';
+import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
+
+import { ObfuscationTarget } from '../../enums/ObfuscationTarget';
 
 import { initializable } from '../../decorators/Initializable';
 
-import { DebugProtectionFunctionTemplate } from '../../templates/custom-nodes/debug-protection-nodes/debug-protection-function-node/DebugProtectionFunctionTemplate';
+import { DebuggerTemplate } from '../../templates/debug-protection-nodes/debug-protection-function-node/DebuggerTemplate';
+import { DebuggerTemplateNoEval } from '../../templates/debug-protection-nodes/debug-protection-function-node/DebuggerTemplateNoEval';
+import { DebugProtectionFunctionTemplate } from '../../templates/debug-protection-nodes/debug-protection-function-node/DebugProtectionFunctionTemplate';
 
 import { AbstractCustomNode } from '../AbstractCustomNode';
 import { NodeUtils } from '../../node/NodeUtils';
@@ -23,12 +28,14 @@ export class DebugProtectionFunctionNode extends AbstractCustomNode {
     private debugProtectionFunctionName: string;
 
     /**
+     * @param {IRandomGenerator} randomGenerator
      * @param {IOptions} options
      */
     constructor (
+        @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
         @inject(ServiceIdentifiers.IOptions) options: IOptions
     ) {
-        super(options);
+        super(randomGenerator, options);
     }
 
     /**
@@ -49,7 +56,12 @@ export class DebugProtectionFunctionNode extends AbstractCustomNode {
      * @returns {string}
      */
     protected getTemplate (): string {
+        const debuggerTemplate: string = this.options.target !== ObfuscationTarget.Extension
+            ? DebuggerTemplate()
+            : DebuggerTemplateNoEval();
+
         return format(DebugProtectionFunctionTemplate(), {
+            debuggerTemplate,
             debugProtectionFunctionName: this.debugProtectionFunctionName
         });
     }

+ 9 - 8
src/custom-nodes/domain-lock-nodes/DomainLockNode.ts

@@ -9,9 +9,12 @@ import { ICryptUtils } from '../../interfaces/utils/ICryptUtils';
 import { IOptions } from '../../interfaces/options/IOptions';
 import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
 
+import { ObfuscationTarget } from '../../enums/ObfuscationTarget';
+
 import { initializable } from '../../decorators/Initializable';
 
-import { DomainLockNodeTemplate } from '../../templates/custom-nodes/domain-lock-nodes/domain-lock-node/DomainLockNodeTemplate';
+import { DomainLockNodeTemplate } from '../../templates/domain-lock-nodes/domain-lock-node/DomainLockNodeTemplate';
+import { GlobalVariableNoEvalTemplate } from '../../templates/GlobalVariableNoEvalTemplate';
 
 import { AbstractCustomNode } from '../AbstractCustomNode';
 import { NodeUtils } from '../../node/NodeUtils';
@@ -29,11 +32,6 @@ export class DomainLockNode extends AbstractCustomNode {
      */
     private readonly cryptUtils: ICryptUtils;
 
-    /**
-     * @type {IRandomGenerator}
-     */
-    private readonly randomGenerator: IRandomGenerator;
-
     /**
      * @param {IRandomGenerator} randomGenerator
      * @param {ICryptUtils} cryptUtils
@@ -44,9 +42,8 @@ export class DomainLockNode extends AbstractCustomNode {
         @inject(ServiceIdentifiers.ICryptUtils) cryptUtils: ICryptUtils,
         @inject(ServiceIdentifiers.IOptions) options: IOptions
     ) {
-        super(options);
+        super(randomGenerator, options);
 
-        this.randomGenerator = randomGenerator;
         this.cryptUtils = cryptUtils;
     }
 
@@ -73,11 +70,15 @@ export class DomainLockNode extends AbstractCustomNode {
             domainsString,
             domainsString.length * 3
         );
+        const globalVariableTemplate: string = this.options.target !== ObfuscationTarget.Extension
+            ? this.getGlobalVariableTemplate()
+            : GlobalVariableNoEvalTemplate();
 
         return format(DomainLockNodeTemplate(), {
             domainLockFunctionName: this.randomGenerator.getRandomVariableName(6),
             diff: diff,
             domains: hiddenDomainsString,
+            globalVariableTemplate,
             singleNodeCallControllerFunctionName: this.callsControllerFunctionName
         });
     }

+ 5 - 2
src/custom-nodes/node-calls-controller-nodes/NodeCallsControllerFunctionNode.ts

@@ -6,12 +6,13 @@ import * as format from 'string-template';
 import { TStatement } from '../../types/node/TStatement';
 
 import { IOptions } from '../../interfaces/options/IOptions';
+import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
 
 import { ObfuscationEvent } from '../../enums/event-emitters/ObfuscationEvent';
 
 import { initializable } from '../../decorators/Initializable';
 
-import { SingleNodeCallControllerTemplate } from '../../templates/custom-nodes/SingleNodeCallControllerTemplate';
+import { SingleNodeCallControllerTemplate } from '../../templates/SingleNodeCallControllerTemplate';
 
 import { NO_CUSTOM_NODES_PRESET } from '../../options/presets/NoCustomNodes';
 
@@ -34,12 +35,14 @@ export class NodeCallsControllerFunctionNode extends AbstractCustomNode {
     private appendEvent: ObfuscationEvent;
 
     /**
+     * @param {IRandomGenerator} randomGenerator
      * @param {IOptions} options
      */
     constructor (
+        @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
         @inject(ServiceIdentifiers.IOptions) options: IOptions
     ) {
-        super(options);
+        super(randomGenerator, options);
     }
 
     /**

+ 2 - 8
src/custom-nodes/self-defending-nodes/SelfDefendingUnicodeNode.ts

@@ -13,7 +13,7 @@ import { initializable } from '../../decorators/Initializable';
 
 import { NO_CUSTOM_NODES_PRESET } from '../../options/presets/NoCustomNodes';
 
-import { SelfDefendingTemplate } from '../../templates/custom-nodes/self-defending-nodes/self-defending-unicode-node/SelfDefendingTemplate';
+import { SelfDefendingTemplate } from '../../templates/self-defending-nodes/self-defending-unicode-node/SelfDefendingTemplate';
 
 import { AbstractCustomNode } from '../AbstractCustomNode';
 import { JavaScriptObfuscator } from '../../JavaScriptObfuscatorFacade';
@@ -32,11 +32,6 @@ export class SelfDefendingUnicodeNode extends AbstractCustomNode {
     @initializable()
     private callsControllerFunctionName: string;
 
-    /**
-     * @type {IRandomGenerator}
-     */
-    private readonly randomGenerator: IRandomGenerator;
-
     /**
      * @param {IRandomGenerator} randomGenerator
      * @param {IEscapeSequenceEncoder} escapeSequenceEncoder
@@ -47,9 +42,8 @@ export class SelfDefendingUnicodeNode extends AbstractCustomNode {
         @inject(ServiceIdentifiers.IEscapeSequenceEncoder) escapeSequenceEncoder: IEscapeSequenceEncoder,
         @inject(ServiceIdentifiers.IOptions) options: IOptions
     ) {
-        super(options);
+        super(randomGenerator, options);
 
-        this.randomGenerator = randomGenerator;
         this.escapeSequenceEncoder = escapeSequenceEncoder;
     }
 

+ 19 - 9
src/custom-nodes/string-array-nodes/StringArrayCallsWrapper.ts

@@ -7,20 +7,23 @@ import { TStatement } from '../../types/node/TStatement';
 
 import { IEscapeSequenceEncoder } from '../../interfaces/utils/IEscapeSequenceEncoder';
 import { IOptions } from '../../interfaces/options/IOptions';
+import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
 import { IStorage } from '../../interfaces/storages/IStorage';
 
+import { ObfuscationTarget } from '../../enums/ObfuscationTarget';
 import { StringArrayEncoding } from '../../enums/StringArrayEncoding';
 
 import { initializable } from '../../decorators/Initializable';
 
 import { NO_CUSTOM_NODES_PRESET } from '../../options/presets/NoCustomNodes';
 
-import { AtobTemplate } from '../../templates/custom-nodes/AtobTemplate';
-import { Rc4Template } from '../../templates/custom-nodes/Rc4Template';
-import { SelfDefendingTemplate } from '../../templates/custom-nodes/string-array-nodes/string-array-calls-wrapper/SelfDefendingTemplate';
-import { StringArrayBase64DecodeNodeTemplate } from '../../templates/custom-nodes/string-array-nodes/string-array-calls-wrapper/StringArrayBase64DecodeNodeTemplate';
-import { StringArrayCallsWrapperTemplate } from '../../templates/custom-nodes/string-array-nodes/string-array-calls-wrapper/StringArrayCallsWrapperTemplate';
-import { StringArrayRc4DecodeNodeTemplate } from '../../templates/custom-nodes/string-array-nodes/string-array-calls-wrapper/StringArrayRC4DecodeNodeTemplate';
+import { AtobTemplate } from '../../templates/AtobTemplate';
+import { GlobalVariableNoEvalTemplate } from '../../templates/GlobalVariableNoEvalTemplate';
+import { Rc4Template } from '../../templates/Rc4Template';
+import { SelfDefendingTemplate } from '../../templates/string-array-nodes/string-array-calls-wrapper/SelfDefendingTemplate';
+import { StringArrayBase64DecodeNodeTemplate } from '../../templates/string-array-nodes/string-array-calls-wrapper/StringArrayBase64DecodeNodeTemplate';
+import { StringArrayCallsWrapperTemplate } from '../../templates/string-array-nodes/string-array-calls-wrapper/StringArrayCallsWrapperTemplate';
+import { StringArrayRc4DecodeNodeTemplate } from '../../templates/string-array-nodes/string-array-calls-wrapper/StringArrayRC4DecodeNodeTemplate';
 
 import { AbstractCustomNode } from '../AbstractCustomNode';
 import { JavaScriptObfuscator } from '../../JavaScriptObfuscatorFacade';
@@ -52,14 +55,16 @@ export class StringArrayCallsWrapper extends AbstractCustomNode {
     private stringArrayCallsWrapperName: string;
 
     /**
+     * @param {IRandomGenerator} randomGenerator
      * @param {IEscapeSequenceEncoder} escapeSequenceEncoder
      * @param {IOptions} options
      */
     constructor (
+        @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
         @inject(ServiceIdentifiers.IEscapeSequenceEncoder) escapeSequenceEncoder: IEscapeSequenceEncoder,
         @inject(ServiceIdentifiers.IOptions) options: IOptions
     ) {
-        super(options);
+        super(randomGenerator, options);
 
         this.escapeSequenceEncoder = escapeSequenceEncoder;
     }
@@ -109,6 +114,11 @@ export class StringArrayCallsWrapper extends AbstractCustomNode {
      * @returns {string}
      */
     private getDecodeStringArrayTemplate (): string {
+        const globalVariableTemplate: string = this.options.target !== ObfuscationTarget.Extension
+            ? this.getGlobalVariableTemplate()
+            : GlobalVariableNoEvalTemplate();
+        const atobPolyfill: string = format(AtobTemplate(), { globalVariableTemplate });
+
         let decodeStringArrayTemplate: string = '',
             selfDefendingCode: string = '';
 
@@ -122,7 +132,7 @@ export class StringArrayCallsWrapper extends AbstractCustomNode {
         switch (this.options.stringArrayEncoding) {
             case StringArrayEncoding.Rc4:
                 decodeStringArrayTemplate = format(StringArrayRc4DecodeNodeTemplate(), {
-                    atobPolyfill: AtobTemplate(),
+                    atobPolyfill,
                     rc4Polyfill: Rc4Template(),
                     selfDefendingCode,
                     stringArrayCallsWrapperName: this.stringArrayCallsWrapperName
@@ -132,7 +142,7 @@ export class StringArrayCallsWrapper extends AbstractCustomNode {
 
             case StringArrayEncoding.Base64:
                 decodeStringArrayTemplate = format(StringArrayBase64DecodeNodeTemplate(), {
-                    atobPolyfill: AtobTemplate(),
+                    atobPolyfill,
                     selfDefendingCode,
                     stringArrayCallsWrapperName: this.stringArrayCallsWrapperName
                 });

+ 5 - 2
src/custom-nodes/string-array-nodes/StringArrayNode.ts

@@ -6,11 +6,12 @@ import * as format from 'string-template';
 import { TStatement } from '../../types/node/TStatement';
 
 import { IOptions } from '../../interfaces/options/IOptions';
+import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
 import { IStorage } from '../../interfaces/storages/IStorage';
 
 import { initializable } from '../../decorators/Initializable';
 
-import { StringArrayTemplate } from '../../templates/custom-nodes/string-array-nodes/string-array-node/StringArrayTemplate';
+import { StringArrayTemplate } from '../../templates/string-array-nodes/string-array-node/StringArrayTemplate';
 
 import { AbstractCustomNode } from '../AbstractCustomNode';
 import { NodeUtils } from '../../node/NodeUtils';
@@ -37,12 +38,14 @@ export class StringArrayNode extends AbstractCustomNode {
     private stringArrayRotateValue: number;
 
     /**
+     * @param {IRandomGenerator} randomGenerator
      * @param {IOptions} options
      */
     constructor (
+        @inject(ServiceIdentifiers.IRandomGenerator) randomGenerator: IRandomGenerator,
         @inject(ServiceIdentifiers.IOptions) options: IOptions
     ) {
-        super(options);
+        super(randomGenerator, options);
     }
 
     /**

+ 3 - 9
src/custom-nodes/string-array-nodes/StringArrayRotateFunctionNode.ts

@@ -14,8 +14,8 @@ import { initializable } from '../../decorators/Initializable';
 
 import { NO_CUSTOM_NODES_PRESET } from '../../options/presets/NoCustomNodes';
 
-import { SelfDefendingTemplate } from '../../templates/custom-nodes/string-array-nodes/string-array-rotate-function-node/SelfDefendingTemplate';
-import { StringArrayRotateFunctionTemplate } from '../../templates/custom-nodes/string-array-nodes/string-array-rotate-function-node/StringArrayRotateFunctionTemplate';
+import { SelfDefendingTemplate } from '../../templates/string-array-nodes/string-array-rotate-function-node/SelfDefendingTemplate';
+import { StringArrayRotateFunctionTemplate } from '../../templates/string-array-nodes/string-array-rotate-function-node/StringArrayRotateFunctionTemplate';
 
 import { AbstractCustomNode } from '../AbstractCustomNode';
 import { JavaScriptObfuscator } from '../../JavaScriptObfuscatorFacade';
@@ -29,11 +29,6 @@ export class StringArrayRotateFunctionNode extends AbstractCustomNode {
      */
     private readonly escapeSequenceEncoder: IEscapeSequenceEncoder;
 
-    /**
-     * @type {IRandomGenerator}
-     */
-    private readonly randomGenerator: IRandomGenerator;
-
     /**
      * @type {IStorage <string>}
      */
@@ -62,9 +57,8 @@ export class StringArrayRotateFunctionNode extends AbstractCustomNode {
         @inject(ServiceIdentifiers.IEscapeSequenceEncoder) escapeSequenceEncoder: IEscapeSequenceEncoder,
         @inject(ServiceIdentifiers.IOptions) options: IOptions
     ) {
-        super(options);
+        super(randomGenerator, options);
 
-        this.randomGenerator = randomGenerator;
         this.escapeSequenceEncoder = escapeSequenceEncoder;
     }
 

+ 5 - 0
src/enums/ObfuscationTarget.ts

@@ -0,0 +1,5 @@
+export enum ObfuscationTarget {
+    Browser = 'browser',
+    Extension = 'extension',
+    Node = 'node'
+}

+ 5 - 2
src/interfaces/options/IOptions.d.ts

@@ -1,6 +1,8 @@
-import { TSourceMapMode } from '../../types/source-map/TSourceMapMode';
 import { TStringArrayEncoding } from '../../types/options/TStringArrayEncoding';
 
+import { ObfuscationTarget } from '../../enums/ObfuscationTarget';
+import { SourceMapMode } from '../../enums/source-map/SourceMapMode';
+
 export interface IOptions {
     readonly compact: boolean;
     readonly controlFlowFlattening: boolean;
@@ -21,9 +23,10 @@ export interface IOptions {
     readonly sourceMap: boolean;
     readonly sourceMapBaseUrl: string;
     readonly sourceMapFileName: string;
-    readonly sourceMapMode: TSourceMapMode;
+    readonly sourceMapMode: SourceMapMode;
     readonly stringArray: boolean;
     readonly stringArrayEncoding: TStringArrayEncoding;
     readonly stringArrayThreshold: number;
+    readonly target: ObfuscationTarget;
     readonly unicodeEscapeSequence: boolean;
 }

+ 14 - 6
src/options/Options.ts

@@ -17,11 +17,13 @@ import {
 } from 'class-validator';
 
 import { TInputOptions } from '../types/options/TInputOptions';
+import { TStringArrayEncoding } from '../types/options/TStringArrayEncoding';
 
 import { IOptions } from '../interfaces/options/IOptions';
 
-import { TSourceMapMode } from '../types/source-map/TSourceMapMode';
-import { TStringArrayEncoding } from '../types/options/TStringArrayEncoding';
+import { ObfuscationTarget } from '../enums/ObfuscationTarget';
+import { SourceMapMode } from '../enums/source-map/SourceMapMode';
+import { StringArrayEncoding } from '../enums/StringArrayEncoding';
 
 import { DEFAULT_PRESET } from './presets/Default';
 
@@ -169,10 +171,10 @@ export class Options implements IOptions {
     public readonly sourceMapFileName: string;
 
     /**
-     * @type {TSourceMapMode}
+     * @type {SourceMapMode}
      */
-    @IsIn(['inline', 'separate'])
-    public readonly sourceMapMode: TSourceMapMode;
+    @IsIn([SourceMapMode.Inline, SourceMapMode.Separate])
+    public readonly sourceMapMode: SourceMapMode;
 
     /**
      * @type {boolean}
@@ -183,7 +185,7 @@ export class Options implements IOptions {
     /**
      * @type {TStringArrayEncoding}
      */
-    @IsIn([true, false, 'base64', 'rc4'])
+    @IsIn([true, false, StringArrayEncoding.Base64, StringArrayEncoding.Rc4])
     public readonly stringArrayEncoding: TStringArrayEncoding;
 
     /**
@@ -194,6 +196,12 @@ export class Options implements IOptions {
     @Max(1)
     public readonly stringArrayThreshold: number;
 
+    /**
+     * @type {ObfuscationTarget}
+     */
+    @IsIn([ObfuscationTarget.Browser, ObfuscationTarget.Extension, ObfuscationTarget.Node])
+    public readonly target: ObfuscationTarget;
+
     /**
      * @type {boolean}
      */

+ 3 - 1
src/options/normalizer-rules/StringArrayEncodingRule.ts

@@ -2,6 +2,8 @@ import { TOptionsNormalizerRule } from '../../types/options/TOptionsNormalizerRu
 
 import { IOptions } from '../../interfaces/options/IOptions';
 
+import { StringArrayEncoding } from '../../enums/StringArrayEncoding';
+
 /**
  * @param {IOptions} options
  * @returns {IOptions}
@@ -10,7 +12,7 @@ export const StringArrayEncodingRule: TOptionsNormalizerRule = (options: IOption
     if (options.stringArrayEncoding === true) {
         options = {
             ...options,
-            stringArrayEncoding: 'base64'
+            stringArrayEncoding: StringArrayEncoding.Base64
         };
     }
 

+ 2 - 0
src/options/presets/Default.ts

@@ -1,5 +1,6 @@
 import { TInputOptions } from '../../types/options/TInputOptions';
 
+import { ObfuscationTarget } from '../../enums/ObfuscationTarget';
 import { SourceMapMode } from '../../enums/source-map/SourceMapMode';
 
 export const DEFAULT_PRESET: TInputOptions = Object.freeze({
@@ -27,5 +28,6 @@ export const DEFAULT_PRESET: TInputOptions = Object.freeze({
     stringArray: true,
     stringArrayEncoding: false,
     stringArrayThreshold: 0.75,
+    target: ObfuscationTarget.Browser,
     unicodeEscapeSequence: false
 });

+ 2 - 0
src/options/presets/NoCustomNodes.ts

@@ -1,5 +1,6 @@
 import { TInputOptions } from '../../types/options/TInputOptions';
 
+import { ObfuscationTarget } from '../../enums/ObfuscationTarget';
 import { SourceMapMode } from '../../enums/source-map/SourceMapMode';
 
 export const NO_CUSTOM_NODES_PRESET: TInputOptions = Object.freeze({
@@ -26,5 +27,6 @@ export const NO_CUSTOM_NODES_PRESET: TInputOptions = Object.freeze({
     stringArray: false,
     stringArrayEncoding: false,
     stringArrayThreshold: 0,
+    target: ObfuscationTarget.Browser,
     unicodeEscapeSequence: false
 });

+ 3 - 11
src/templates/custom-nodes/AtobTemplate.ts → src/templates/AtobTemplate.ts

@@ -4,20 +4,12 @@
 export function AtobTemplate (): string {
     return `
         (function () {
-            var object;
-            
-            try { 
-                var getGlobal = Function('return (function() ' + '{}.constructor("return this")( )' + ');');
-                
-                object = getGlobal(); 
-            } catch (e) { 
-                object = window; 
-            }
+            {globalVariableTemplate}
             
             var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
 
-            object.atob || (
-                object.atob = function(input) {
+            that.atob || (
+                that.atob = function(input) {
                     var str = String(input).replace(/=+$/, '');
                     for (
                         var bc = 0, bs, buffer, idx = 0, output = '';

+ 14 - 0
src/templates/GlobalVariableNoEvalTemplate.ts

@@ -0,0 +1,14 @@
+/**
+ * @returns {string}
+ */
+export function GlobalVariableNoEvalTemplate (): string {
+    return `
+        var that = (typeof window !== 'undefined'
+           ? window
+           : (typeof process === 'object' &&
+              typeof require === 'function' &&
+              typeof global === 'object')
+             ? global
+             : this);
+    `;
+}

+ 16 - 0
src/templates/GlobalVariableTemplate1.ts

@@ -0,0 +1,16 @@
+/**
+ * @returns {string}
+ */
+export function GlobalVariableTemplate1 (): string {
+    return `
+        var that;
+        
+        try { 
+            var getGlobal = Function('return (function() ' + '{}.constructor("return this")( )' + ');');
+            
+            that = getGlobal(); 
+        } catch (e) { 
+            that = window; 
+        }
+    `;
+}

+ 19 - 0
src/templates/GlobalVariableTemplate2.ts

@@ -0,0 +1,19 @@
+/**
+ * @returns {string}
+ */
+export function GlobalVariableTemplate2 (): string {
+    return `
+        var getGlobal = function () {
+            var globalObject;
+        
+            try {                     
+                globalObject = Function('return (function() ' + '{}.constructor("return this")( )' + ');')(); 
+            } catch (e) { 
+                globalObject = window; 
+            }
+            
+            return globalObject;
+        };
+        var that = getGlobal();
+    `;
+}

+ 0 - 0
src/templates/custom-nodes/Rc4Template.ts → src/templates/Rc4Template.ts


+ 0 - 0
src/templates/custom-nodes/SingleNodeCallControllerTemplate.ts → src/templates/SingleNodeCallControllerTemplate.ts


+ 1 - 8
src/templates/custom-nodes/console-output-nodes/console-output-disable-expression-node/ConsoleOutputDisableExpressionTemplate.ts → src/templates/console-output-nodes/console-output-disable-expression-node/ConsoleOutputDisableExpressionTemplate.ts

@@ -5,15 +5,8 @@ export function ConsoleOutputDisableExpressionTemplate (): string {
     return `
         var {consoleLogDisableFunctionName} = {singleNodeCallControllerFunctionName}(this, function () {            
             var func = function () {};
-            var that;
             
-            try { 
-                var getGlobal = Function('return (function() ' + '{}.constructor("return this")( )' + ');');
-                
-                that = getGlobal(); 
-            } catch (e) { 
-                that = window; 
-            }
+            {globalVariableTemplate}
                         
             if (!that.console) {
                 that.console = (function (func){ 

+ 0 - 31
src/templates/custom-nodes/debug-protection-nodes/debug-protection-function-node/DebugProtectionFunctionTemplate.ts

@@ -1,31 +0,0 @@
-/**
- * @returns {string}
- */
-export function DebugProtectionFunctionTemplate (): string {
-    return `     
-        function {debugProtectionFunctionName} (ret) {
-            function debuggerProtection (counter) {
-                if (typeof counter === 'string') {
-                    return (function (arg) {}.constructor('while (true) {}').apply('counter'));
-                } else {
-                    if (('' + counter / counter)['length'] !== 1 || counter % 20 === 0) {
-                        (function () {return true;}.constructor('debu' + 'gger').call('action'));
-                    } else {
-                        (function () {return false;}.constructor('debu' + 'gger').apply('stateObject'));
-                    }
-                    
-                }
-                
-                debuggerProtection(++counter);
-            }
-            
-            try {
-                if (ret) {
-                    return debuggerProtection;
-                } else {
-                    debuggerProtection(0);
-                }
-            } catch (y) {}
-        }
-    `;
-}

+ 0 - 0
src/templates/custom-nodes/debug-protection-nodes/debug-protection-function-call-node/DebufProtectionFunctionCallTemplate.ts → src/templates/debug-protection-nodes/debug-protection-function-call-node/DebufProtectionFunctionCallTemplate.ts


+ 0 - 0
src/templates/custom-nodes/debug-protection-nodes/debug-protection-function-interval-node/DebugProtectionFunctionIntervalTemplate.ts → src/templates/debug-protection-nodes/debug-protection-function-interval-node/DebugProtectionFunctionIntervalTemplate.ts


+ 23 - 0
src/templates/debug-protection-nodes/debug-protection-function-node/DebugProtectionFunctionTemplate.ts

@@ -0,0 +1,23 @@
+/**
+ * @returns {string}
+ */
+export function DebugProtectionFunctionTemplate (): string {
+    return `     
+        function {debugProtectionFunctionName} (ret) {
+            function debuggerProtection (counter) {
+            
+                {debuggerTemplate}
+                
+                debuggerProtection(++counter);
+            }
+            
+            try {
+                if (ret) {
+                    return debuggerProtection;
+                } else {
+                    debuggerProtection(0);
+                }
+            } catch (y) {}
+        }
+    `;
+}

+ 17 - 0
src/templates/debug-protection-nodes/debug-protection-function-node/DebuggerTemplate.ts

@@ -0,0 +1,17 @@
+/**
+ * @returns {string}
+ */
+export function DebuggerTemplate (): string {
+    return `     
+        if (typeof counter === 'string') {
+            return (function (arg) {}.constructor('while (true) {}').apply('counter'));
+        } else {
+            if (('' + counter / counter)['length'] !== 1 || counter % 20 === 0) {
+                (function () {return true;}.constructor('debu' + 'gger').call('action'));
+            } else {
+                (function () {return false;}.constructor('debu' + 'gger').apply('stateObject'));
+            }
+            
+        }
+    `;
+}

+ 21 - 0
src/templates/debug-protection-nodes/debug-protection-function-node/DebuggerTemplateNoEval.ts

@@ -0,0 +1,21 @@
+/**
+ * @returns {string}
+ */
+export function DebuggerTemplateNoEval (): string {
+    return `     
+        if (typeof counter === 'string') {
+            var func = function () {
+                while (true) {}
+            };
+            
+            return func();
+        } else {
+            if (('' + counter / counter)['length'] !== 1 || counter % 20 === 0) {
+                debugger;
+            } else {
+                debugger;
+            }
+            
+        }
+    `;
+}

+ 2 - 11
src/templates/custom-nodes/domain-lock-nodes/domain-lock-node/DomainLockNodeTemplate.ts → src/templates/domain-lock-nodes/domain-lock-node/DomainLockNodeTemplate.ts

@@ -4,18 +4,9 @@
 export function DomainLockNodeTemplate (): string {
     return `
         var {domainLockFunctionName} = {singleNodeCallControllerFunctionName}(this, function () {
-            var getGlobal = function () {
-                var globalObject;
             
-                try {                     
-                    globalObject = Function('return (function() ' + '{}.constructor("return this")( )' + ');')(); 
-                } catch (e) { 
-                    globalObject = window; 
-                }
-                
-                return globalObject;
-            };
-            var that = getGlobal();
+            {globalVariableTemplate}
+            
             var func = function () { 
                 return {
                     key: 'item',

+ 1 - 1
src/templates/custom-nodes/self-defending-nodes/self-defending-unicode-node/SelfDefendingTemplate.ts → src/templates/self-defending-nodes/self-defending-unicode-node/SelfDefendingTemplate.ts

@@ -1,4 +1,4 @@
-import { IEscapeSequenceEncoder } from '../../../../interfaces/utils/IEscapeSequenceEncoder';
+import { IEscapeSequenceEncoder } from '../../../interfaces/utils/IEscapeSequenceEncoder';
 
 /**
  * SelfDefendingTemplate. Enters code in infinity loop.

+ 1 - 1
src/templates/custom-nodes/string-array-nodes/string-array-calls-wrapper/SelfDefendingTemplate.ts → src/templates/string-array-nodes/string-array-calls-wrapper/SelfDefendingTemplate.ts

@@ -1,4 +1,4 @@
-import { IEscapeSequenceEncoder } from '../../../../interfaces/utils/IEscapeSequenceEncoder';
+import { IEscapeSequenceEncoder } from '../../../interfaces/utils/IEscapeSequenceEncoder';
 
 /**
  * @param {IEscapeSequenceEncoder} escapeSequenceEncoder

+ 0 - 0
src/templates/custom-nodes/string-array-nodes/string-array-calls-wrapper/StringArrayBase64DecodeNodeTemplate.ts → src/templates/string-array-nodes/string-array-calls-wrapper/StringArrayBase64DecodeNodeTemplate.ts


+ 0 - 0
src/templates/custom-nodes/string-array-nodes/string-array-calls-wrapper/StringArrayCallsWrapperTemplate.ts → src/templates/string-array-nodes/string-array-calls-wrapper/StringArrayCallsWrapperTemplate.ts


+ 0 - 0
src/templates/custom-nodes/string-array-nodes/string-array-calls-wrapper/StringArrayRC4DecodeNodeTemplate.ts → src/templates/string-array-nodes/string-array-calls-wrapper/StringArrayRC4DecodeNodeTemplate.ts


+ 0 - 0
src/templates/custom-nodes/string-array-nodes/string-array-node/StringArrayTemplate.ts → src/templates/string-array-nodes/string-array-node/StringArrayTemplate.ts


+ 1 - 1
src/templates/custom-nodes/string-array-nodes/string-array-rotate-function-node/SelfDefendingTemplate.ts → src/templates/string-array-nodes/string-array-rotate-function-node/SelfDefendingTemplate.ts

@@ -1,4 +1,4 @@
-import { IEscapeSequenceEncoder } from '../../../../interfaces/utils/IEscapeSequenceEncoder';
+import { IEscapeSequenceEncoder } from '../../../interfaces/utils/IEscapeSequenceEncoder';
 
 /**
  * SelfDefendingTemplate. Enter code in infinity loop.

+ 0 - 0
src/templates/custom-nodes/string-array-nodes/string-array-rotate-function-node/StringArrayRotateFunctionTemplate.ts → src/templates/string-array-nodes/string-array-rotate-function-node/StringArrayRotateFunctionTemplate.ts


+ 3 - 1
src/types/options/TStringArrayEncoding.d.ts

@@ -1 +1,3 @@
-export type TStringArrayEncoding = boolean | 'base64' | 'rc4';
+import { StringArrayEncoding } from '../../enums/StringArrayEncoding';
+
+export type TStringArrayEncoding = boolean | StringArrayEncoding;

+ 5 - 2
test/functional-tests/javascript-obfuscator/JavaScriptObfuscator.spec.ts

@@ -2,6 +2,9 @@ import { assert } from 'chai';
 
 import { IObfuscationResult } from '../../../src/interfaces/IObfuscationResult';
 
+import { SourceMapMode } from '../../../src/enums/source-map/SourceMapMode';
+import { StringArrayEncoding } from '../../../src/enums/StringArrayEncoding';
+
 import { JavaScriptObfuscator } from '../../../src/JavaScriptObfuscatorFacade';
 
 import { NO_CUSTOM_NODES_PRESET } from '../../../src/options/presets/NoCustomNodes';
@@ -113,7 +116,7 @@ describe('JavaScriptObfuscator', () => {
                         {
                             ...NO_CUSTOM_NODES_PRESET,
                             sourceMap: true,
-                            sourceMapMode: 'inline'
+                            sourceMapMode: SourceMapMode.Inline
                         }
                     );
 
@@ -483,7 +486,7 @@ describe('JavaScriptObfuscator', () => {
                         disableConsoleOutput: false,
                         rotateStringArray: true,
                         stringArray: true,
-                        stringArrayEncoding: 'rc4',
+                        stringArrayEncoding: StringArrayEncoding.Rc4,
                         stringArrayThreshold: 1,
                         unicodeEscapeSequence: false
                     }

+ 4 - 2
test/functional-tests/node-transformers/obfuscating-transformers/literal-transformer/LiteralTransformer.spec.ts

@@ -2,6 +2,8 @@ import { assert } from 'chai';
 
 import { IObfuscationResult } from '../../../../../src/interfaces/IObfuscationResult';
 
+import { StringArrayEncoding } from '../../../../../src/enums/StringArrayEncoding';
+
 import { NO_CUSTOM_NODES_PRESET } from '../../../../../src/options/presets/NoCustomNodes';
 
 import { readFileAsString } from '../../../../helpers/readFileAsString';
@@ -202,7 +204,7 @@ describe('LiteralTransformer', () => {
                     {
                         ...NO_CUSTOM_NODES_PRESET,
                         stringArray: true,
-                        stringArrayEncoding: 'base64',
+                        stringArrayEncoding: StringArrayEncoding.Base64,
                         stringArrayThreshold: 1
                     }
                 );
@@ -231,7 +233,7 @@ describe('LiteralTransformer', () => {
                     {
                         ...NO_CUSTOM_NODES_PRESET,
                         stringArray: true,
-                        stringArrayEncoding: 'rc4',
+                        stringArrayEncoding: StringArrayEncoding.Rc4,
                         stringArrayThreshold: 1
                     }
                 );

+ 5 - 1
test/functional-tests/templates/custom-nodes/domain-lock-nodes/DomainLockNodeTemplate.spec.ts

@@ -7,7 +7,8 @@ import { ServiceIdentifiers } from '../../../../../src/container/ServiceIdentifi
 import { ICryptUtils } from '../../../../../src/interfaces/utils/ICryptUtils';
 import { IInversifyContainerFacade } from '../../../../../src/interfaces/container/IInversifyContainerFacade';
 
-import { DomainLockNodeTemplate } from '../../../../../src/templates/custom-nodes/domain-lock-nodes/domain-lock-node/DomainLockNodeTemplate';
+import { DomainLockNodeTemplate } from '../../../../../src/templates/domain-lock-nodes/domain-lock-node/DomainLockNodeTemplate';
+import { GlobalVariableTemplate1 } from '../../../../../src/templates/GlobalVariableTemplate1';
 
 import { InversifyContainerFacade } from '../../../../../src/container/InversifyContainerFacade';
 
@@ -65,6 +66,7 @@ describe('DomainLockNodeTemplate (): string', () => {
                 domainLockFunctionName: 'domainLockFunction',
                 diff: diff,
                 domains: hiddenDomainsString,
+                globalVariableTemplate: GlobalVariableTemplate1(),
                 singleNodeCallControllerFunctionName
             }, singleNodeCallControllerFunctionName, currentDomain);
         });
@@ -90,6 +92,7 @@ describe('DomainLockNodeTemplate (): string', () => {
                 domainLockFunctionName: 'domainLockFunction',
                 diff: diff,
                 domains: hiddenDomainsString,
+                globalVariableTemplate: GlobalVariableTemplate1(),
                 singleNodeCallControllerFunctionName
             }, singleNodeCallControllerFunctionName, currentDomain);
         });
@@ -115,6 +118,7 @@ describe('DomainLockNodeTemplate (): string', () => {
                 domainLockFunctionName: 'domainLockFunction',
                 diff: diff,
                 domains: hiddenDomainsString,
+                globalVariableTemplate: GlobalVariableTemplate1(),
                 singleNodeCallControllerFunctionName
             }, singleNodeCallControllerFunctionName, currentDomain);
         });

+ 14 - 7
test/functional-tests/templates/custom-nodes/string-array-nodes/StringArrayCallsWrapperNodeTemplate.spec.ts

@@ -7,11 +7,12 @@ import { ServiceIdentifiers } from '../../../../../src/container/ServiceIdentifi
 import { ICryptUtils } from '../../../../../src/interfaces/utils/ICryptUtils';
 import { IInversifyContainerFacade } from '../../../../../src/interfaces/container/IInversifyContainerFacade';
 
-import { AtobTemplate } from '../../../../../src/templates/custom-nodes/AtobTemplate';
-import { Rc4Template } from '../../../../../src/templates/custom-nodes/Rc4Template';
-import { StringArrayBase64DecodeNodeTemplate } from '../../../../../src/templates/custom-nodes/string-array-nodes/string-array-calls-wrapper/StringArrayBase64DecodeNodeTemplate';
-import { StringArrayCallsWrapperTemplate } from '../../../../../src/templates/custom-nodes/string-array-nodes/string-array-calls-wrapper/StringArrayCallsWrapperTemplate';
-import { StringArrayRc4DecodeNodeTemplate } from '../../../../../src/templates/custom-nodes/string-array-nodes/string-array-calls-wrapper/StringArrayRC4DecodeNodeTemplate';
+import { AtobTemplate } from '../../../../../src/templates/AtobTemplate';
+import { GlobalVariableTemplate1 } from '../../../../../src/templates/GlobalVariableTemplate1';
+import { Rc4Template } from '../../../../../src/templates/Rc4Template';
+import { StringArrayBase64DecodeNodeTemplate } from '../../../../../src/templates/string-array-nodes/string-array-calls-wrapper/StringArrayBase64DecodeNodeTemplate';
+import { StringArrayCallsWrapperTemplate } from '../../../../../src/templates/string-array-nodes/string-array-calls-wrapper/StringArrayCallsWrapperTemplate';
+import { StringArrayRc4DecodeNodeTemplate } from '../../../../../src/templates/string-array-nodes/string-array-calls-wrapper/StringArrayRC4DecodeNodeTemplate';
 
 import { InversifyContainerFacade } from '../../../../../src/container/InversifyContainerFacade';
 
@@ -29,8 +30,11 @@ describe('StringArrayCallsWrapperNodeTemplate (): string', () => {
     });
 
     describe('variant #1: `base64` encoding', () => {
+        const atobPolyfill = format(AtobTemplate(), {
+            globalVariableTemplate: GlobalVariableTemplate1()
+        });
         const atobDecodeNodeTemplate: string = format(StringArrayBase64DecodeNodeTemplate(), {
-            atobPolyfill: AtobTemplate(),
+            atobPolyfill,
             selfDefendingCode: '',
             stringArrayCallsWrapperName
         });
@@ -61,8 +65,11 @@ describe('StringArrayCallsWrapperNodeTemplate (): string', () => {
     });
 
     describe('variant #2: `rc4` encoding', () => {
+        const atobPolyfill = format(AtobTemplate(), {
+            globalVariableTemplate: GlobalVariableTemplate1()
+        });
         const rc4DecodeNodeTemplate: string = format(StringArrayRc4DecodeNodeTemplate(), {
-            atobPolyfill: AtobTemplate(),
+            atobPolyfill,
             rc4Polyfill: Rc4Template(),
             selfDefendingCode: '',
             stringArrayCallsWrapperName

+ 1 - 0
test/index.spec.ts

@@ -8,6 +8,7 @@ require('source-map-support').install();
 import './unit-tests/analyzers/stack-trace-analyzer/StackTraceAnalyzer.spec';
 import './unit-tests/cli/sanitizers/ArraySanitizer.spec';
 import './unit-tests/cli/sanitizers/BooleanSanitizer.spec';
+import './unit-tests/cli/sanitizers/ObfuscationTargetSanitizer.spec';
 import './unit-tests/cli/sanitizers/SourceMapModeSanitizer.spec';
 import './unit-tests/cli/sanitizers/StringArrayEncodingSanitizer.spec';
 import './unit-tests/cli/utils/CLIUtils.spec';

+ 3 - 1
test/runtime-tests/JavaScriptObfuscatorRuntime.spec.ts

@@ -2,6 +2,8 @@ import { assert } from 'chai';
 
 import { IObfuscationResult } from '../../src/interfaces/IObfuscationResult';
 
+import { StringArrayEncoding } from '../../src/enums/StringArrayEncoding';
+
 import { readFileAsString } from '../helpers/readFileAsString';
 
 import { JavaScriptObfuscator } from '../../src/JavaScriptObfuscatorFacade';
@@ -20,7 +22,7 @@ describe('JavaScriptObfuscator runtime eval', function () {
                 deadCodeInjection: true,
                 debugProtection: true,
                 selfDefending: true,
-                stringArrayEncoding: 'rc4'
+                stringArrayEncoding: StringArrayEncoding.Rc4
             }
         );
 

+ 36 - 0
test/unit-tests/cli/sanitizers/ObfuscationTargetSanitizer.spec.ts

@@ -0,0 +1,36 @@
+import { assert } from 'chai';
+
+import { ObfuscationTargetSanitizer } from '../../../../src/cli/sanitizers/ObfuscatingTargetSanitizer';
+
+describe('ObfuscationTargetSanitizer', () => {
+    describe('ObfuscationTargetSanitizer: TCLISanitizer = (value: string): string', () => {
+        describe('variant #1: valid obfuscation target', () => {
+            const inputValue: string = 'browser';
+            const expectedValue: string = inputValue;
+
+            let value: string;
+
+            before(() => {
+                value = ObfuscationTargetSanitizer(inputValue);
+            });
+
+            it('should sanitize value', () => {
+                assert.equal(value, expectedValue);
+            });
+        });
+
+        describe('variant #2: invalid obfuscation target', () => {
+            const inputValue: string = 'foo';
+
+            let testFunc: () => void;
+
+            before(() => {
+                testFunc = () => ObfuscationTargetSanitizer(inputValue);
+            });
+
+            it('should throw error', () => {
+                assert.throw(testFunc, ReferenceError);
+            });
+        });
+    });
+});

+ 4 - 2
test/unit-tests/options/OptionsNormalizer.spec.ts

@@ -4,6 +4,8 @@ import { TInputOptions } from '../../../src/types/options/TInputOptions';
 
 import { IOptions } from '../../../src/interfaces/options/IOptions';
 
+import { StringArrayEncoding } from '../../../src/enums/StringArrayEncoding';
+
 import { DEFAULT_PRESET } from '../../../src/options/presets/Default';
 
 import { Options } from '../../../src/options/Options';
@@ -247,7 +249,7 @@ describe('OptionsNormalizer', () => {
                 optionsPreset = getNormalizedOptions({
                     ...DEFAULT_PRESET,
                     stringArray: false,
-                    stringArrayEncoding: 'rc4',
+                    stringArrayEncoding: StringArrayEncoding.Rc4,
                     stringArrayThreshold: 0.5,
                     rotateStringArray: true
                 });
@@ -275,7 +277,7 @@ describe('OptionsNormalizer', () => {
 
                 expectedOptionsPreset = {
                     ...DEFAULT_PRESET,
-                    stringArrayEncoding: 'base64'
+                    stringArrayEncoding: StringArrayEncoding.Base64
                 };
             });
 

+ 1 - 3
test/unit-tests/source-map/SourceMapCorrector.spec.ts

@@ -2,8 +2,6 @@ import { ServiceIdentifiers } from '../../../src/container/ServiceIdentifiers';
 
 import { assert } from 'chai';
 
-import { TSourceMapMode } from '../../../src/types/source-map/TSourceMapMode';
-
 import { IInversifyContainerFacade } from '../../../src/interfaces/container/IInversifyContainerFacade';
 import { IObfuscationResult } from '../../../src/interfaces/IObfuscationResult';
 import { ISourceMapCorrector } from '../../../src/interfaces/source-map/ISourceMapCorrector';
@@ -24,7 +22,7 @@ function getCorrectedObfuscationResult (
     sourceMap: string,
     sourceMapBaseUrl: string,
     sourceMapFileName: string,
-    sourceMapMode: TSourceMapMode
+    sourceMapMode: SourceMapMode
 ): IObfuscationResult {
     const inversifyContainerFacade: IInversifyContainerFacade = new InversifyContainerFacade();
 

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio