ConditionalCommentObfuscatingGuard.spec.ts 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  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 #1', () => {
  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-1.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` and `enable` conditional comments #2', () => {
  56. const ignoredVariableDeclarationRegExp: RegExp = /var foo *= *1;/;
  57. const obfuscatedVariableDeclarationRegExp: RegExp = /var _0x([a-f0-9]){4,6} *= *0x2;/;
  58. let obfuscatedCode: string;
  59. beforeEach(() => {
  60. const code: string = readFileAsString(__dirname + '/fixtures/disable-and-enable-comments-2.js');
  61. obfuscatedCode = JavaScriptObfuscator.obfuscate(
  62. code,
  63. {
  64. ...NO_ADDITIONAL_NODES_PRESET,
  65. renameGlobals: true
  66. }
  67. ).getObfuscatedCode();
  68. });
  69. it('match #1: should ignore variable declaration after `disable` conditional comment', () => {
  70. assert.match(obfuscatedCode, ignoredVariableDeclarationRegExp);
  71. });
  72. it('match #2: should obfuscate variable declaration before `disable` conditional comment', () => {
  73. assert.match(obfuscatedCode, obfuscatedVariableDeclarationRegExp);
  74. });
  75. });
  76. describe('Variant #4: `disable` conditional comment from beginning of the code', () => {
  77. const ignoredVariableDeclaration1RegExp: RegExp = /var foo *= *1;/;
  78. const ignoredVariableDeclaration2RegExp: RegExp = /var bar *= *2;/;
  79. let obfuscatedCode: string;
  80. beforeEach(() => {
  81. const code: string = readFileAsString(__dirname + '/fixtures/disable-from-beginning.js');
  82. obfuscatedCode = JavaScriptObfuscator.obfuscate(
  83. code,
  84. {
  85. ...NO_ADDITIONAL_NODES_PRESET
  86. }
  87. ).getObfuscatedCode();
  88. });
  89. it('match #1: should ignore variable declaration after `disable` conditional comment', () => {
  90. assert.match(obfuscatedCode, ignoredVariableDeclaration1RegExp);
  91. });
  92. it('match #2: should ignore variable declaration after `disable` conditional comment', () => {
  93. assert.match(obfuscatedCode, ignoredVariableDeclaration2RegExp);
  94. });
  95. });
  96. describe('Variant #5: `disable` and `enable` conditional comments with dead code injection', () => {
  97. 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;
  98. const expectedObfuscatedFunctionExpressionLength: number = 3;
  99. const ignoredFunctionExpression1RegExp: RegExp = /var bar *= *function *\(a, *b, *c\) *{/;
  100. const ignoredFunctionExpression2RegExp: RegExp = /var baz *= *function *\(a, *b, *c\) *{/;
  101. const obfuscatedFunctionCallRegExp: RegExp = /_0x([a-f0-9]){4,6}\( *\);/g;
  102. const expectedObfuscatedFunctionCallsLength: number = 3;
  103. const ignoredFunctionCall1RegExp: RegExp = /bar\( *\);/;
  104. const ignoredFunctionCall2RegExp: RegExp = /baz\( *\);/;
  105. let obfuscatedCode: string,
  106. obfuscatedFunctionExpressionMatchesLength: number,
  107. obfuscatedFunctionCallMatchesLength: number;
  108. beforeEach(() => {
  109. const code: string = readFileAsString(__dirname + '/fixtures/dead-code-injection.js');
  110. obfuscatedCode = JavaScriptObfuscator.obfuscate(
  111. code,
  112. {
  113. ...NO_ADDITIONAL_NODES_PRESET,
  114. deadCodeInjection: true,
  115. deadCodeInjectionThreshold: 1
  116. }
  117. ).getObfuscatedCode();
  118. const obfuscatedFunctionExpressionMatches: RegExpMatchArray | null = obfuscatedCode.match(
  119. obfuscatedFunctionExpressionRegExp
  120. );
  121. const obfuscatedFunctionCallMatches: RegExpMatchArray | null = obfuscatedCode.match(
  122. obfuscatedFunctionCallRegExp
  123. );
  124. obfuscatedFunctionExpressionMatchesLength = obfuscatedFunctionExpressionMatches
  125. ? obfuscatedFunctionExpressionMatches.length
  126. : 0;
  127. obfuscatedFunctionCallMatchesLength = obfuscatedFunctionCallMatches
  128. ? obfuscatedFunctionCallMatches.length
  129. : 0;
  130. });
  131. it('match #1: should ignore function expression after `disable` conditional comment', () => {
  132. assert.match(obfuscatedCode, ignoredFunctionExpression1RegExp);
  133. });
  134. it('match #2: should ignore function expression after `disable` conditional comment', () => {
  135. assert.match(obfuscatedCode, ignoredFunctionExpression2RegExp);
  136. });
  137. it('match #3: should ignore function expression call', () => {
  138. assert.match(obfuscatedCode, ignoredFunctionCall1RegExp);
  139. });
  140. it('match #4: should ignore function expression call', () => {
  141. assert.match(obfuscatedCode, ignoredFunctionCall2RegExp);
  142. });
  143. it('should obfuscate 3 function expressions', () => {
  144. assert.equal(obfuscatedFunctionExpressionMatchesLength, expectedObfuscatedFunctionExpressionLength);
  145. });
  146. it('should obfuscate 3 function expression calls', () => {
  147. assert.equal(obfuscatedFunctionCallMatchesLength, expectedObfuscatedFunctionCallsLength);
  148. });
  149. });
  150. describe('Variant #6: `disable` and `enable` conditional comments with control flow flattening', () => {
  151. const obfuscatedVariableDeclarationRegExp: RegExp = /var _0x([a-f0-9]){4,6} *= *_0x([a-f0-9]){4,6}\['[a-zA-Z0-9]{1,5}'];/;
  152. const ignoredVariableDeclarationRegExp: RegExp = /var bar *= *'bar';/;
  153. let obfuscatedCode: string;
  154. beforeEach(() => {
  155. const code: string = readFileAsString(__dirname + '/fixtures/control-flow-flattening.js');
  156. obfuscatedCode = JavaScriptObfuscator.obfuscate(
  157. code,
  158. {
  159. ...NO_ADDITIONAL_NODES_PRESET,
  160. controlFlowFlattening: true,
  161. controlFlowFlatteningThreshold: 1
  162. }
  163. ).getObfuscatedCode();
  164. });
  165. it('match #1: should obfuscate variable declaration before `disable` conditional comment', () => {
  166. assert.match(obfuscatedCode, obfuscatedVariableDeclarationRegExp);
  167. });
  168. it('match #2: should ignore variable declaration after `disable` conditional comment', () => {
  169. assert.match(obfuscatedCode, ignoredVariableDeclarationRegExp);
  170. });
  171. });
  172. });
  173. });