ConditionalCommentObfuscatingGuard.spec.ts 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. import { assert } from 'chai';
  2. import { JavaScriptObfuscator } from '../../../../../../src/JavaScriptObfuscatorFacade';
  3. import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../../src/options/presets/NoCustomNodes';
  4. import { readFileAsString } from '../../../../../helpers/readFileAsString';
  5. describe('ConditionalCommentObfuscatingGuard', () => {
  6. describe('check', () => {
  7. describe('Variant #1: `disable` conditional comment', () => {
  8. const obfuscatedVariableDeclarationRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *0x1;/;
  9. const ignoredVariableDeclarationRegExp: RegExp = /var *bar *= *2;/;
  10. const consoleLogRegExp: RegExp = /console.log\(_0x([a-f0-9]){4,6}\);/;
  11. let obfuscatedCode: string;
  12. beforeEach(() => {
  13. const code: string = readFileAsString(__dirname + '/fixtures/simple.js');
  14. obfuscatedCode = JavaScriptObfuscator.obfuscate(
  15. code,
  16. {
  17. ...NO_ADDITIONAL_NODES_PRESET
  18. }
  19. ).getObfuscatedCode();
  20. });
  21. it('match #1: should obfuscate variable declaration before `disable` conditional comment', () => {
  22. assert.match(obfuscatedCode, obfuscatedVariableDeclarationRegExp);
  23. });
  24. it('match #2: should ignore variable declaration after `disable` conditional comment', () => {
  25. assert.match(obfuscatedCode, ignoredVariableDeclarationRegExp);
  26. });
  27. it('match #3: should obfuscate variable name in `console.log`', () => {
  28. assert.match(obfuscatedCode, consoleLogRegExp);
  29. });
  30. });
  31. describe('Variant #2: `disable` and `enable` conditional comments', () => {
  32. const obfuscatedVariableDeclaration1RegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *0x1;/;
  33. const obfuscatedVariableDeclaration2RegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *0x3;/;
  34. const ignoredVariableDeclarationRegExp: RegExp = /var *bar *= *2;/;
  35. let obfuscatedCode: string;
  36. beforeEach(() => {
  37. const code: string = readFileAsString(__dirname + '/fixtures/disable-and-enable-comments.js');
  38. obfuscatedCode = JavaScriptObfuscator.obfuscate(
  39. code,
  40. {
  41. ...NO_ADDITIONAL_NODES_PRESET
  42. }
  43. ).getObfuscatedCode();
  44. });
  45. it('match #1: should obfuscate variable declaration before `disable` conditional comment', () => {
  46. assert.match(obfuscatedCode, obfuscatedVariableDeclaration1RegExp);
  47. });
  48. it('match #2: should ignore variable declaration after `disable` conditional comment', () => {
  49. assert.match(obfuscatedCode, ignoredVariableDeclarationRegExp);
  50. });
  51. it('match #3: should obfuscate variable declaration after `enable` conditional comment', () => {
  52. assert.match(obfuscatedCode, obfuscatedVariableDeclaration2RegExp);
  53. });
  54. });
  55. describe('Variant #3: `disable` conditional comment from beginning of the code', () => {
  56. const ignoredVariableDeclaration1RegExp: RegExp = /var *foo *= *1;/;
  57. const ignoredVariableDeclaration2RegExp: RegExp = /var *bar *= *2;/;
  58. let obfuscatedCode: string;
  59. beforeEach(() => {
  60. const code: string = readFileAsString(__dirname + '/fixtures/disable-from-beginning.js');
  61. obfuscatedCode = JavaScriptObfuscator.obfuscate(
  62. code,
  63. {
  64. ...NO_ADDITIONAL_NODES_PRESET
  65. }
  66. ).getObfuscatedCode();
  67. });
  68. it('match #1: should ignore variable declaration after `disable` conditional comment', () => {
  69. assert.match(obfuscatedCode, ignoredVariableDeclaration1RegExp);
  70. });
  71. it('match #2: should ignore variable declaration after `disable` conditional comment', () => {
  72. assert.match(obfuscatedCode, ignoredVariableDeclaration2RegExp);
  73. });
  74. });
  75. describe('Variant #4: `disable` and `enable` conditional comments with dead code injection', () => {
  76. const obfuscatedFunctionExpressionRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *function *\(_0x([a-f0-9]){4,6}, *_0x([a-f0-9]){4,6}, *_0x([a-f0-9]){4,6}\) *{/g;
  77. const expectedObfuscatedFunctionExpressionLength: number = 3;
  78. const ignoredFunctionExpression1RegExp: RegExp = /var *bar *= *function *\(a, *b, *c\) *{/;
  79. const ignoredFunctionExpression2RegExp: RegExp = /var *baz *= *function *\(a, *b, *c\) *{/;
  80. const obfuscatedFunctionCallRegExp: RegExp = /_0x([a-f0-9]){4,6}\( *\);/g;
  81. const expectedObfuscatedFunctionCallsLength: number = 3;
  82. const ignoredFunctionCall1RegExp: RegExp = /bar\( *\);/;
  83. const ignoredFunctionCall2RegExp: RegExp = /baz\( *\);/;
  84. let obfuscatedCode: string,
  85. obfuscatedFunctionExpressionMatchesLength: number,
  86. obfuscatedFunctionCallMatchesLength: number;
  87. beforeEach(() => {
  88. const code: string = readFileAsString(__dirname + '/fixtures/dead-code-injection.js');
  89. obfuscatedCode = JavaScriptObfuscator.obfuscate(
  90. code,
  91. {
  92. ...NO_ADDITIONAL_NODES_PRESET,
  93. deadCodeInjection: true,
  94. deadCodeInjectionThreshold: 1
  95. }
  96. ).getObfuscatedCode();
  97. const obfuscatedFunctionExpressionMatches: RegExpMatchArray | null = obfuscatedCode.match(
  98. obfuscatedFunctionExpressionRegExp
  99. );
  100. const obfuscatedFunctionCallMatches: RegExpMatchArray | null = obfuscatedCode.match(
  101. obfuscatedFunctionCallRegExp
  102. );
  103. obfuscatedFunctionExpressionMatchesLength = obfuscatedFunctionExpressionMatches
  104. ? obfuscatedFunctionExpressionMatches.length
  105. : 0;
  106. obfuscatedFunctionCallMatchesLength = obfuscatedFunctionCallMatches
  107. ? obfuscatedFunctionCallMatches.length
  108. : 0;
  109. });
  110. it('match #1: should ignore function expression after `disable` conditional comment', () => {
  111. assert.match(obfuscatedCode, ignoredFunctionExpression1RegExp);
  112. });
  113. it('match #2: should ignore function expression after `disable` conditional comment', () => {
  114. assert.match(obfuscatedCode, ignoredFunctionExpression2RegExp);
  115. });
  116. it('match #3: should ignore function expression call', () => {
  117. assert.match(obfuscatedCode, ignoredFunctionCall1RegExp);
  118. });
  119. it('match #4: should ignore function expression call', () => {
  120. assert.match(obfuscatedCode, ignoredFunctionCall2RegExp);
  121. });
  122. it('should obfuscate 3 function expressions', () => {
  123. assert.equal(obfuscatedFunctionExpressionMatchesLength, expectedObfuscatedFunctionExpressionLength);
  124. });
  125. it('should obfuscate 3 function expression calls', () => {
  126. assert.equal(obfuscatedFunctionCallMatchesLength, expectedObfuscatedFunctionCallsLength);
  127. });
  128. });
  129. describe('Variant #5: `disable` and `enable` conditional comments with control flow flattening', () => {
  130. const obfuscatedVariableDeclarationRegExp: RegExp = /var *_0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\['[a-zA-Z0-9]{1,5}'];/;
  131. const ignoredVariableDeclarationRegExp: RegExp = /var *bar *= *'bar';/;
  132. let obfuscatedCode: string;
  133. beforeEach(() => {
  134. const code: string = readFileAsString(__dirname + '/fixtures/control-flow-flattening.js');
  135. obfuscatedCode = JavaScriptObfuscator.obfuscate(
  136. code,
  137. {
  138. ...NO_ADDITIONAL_NODES_PRESET,
  139. controlFlowFlattening: true,
  140. controlFlowFlatteningThreshold: 1
  141. }
  142. ).getObfuscatedCode();
  143. });
  144. it('match #1: should obfuscate variable declaration before `disable` conditional comment', () => {
  145. assert.match(obfuscatedCode, obfuscatedVariableDeclarationRegExp);
  146. });
  147. it('match #2: should ignore variable declaration after `disable` conditional comment', () => {
  148. assert.match(obfuscatedCode, ignoredVariableDeclarationRegExp);
  149. });
  150. });
  151. });
  152. });