LiteralTransformer.spec.ts 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. import { assert } from 'chai';
  2. import { IObfuscationResult } from '../../../../src/interfaces/IObfuscationResult';
  3. import { NO_CUSTOM_NODES_PRESET } from '../../../../src/options/presets/NoCustomNodes';
  4. import { readFileAsString } from '../../../helpers/readFileAsString';
  5. import { JavaScriptObfuscator } from '../../../../src/JavaScriptObfuscator';
  6. describe('LiteralTransformer', () => {
  7. describe('obfuscation of literal node with string value', () => {
  8. it('should replace literal node value with unicode escape sequence', () => {
  9. let obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
  10. `var test = 'test';`,
  11. {
  12. ...NO_CUSTOM_NODES_PRESET
  13. }
  14. );
  15. assert.match(obfuscationResult.getObfuscatedCode(), /^var *test *= *'\\x74\\x65\\x73\\x74';$/);
  16. });
  17. it('should replace literal node value with unicode escape sequence from string array', () => {
  18. let obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
  19. `var test = 'test';`,
  20. {
  21. ...NO_CUSTOM_NODES_PRESET,
  22. stringArray: true,
  23. stringArrayThreshold: 1
  24. }
  25. );
  26. assert.match(
  27. obfuscationResult.getObfuscatedCode(),
  28. /^var *_0x([a-z0-9]){4} *= *\['\\x74\\x65\\x73\\x74'\];/
  29. );
  30. assert.match(obfuscationResult.getObfuscatedCode(), /var *test *= *_0x([a-z0-9]){4}\('0x0'\);/);
  31. });
  32. it('should create only one item in string array for same literal node values', () => {
  33. let obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
  34. `
  35. var test = 'test';
  36. var test = 'test';
  37. object.test();
  38. `,
  39. {
  40. ...NO_CUSTOM_NODES_PRESET,
  41. stringArray: true,
  42. stringArrayThreshold: 1
  43. }
  44. );
  45. assert.match(
  46. obfuscationResult.getObfuscatedCode(),
  47. /^var *_0x([a-z0-9]){4} *= *\['\\x74\\x65\\x73\\x74'\];/
  48. );
  49. assert.match(obfuscationResult.getObfuscatedCode(), /var *test *= *_0x([a-z0-9]){4}\('0x0'\);/);
  50. });
  51. it('should replace literal node value with raw value from string array if `unicodeEscapeSequence` is disabled', () => {
  52. let obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
  53. `var test = 'test';`,
  54. {
  55. ...NO_CUSTOM_NODES_PRESET,
  56. stringArray: true,
  57. stringArrayThreshold: 1,
  58. unicodeEscapeSequence: false
  59. }
  60. );
  61. assert.match(
  62. obfuscationResult.getObfuscatedCode(),
  63. /^var *_0x([a-z0-9]){4} *= *\['test'\];/
  64. );
  65. assert.match(obfuscationResult.getObfuscatedCode(), /var *test *= *_0x([a-z0-9]){4}\('0x0'\);/);
  66. });
  67. it('should replace literal node value with raw value from string array if `unicodeEscapeSequence` and `stringArray` are disabled', () => {
  68. let obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
  69. `var test = 'test';`,
  70. {
  71. ...NO_CUSTOM_NODES_PRESET,
  72. unicodeEscapeSequence: false
  73. }
  74. );
  75. assert.match(
  76. obfuscationResult.getObfuscatedCode(),
  77. /^var *test *= *'test';/
  78. );
  79. });
  80. it('should\'t throw an error when string contains non-latin and non-digit characters and `unicodeEscapeSequence` is disabled', () => {
  81. assert.doesNotThrow(() => JavaScriptObfuscator.obfuscate(
  82. readFileAsString('./test/fixtures/node-transformers/obfuscation-transformers/literal-transformer-unicode-sequence.js'),
  83. {
  84. ...NO_CUSTOM_NODES_PRESET,
  85. stringArray: true,
  86. stringArrayThreshold: 1,
  87. unicodeEscapeSequence: false
  88. }
  89. ));
  90. });
  91. it('shouldn\'t replace short literal node value with value from string array', () => {
  92. let obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
  93. `var test = 'te';`,
  94. {
  95. ...NO_CUSTOM_NODES_PRESET,
  96. stringArray: true,
  97. stringArrayThreshold: 1
  98. }
  99. );
  100. assert.match(obfuscationResult.getObfuscatedCode(), /var *test *= *'\\x74\\x65';/);
  101. });
  102. it('should replace literal node value with value from string array encoded using base64', () => {
  103. let obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
  104. `var test = 'test';`,
  105. {
  106. ...NO_CUSTOM_NODES_PRESET,
  107. stringArray: true,
  108. stringArrayEncoding: 'base64',
  109. stringArrayThreshold: 1
  110. }
  111. );
  112. assert.match(
  113. obfuscationResult.getObfuscatedCode(),
  114. /^var *_0x([a-z0-9]){4} *= *\['\\x64\\x47\\x56\\x7a\\x64\\x41\\x3d\\x3d'\];/
  115. );
  116. assert.match(obfuscationResult.getObfuscatedCode(), /var *test *= *_0x([a-z0-9]){4}\('0x0'\);/);
  117. });
  118. it('should replace literal node value with value from string array encoded using rc4', () => {
  119. let obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
  120. `var test = 'test';`,
  121. {
  122. ...NO_CUSTOM_NODES_PRESET,
  123. stringArray: true,
  124. stringArrayEncoding: 'rc4',
  125. stringArrayThreshold: 1
  126. }
  127. );
  128. assert.match(
  129. obfuscationResult.getObfuscatedCode(),
  130. /var *test *= *_0x([a-z0-9]){4}\('0x0', '(\\x[a-f0-9]*){4}'\);/
  131. );
  132. });
  133. it('should replace literal node value with value from string array with `stringArrayThreshold` chance', () => {
  134. const samples: number = 1000;
  135. const stringArrayThreshold: number = 0.5;
  136. const delta: number = 0.1;
  137. const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
  138. `var test = 'test';\n`.repeat(samples),
  139. {
  140. ...NO_CUSTOM_NODES_PRESET,
  141. stringArray: true,
  142. stringArrayThreshold: stringArrayThreshold
  143. }
  144. );
  145. const regExp1: RegExp = /var *test *= *_0x([a-z0-9]){4}\('0x0'\);/g;
  146. const regExp2: RegExp = /var *test *= *'\\x74\\x65\\x73\\x74';/g;
  147. const stringArrayMatchesLength = obfuscationResult.getObfuscatedCode().match(regExp1)!.length;
  148. const noStringArrayMatchesLength = obfuscationResult.getObfuscatedCode().match(regExp2)!.length;
  149. assert.closeTo(stringArrayMatchesLength / samples, stringArrayThreshold, delta);
  150. assert.closeTo(noStringArrayMatchesLength / samples, stringArrayThreshold, delta);
  151. });
  152. });
  153. it('should obfuscate literal node with boolean value', () => {
  154. let obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
  155. `var test = true;`,
  156. {
  157. ...NO_CUSTOM_NODES_PRESET,
  158. stringArray: true,
  159. stringArrayThreshold: 1
  160. }
  161. );
  162. assert.match(obfuscationResult.getObfuscatedCode(), /^var *test *= *!!\[\];$/);
  163. });
  164. it('should obfuscate literal node with number value', () => {
  165. let obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
  166. `var test = 0;`,
  167. {
  168. ...NO_CUSTOM_NODES_PRESET,
  169. stringArray: true,
  170. stringArrayThreshold: 1
  171. }
  172. );
  173. assert.match(obfuscationResult.getObfuscatedCode(), /^var *test *= *0x0;$/);
  174. });
  175. });