ConditionalCommentObfuscatingGuard.spec.ts 9.2 KB

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