瀏覽代碼

`debugProtectionInteraval` option now accepts value in milliseconds instead of `boolean` value (#1063)

Timofey Kachalov 3 年之前
父節點
當前提交
e8e92c601d
共有 21 個文件被更改,包括 152 次插入35 次删除
  1. 4 0
      CHANGELOG.md
  2. 8 8
      README.md
  3. 1 1
      package.json
  4. 3 3
      src/cli/JavaScriptObfuscatorCLI.ts
  5. 19 2
      src/custom-code-helpers/debug-protection/DebugProtectionFunctionIntervalCodeHelper.ts
  6. 1 1
      src/custom-code-helpers/debug-protection/group/DebugProtectionCodeHelperGroup.ts
  7. 5 3
      src/custom-code-helpers/debug-protection/templates/debug-protection-function-interval/DebugProtectionFunctionIntervalTemplate.ts
  8. 0 1
      src/custom-code-helpers/debug-protection/templates/debug-protection-function/DebugProtectionFunctionTemplate.ts
  9. 1 1
      src/interfaces/options/IOptions.ts
  10. 4 3
      src/options/Options.ts
  11. 1 1
      src/options/presets/Default.ts
  12. 1 1
      src/options/presets/HighObfuscation.ts
  13. 1 1
      src/options/presets/NoCustomNodes.ts
  14. 6 6
      test/functional-tests/custom-code-helpers/debug-protection/templates/debug-protection-function-call-template/DebugProtectionFunctionCallTemplate.spec.ts
  15. 0 0
      test/functional-tests/custom-code-helpers/debug-protection/templates/debug-protection-function-call-template/fixtures/input.js
  16. 0 0
      test/functional-tests/custom-code-helpers/debug-protection/templates/debug-protection-function-call-template/fixtures/single-call.js
  17. 90 0
      test/functional-tests/custom-code-helpers/debug-protection/templates/debug-protection-function-interval-template/DebugProtectionFunctionIntervalTemplate.spec.ts
  18. 3 0
      test/functional-tests/custom-code-helpers/debug-protection/templates/debug-protection-function-interval-template/fixtures/input.js
  19. 1 1
      test/functional-tests/javascript-obfuscator/JavaScriptObfuscator.spec.ts
  20. 2 1
      test/index.spec.ts
  21. 1 1
      test/performance-tests/JavaScriptObfuscatorMemory.spec.ts

+ 4 - 0
CHANGELOG.md

@@ -1,5 +1,9 @@
 Change Log
 
+v4.0.0
+---
+* **Breaking change:** `debugProtectionInteraval` option now accepts value in milliseconds instead of `boolean` value. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/1031
+
 v3.2.7
 ---
 * Fixed cases when dead code is added to the inner code of `eval` expressions. Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/1053

+ 8 - 8
README.md

@@ -349,7 +349,7 @@ Following options are available for the JS Obfuscator:
     deadCodeInjection: false,
     deadCodeInjectionThreshold: 0.4,
     debugProtection: false,
-    debugProtectionInterval: false,
+    debugProtectionInterval: 0,
     disableConsoleOutput: false,
     domainLock: [],
     domainLockRedirectUrl: 'about:blank',
@@ -413,7 +413,7 @@ Following options are available for the JS Obfuscator:
     --dead-code-injection <boolean>
     --dead-code-injection-threshold <number>
     --debug-protection <boolean>
-    --debug-protection-interval <boolean>
+    --debug-protection-interval <number>
     --disable-console-output <boolean>
     --domain-lock '<list>' (comma separated)
     --domain-lock-redirect-url <string>
@@ -678,11 +678,11 @@ Type: `boolean` Default: `false`
 This option makes it almost impossible to use the `debugger` function of the Developer Tools (both on WebKit-based and Mozilla Firefox).
 
 ### `debugProtectionInterval`
-Type: `boolean` Default: `false`
+Type: `number` Default: `0`
 
 ##### :warning: Can freeze your browser! Use at own risk.
 
-If checked, an interval is used to force the debug mode on the Console tab, making it harder to use other features of the Developer Tools. Works if [`debugProtection`](#debugprotection) is enabled.
+If set, an interval in milliseconds is used to force the debug mode on the Console tab, making it harder to use other features of the Developer Tools. Works if [`debugProtection`](#debugprotection) is enabled. Recommended value is between `2000` and `4000` milliseconds.
 
 ### `disableConsoleOutput`
 Type: `boolean` Default: `false`
@@ -1507,7 +1507,7 @@ The performance will be much slower than without obfuscation
     deadCodeInjection: true,
     deadCodeInjectionThreshold: 1,
     debugProtection: true,
-    debugProtectionInterval: true,
+    debugProtectionInterval: 4000,
     disableConsoleOutput: true,
     identifierNamesGenerator: 'hexadecimal',
     log: false,
@@ -1545,7 +1545,7 @@ The performance will be slower than without obfuscation
     deadCodeInjection: true,
     deadCodeInjectionThreshold: 0.4,
     debugProtection: false,
-    debugProtectionInterval: false,
+    debugProtectionInterval: 0,
     disableConsoleOutput: true,
     identifierNamesGenerator: 'hexadecimal',
     log: false,
@@ -1582,7 +1582,7 @@ The performance will be at a relatively normal level
     controlFlowFlattening: false,
     deadCodeInjection: false,
     debugProtection: false,
-    debugProtectionInterval: false,
+    debugProtectionInterval: 0,
     disableConsoleOutput: true,
     identifierNamesGenerator: 'hexadecimal',
     log: false,
@@ -1614,7 +1614,7 @@ The performance will be at a relatively normal level
     controlFlowFlattening: false,
     deadCodeInjection: false,
     debugProtection: false,
-    debugProtectionInterval: false,
+    debugProtectionInterval: 0,
     disableConsoleOutput: false,
     identifierNamesGenerator: 'hexadecimal',
     log: false,

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "javascript-obfuscator",
-  "version": "3.2.7",
+  "version": "4.0.0",
   "description": "JavaScript obfuscator",
   "keywords": [
     "obfuscator",

+ 3 - 3
src/cli/JavaScriptObfuscatorCLI.ts

@@ -223,9 +223,9 @@ export class JavaScriptObfuscatorCLI implements IInitializable {
                 BooleanSanitizer
             )
             .option(
-                '--debug-protection-interval <boolean>',
-                'Disable browser Debug panel even after page was loaded (can cause DevTools enabled browser freeze)',
-                BooleanSanitizer
+                '--debug-protection-interval <number>',
+                'Sets interval in milliseconds for debug protection so it is working even after page was loaded (can cause DevTools enabled browser freeze)',
+                parseInt
             )
             .option(
                 '--disable-console-output <boolean>',

+ 19 - 2
src/custom-code-helpers/debug-protection/DebugProtectionFunctionIntervalCodeHelper.ts

@@ -9,9 +9,12 @@ import { ICustomCodeHelperObfuscator } from '../../interfaces/custom-code-helper
 import { IOptions } from '../../interfaces/options/IOptions';
 import { IRandomGenerator } from '../../interfaces/utils/IRandomGenerator';
 
+import { ObfuscationTarget } from '../../enums/ObfuscationTarget';
+
 import { initializable } from '../../decorators/Initializable';
 
 import { DebugProtectionFunctionIntervalTemplate } from './templates/debug-protection-function-interval/DebugProtectionFunctionIntervalTemplate';
+import { GlobalVariableNoEvalTemplate } from '../common/templates/GlobalVariableNoEvalTemplate';
 
 import { AbstractCustomCodeHelper } from '../AbstractCustomCodeHelper';
 import { NodeUtils } from '../../node/NodeUtils';
@@ -24,6 +27,12 @@ export class DebugProtectionFunctionIntervalCodeHelper extends AbstractCustomCod
     @initializable()
     private debugProtectionFunctionName!: string;
 
+    /**
+     * @type {number}
+     */
+    @initializable()
+    private debugProtectionInterval!: number;
+
     /**
      * @param {TIdentifierNamesGeneratorFactory} identifierNamesGeneratorFactory
      * @param {ICustomCodeHelperFormatter} customCodeHelperFormatter
@@ -50,9 +59,11 @@ export class DebugProtectionFunctionIntervalCodeHelper extends AbstractCustomCod
 
     /**
      * @param {string} debugProtectionFunctionName
+     * @param {number} debugProtectionInterval
      */
-    public initialize (debugProtectionFunctionName: string): void {
+    public initialize (debugProtectionFunctionName: string, debugProtectionInterval: number): void {
         this.debugProtectionFunctionName = debugProtectionFunctionName;
+        this.debugProtectionInterval = debugProtectionInterval;
     }
 
     /**
@@ -67,8 +78,14 @@ export class DebugProtectionFunctionIntervalCodeHelper extends AbstractCustomCod
      * @returns {string}
      */
     protected override getCodeHelperTemplate (): string {
+        const globalVariableTemplate: string = this.options.target !== ObfuscationTarget.BrowserNoEval
+            ? this.getGlobalVariableTemplate()
+            : GlobalVariableNoEvalTemplate();
+
         return this.customCodeHelperFormatter.formatTemplate(DebugProtectionFunctionIntervalTemplate(), {
-            debugProtectionFunctionName: this.debugProtectionFunctionName
+            debugProtectionFunctionName: this.debugProtectionFunctionName,
+            debugProtectionInterval: this.debugProtectionInterval,
+            globalVariableTemplate
         });
     }
 }

+ 1 - 1
src/custom-code-helpers/debug-protection/group/DebugProtectionCodeHelperGroup.ts

@@ -124,7 +124,7 @@ export class DebugProtectionCodeHelperGroup extends AbstractCustomCodeHelperGrou
                     : nodeWithStatements.body.length;
                 const randomIndex: number = this.randomGenerator.getRandomInteger(0, programBodyLength);
 
-                customCodeHelper.initialize(debugProtectionFunctionName);
+                customCodeHelper.initialize(debugProtectionFunctionName, this.options.debugProtectionInterval);
 
                 NodeAppender.insertAtIndex(nodeWithStatements, customCodeHelper.getNode(), randomIndex);
             }

+ 5 - 3
src/custom-code-helpers/debug-protection/templates/debug-protection-function-interval/DebugProtectionFunctionIntervalTemplate.ts

@@ -3,8 +3,10 @@
  */
 export function DebugProtectionFunctionIntervalTemplate (): string {
     return `
-        setInterval(function () {
-            {debugProtectionFunctionName}();
-        }, 4000);
+        (function () {
+            {globalVariableTemplate}
+    
+            that.setInterval({debugProtectionFunctionName}, {debugProtectionInterval});
+        })();
     `;
 }

+ 0 - 1
src/custom-code-helpers/debug-protection/templates/debug-protection-function/DebugProtectionFunctionTemplate.ts

@@ -5,7 +5,6 @@ export function DebugProtectionFunctionTemplate (): string {
     return `
         function {debugProtectionFunctionName} (ret) {
             function debuggerProtection (counter) {
-            
                 {debuggerTemplate}
                 
                 debuggerProtection(++counter);

+ 1 - 1
src/interfaces/options/IOptions.ts

@@ -18,7 +18,7 @@ export interface IOptions {
     readonly deadCodeInjection: boolean;
     readonly deadCodeInjectionThreshold: number;
     readonly debugProtection: boolean;
-    readonly debugProtectionInterval: boolean;
+    readonly debugProtectionInterval: number;
     readonly disableConsoleOutput: boolean;
     readonly domainLock: string[];
     readonly domainLockRedirectUrl: string;

+ 4 - 3
src/options/Options.ts

@@ -112,10 +112,11 @@ export class Options implements IOptions {
     public readonly debugProtection!: boolean;
 
     /**
-     * @type {boolean}
+     * @type {number}
      */
-    @IsBoolean()
-    public readonly debugProtectionInterval!: boolean;
+    @IsNumber()
+    @Min(0)
+    public readonly debugProtectionInterval!: number;
 
     /**
      * @type {boolean}

+ 1 - 1
src/options/presets/Default.ts

@@ -18,7 +18,7 @@ export const DEFAULT_PRESET: TInputOptions = Object.freeze({
     deadCodeInjection: false,
     deadCodeInjectionThreshold: 0.4,
     debugProtection: false,
-    debugProtectionInterval: false,
+    debugProtectionInterval: 0,
     disableConsoleOutput: false,
     domainLock: [],
     domainLockRedirectUrl: 'about:blank',

+ 1 - 1
src/options/presets/HighObfuscation.ts

@@ -10,7 +10,7 @@ export const HIGH_OBFUSCATION_PRESET: TInputOptions = Object.freeze({
     controlFlowFlatteningThreshold: 1,
     deadCodeInjectionThreshold: 1,
     debugProtection: true,
-    debugProtectionInterval: true,
+    debugProtectionInterval: 4000,
     optionsPreset: OptionsPreset.HighObfuscation,
     splitStringsChunkLength: 5,
     stringArrayCallsTransformThreshold: 1,

+ 1 - 1
src/options/presets/NoCustomNodes.ts

@@ -16,7 +16,7 @@ export const NO_ADDITIONAL_NODES_PRESET: TInputOptions = Object.freeze({
     deadCodeInjection: false,
     deadCodeInjectionThreshold: 0,
     debugProtection: false,
-    debugProtectionInterval: false,
+    debugProtectionInterval: 0,
     disableConsoleOutput: false,
     domainLock: [],
     domainLockRedirectUrl: 'about:blank',

+ 6 - 6
test/functional-tests/custom-code-helpers/debug-protection/templates/DebugProtectionFunctionCallTemplate.spec.ts → test/functional-tests/custom-code-helpers/debug-protection/templates/debug-protection-function-call-template/DebugProtectionFunctionCallTemplate.spec.ts

@@ -1,15 +1,15 @@
 import { assert } from 'chai';
 
-import { readFileAsString } from '../../../../helpers/readFileAsString';
+import { readFileAsString } from '../../../../../helpers/readFileAsString';
 
-import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../src/options/presets/NoCustomNodes';
+import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../../src/options/presets/NoCustomNodes';
 
-import { IdentifierNamesGenerator } from '../../../../../src/enums/generators/identifier-names-generators/IdentifierNamesGenerator';
-import { ObfuscationTarget } from '../../../../../src/enums/ObfuscationTarget';
+import { IdentifierNamesGenerator } from '../../../../../../src/enums/generators/identifier-names-generators/IdentifierNamesGenerator';
+import { ObfuscationTarget } from '../../../../../../src/enums/ObfuscationTarget';
 
-import { evaluateInWorker } from '../../../../helpers/evaluateInWorker';
+import { evaluateInWorker } from '../../../../../helpers/evaluateInWorker';
 
-import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
+import { JavaScriptObfuscator } from '../../../../../../src/JavaScriptObfuscatorFacade';
 
 describe('DebugProtectionFunctionCallTemplate', function () {
     const evaluationTimeout: number = 1500;

+ 0 - 0
test/functional-tests/custom-code-helpers/debug-protection/templates/fixtures/input.js → test/functional-tests/custom-code-helpers/debug-protection/templates/debug-protection-function-call-template/fixtures/input.js


+ 0 - 0
test/functional-tests/custom-code-helpers/debug-protection/templates/fixtures/single-call.js → test/functional-tests/custom-code-helpers/debug-protection/templates/debug-protection-function-call-template/fixtures/single-call.js


+ 90 - 0
test/functional-tests/custom-code-helpers/debug-protection/templates/debug-protection-function-interval-template/DebugProtectionFunctionIntervalTemplate.spec.ts

@@ -0,0 +1,90 @@
+import { assert } from 'chai';
+
+import { readFileAsString } from '../../../../../helpers/readFileAsString';
+
+import { HIGH_OBFUSCATION_PRESET } from '../../../../../../src/options/presets/HighObfuscation';
+import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../../src/options/presets/NoCustomNodes';
+
+import { JavaScriptObfuscator } from '../../../../../../src/JavaScriptObfuscatorFacade';
+
+describe('DebugProtectionFunctionIntervalTemplate', function () {
+    const variableMatch: string = '_0x([a-f0-9]){4,6}';
+
+    describe('Variant #1 - `high-obfuscation` preset interval', () => {
+        const debugProtectionIntervalRegExp: RegExp = new RegExp(
+            `${variableMatch}\\['setInterval'\\]\\( *` +
+                `${variableMatch}, *` +
+                '0xfa0 *' +
+            `\\);`
+        );
+
+        let obfuscatedCode: string;
+
+        beforeEach(() => {
+            const code: string = readFileAsString(__dirname + '/fixtures/input.js');
+            obfuscatedCode = JavaScriptObfuscator.obfuscate(
+                code,
+                {
+                    ...NO_ADDITIONAL_NODES_PRESET,
+                    debugProtection: true,
+                    debugProtectionInterval: HIGH_OBFUSCATION_PRESET.debugProtectionInterval
+                }
+            ).getObfuscatedCode();
+
+            console.log(obfuscatedCode);
+        });
+
+        it('Should add debug protection interval code with default interval value', () => {
+            assert.match(obfuscatedCode, debugProtectionIntervalRegExp);
+        });
+    });
+
+    describe('Variant #2 - custom interval', () => {
+        const debugProtectionIntervalRegExp: RegExp = new RegExp(
+            `${variableMatch}\\['setInterval'\\]\\( *` +
+                `${variableMatch}, *` +
+                '0x64 *' +
+            `\\);`
+        );
+
+        let obfuscatedCode: string;
+
+        beforeEach(() => {
+            const code: string = readFileAsString(__dirname + '/fixtures/input.js');
+            obfuscatedCode = JavaScriptObfuscator.obfuscate(
+                code,
+                {
+                    ...NO_ADDITIONAL_NODES_PRESET,
+                    debugProtection: true,
+                    debugProtectionInterval: 100
+                }
+            ).getObfuscatedCode();
+        });
+
+        it('Should add debug protection interval code with default interval value', () => {
+            assert.match(obfuscatedCode, debugProtectionIntervalRegExp);
+        });
+    });
+
+    describe('Variant #3 - no interval', () => {
+        const debugProtectionIntervalRegExp: RegExp = /setInterval/
+
+        let obfuscatedCode: string;
+
+        beforeEach(() => {
+            const code: string = readFileAsString(__dirname + '/fixtures/input.js');
+            obfuscatedCode = JavaScriptObfuscator.obfuscate(
+                code,
+                {
+                    ...NO_ADDITIONAL_NODES_PRESET,
+                    debugProtection: true,
+                    debugProtectionInterval: 0
+                }
+            ).getObfuscatedCode();
+        });
+
+        it('Should not add debug protection interval code', () => {
+            assert.notMatch(obfuscatedCode, debugProtectionIntervalRegExp);
+        });
+    });
+});

+ 3 - 0
test/functional-tests/custom-code-helpers/debug-protection/templates/debug-protection-function-interval-template/fixtures/input.js

@@ -0,0 +1,3 @@
+(function () {
+    return 1;
+})();

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

@@ -1442,7 +1442,7 @@ describe('JavaScriptObfuscator', () => {
                 deadCodeInjection: true,
                 deadCodeInjectionThreshold: 1,
                 debugProtection: true,
-                debugProtectionInterval: true,
+                debugProtectionInterval: 4000,
                 disableConsoleOutput: false,
                 stringArrayRotate: true,
                 selfDefending: true,

+ 2 - 1
test/index.spec.ts

@@ -64,7 +64,8 @@ import './functional-tests/code-transformers/preparing-transformers/hashbang-ope
 import './functional-tests/custom-code-helpers/common/templates/GlobalVariableNoEvalTemplate.spec';
 import './functional-tests/custom-code-helpers/console-output/ConsoleOutputDisableExpressionCodeHelper.spec';
 import './functional-tests/custom-code-helpers/console-output/templates/ConsoleOutputDisableTemplate.spec';
-import './functional-tests/custom-code-helpers/debug-protection/templates/DebugProtectionFunctionCallTemplate.spec';
+import './functional-tests/custom-code-helpers/debug-protection/templates/debug-protection-function-call-template/DebugProtectionFunctionCallTemplate.spec';
+import './functional-tests/custom-code-helpers/debug-protection/templates/debug-protection-function-interval-template/DebugProtectionFunctionIntervalTemplate.spec';
 import './functional-tests/custom-code-helpers/domain-lock/DomainLockCodeHelper.spec';
 import './functional-tests/custom-code-helpers/domain-lock/templates/DomainLockNodeTemplate.spec';
 import './functional-tests/custom-code-helpers/self-defending/SelfDefendingCodeHelper.spec';

+ 1 - 1
test/performance-tests/JavaScriptObfuscatorMemory.spec.ts

@@ -32,7 +32,7 @@ describe('JavaScriptObfuscator memory', function () {
                         deadCodeInjection: true,
                         deadCodeInjectionThreshold: 0.4,
                         debugProtection: false,
-                        debugProtectionInterval: false,
+                        debugProtectionInterval: 0,
                         disableConsoleOutput: true,
                         identifierNamesGenerator: 'mangled',
                         log: false,