DebugProtectionFunctionCallTemplate.spec.ts 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. import { assert } from 'chai';
  2. import { spawn, Thread, Worker } from 'threads/dist';
  3. import { readFileAsString } from '../../../../helpers/readFileAsString';
  4. import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../src/options/presets/NoCustomNodes';
  5. import { IdentifierNamesGenerator } from '../../../../../src/enums/generators/identifier-names-generators/IdentifierNamesGenerator';
  6. import { ObfuscationTarget } from '../../../../../src/enums/ObfuscationTarget';
  7. import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
  8. async function spawnThread(obfuscatedCode: string, threadCallback: Function, timeoutCallback: Function): Promise<void> {
  9. const evaluationWorker = await spawn(new Worker('./workers/evaluation-worker'));
  10. const timeout = setTimeout(() => {
  11. Thread.terminate(evaluationWorker);
  12. timeoutCallback();
  13. }, 1500);
  14. const result: string = await evaluationWorker.evaluate(obfuscatedCode);
  15. clearTimeout(timeout);
  16. Thread.terminate(evaluationWorker);
  17. threadCallback(result);
  18. }
  19. describe('DebugProtectionFunctionCallTemplate', function () {
  20. this.timeout(10000);
  21. describe('Variant #1: correctly obfuscate code with `HexadecimalIdentifierNamesGenerator``', () => {
  22. const expectedEvaluationResult: number = 1;
  23. let obfuscatedCode: string,
  24. evaluationResult: number = 0;
  25. beforeEach((done) => {
  26. const code: string = readFileAsString(__dirname + '/fixtures/input.js');
  27. obfuscatedCode = JavaScriptObfuscator.obfuscate(
  28. code,
  29. {
  30. ...NO_ADDITIONAL_NODES_PRESET,
  31. debugProtection: true,
  32. identifierNamesGenerator: IdentifierNamesGenerator.HexadecimalIdentifierNamesGenerator
  33. }
  34. ).getObfuscatedCode();
  35. spawnThread(
  36. obfuscatedCode,
  37. (response: number) => {
  38. evaluationResult = response;
  39. done();
  40. },
  41. () => {
  42. done();
  43. }
  44. );
  45. });
  46. it('should correctly evaluate code with enabled debug protection', () => {
  47. assert.equal(evaluationResult, expectedEvaluationResult);
  48. });
  49. });
  50. describe('Variant #2: correctly obfuscate code with `MangledIdentifierNamesGenerator` option', () => {
  51. const expectedEvaluationResult: number = 1;
  52. let obfuscatedCode: string,
  53. evaluationResult: number = 0;
  54. beforeEach((done) => {
  55. const code: string = readFileAsString(__dirname + '/fixtures/input.js');
  56. obfuscatedCode = JavaScriptObfuscator.obfuscate(
  57. code,
  58. {
  59. ...NO_ADDITIONAL_NODES_PRESET,
  60. debugProtection: true,
  61. identifierNamesGenerator: IdentifierNamesGenerator.MangledIdentifierNamesGenerator
  62. }
  63. ).getObfuscatedCode();
  64. spawnThread(
  65. obfuscatedCode,
  66. (response: number) => {
  67. evaluationResult = response;
  68. done();
  69. },
  70. () => {
  71. done();
  72. }
  73. );
  74. });
  75. it('should correctly evaluate code with enabled debug protection', () => {
  76. assert.equal(evaluationResult, expectedEvaluationResult);
  77. });
  78. });
  79. describe('Variant #3: correctly obfuscate code with `DictionaryIdentifierNamesGenerator` option', () => {
  80. const expectedEvaluationResult: number = 1;
  81. let obfuscatedCode: string,
  82. evaluationResult: number = 0;
  83. beforeEach((done) => {
  84. const code: string = readFileAsString(__dirname + '/fixtures/input.js');
  85. obfuscatedCode = JavaScriptObfuscator.obfuscate(
  86. code,
  87. {
  88. ...NO_ADDITIONAL_NODES_PRESET,
  89. debugProtection: true,
  90. identifierNamesGenerator: IdentifierNamesGenerator.DictionaryIdentifierNamesGenerator,
  91. identifiersDictionary: ['foo', 'bar', 'baz', 'bark', 'hawk', 'eagle']
  92. }
  93. ).getObfuscatedCode();
  94. spawnThread(
  95. obfuscatedCode,
  96. (response: number) => {
  97. evaluationResult = response;
  98. done();
  99. },
  100. () => {
  101. done();
  102. }
  103. );
  104. });
  105. it('should correctly evaluate code with enabled debug protection', () => {
  106. assert.equal(evaluationResult, expectedEvaluationResult);
  107. });
  108. });
  109. describe('Variant #4: correctly obfuscated code with target `BrowserNoEval`', () => {
  110. const expectedEvaluationResult: number = 1;
  111. let obfuscatedCode: string,
  112. evaluationResult: number = 0;
  113. beforeEach((done) => {
  114. const code: string = readFileAsString(__dirname + '/fixtures/input.js');
  115. obfuscatedCode = JavaScriptObfuscator.obfuscate(
  116. code,
  117. {
  118. ...NO_ADDITIONAL_NODES_PRESET,
  119. debugProtection: true,
  120. target: ObfuscationTarget.BrowserNoEval
  121. }
  122. ).getObfuscatedCode();
  123. spawnThread(
  124. obfuscatedCode,
  125. (response: number) => {
  126. evaluationResult = response;
  127. done();
  128. },
  129. () => {
  130. done();
  131. }
  132. );
  133. });
  134. it('should correctly evaluate code with enabled debug protection', () => {
  135. assert.equal(evaluationResult, expectedEvaluationResult);
  136. });
  137. });
  138. describe('Variant #5: obfuscated code with removed debug protection code', () => {
  139. const expectedEvaluationResult: number = 0;
  140. let obfuscatedCode: string,
  141. evaluationResult: number = 0;
  142. beforeEach((done) => {
  143. const code: string = readFileAsString(__dirname + '/fixtures/input.js');
  144. obfuscatedCode = JavaScriptObfuscator.obfuscate(
  145. code,
  146. {
  147. ...NO_ADDITIONAL_NODES_PRESET,
  148. debugProtection: true
  149. }
  150. ).getObfuscatedCode();
  151. obfuscatedCode = obfuscatedCode.replace(/\+\+ *_0x([a-f0-9]){4,6}/, '');
  152. spawnThread(
  153. obfuscatedCode,
  154. (response: number) => {
  155. evaluationResult = response;
  156. done();
  157. },
  158. () => {
  159. done();
  160. }
  161. );
  162. });
  163. it('should enter code in infinity loop', () => {
  164. assert.equal(evaluationResult, expectedEvaluationResult);
  165. });
  166. });
  167. describe('Variant #6: single call of debug protection code', () => {
  168. const expectedEvaluationResult: number = 1;
  169. let obfuscatedCode: string,
  170. evaluationResult: number = 0;
  171. beforeEach((done) => {
  172. const code: string = readFileAsString(__dirname + '/fixtures/single-call.js');
  173. obfuscatedCode = JavaScriptObfuscator.obfuscate(
  174. code,
  175. {
  176. ...NO_ADDITIONAL_NODES_PRESET,
  177. debugProtection: true
  178. }
  179. ).getObfuscatedCode();
  180. spawnThread(
  181. obfuscatedCode,
  182. (response: number) => {
  183. evaluationResult = response;
  184. done();
  185. },
  186. () => {
  187. done();
  188. }
  189. );
  190. });
  191. it('should correctly evaluate code with enabled debug protection', () => {
  192. assert.equal(evaluationResult, expectedEvaluationResult);
  193. });
  194. });
  195. });