js-confuser 1.7.0 → 1.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/CHANGELOG.md +57 -0
  2. package/README.md +12 -29
  3. package/dist/compiler.js +2 -8
  4. package/dist/constants.js +17 -10
  5. package/dist/index.js +7 -30
  6. package/dist/obfuscator.js +15 -62
  7. package/dist/options.js +21 -38
  8. package/dist/order.js +4 -7
  9. package/dist/parser.js +5 -13
  10. package/dist/precedence.js +6 -8
  11. package/dist/presets.js +4 -6
  12. package/dist/probability.js +13 -24
  13. package/dist/templates/bufferToString.js +100 -5
  14. package/dist/templates/crash.js +51 -9
  15. package/dist/templates/es5.js +125 -6
  16. package/dist/templates/functionLength.js +24 -6
  17. package/dist/templates/globals.js +9 -0
  18. package/dist/templates/template.js +71 -30
  19. package/dist/transforms/antiTooling.js +26 -22
  20. package/dist/transforms/calculator.js +18 -54
  21. package/dist/transforms/controlFlowFlattening/controlFlowFlattening.js +236 -333
  22. package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +46 -25
  23. package/dist/transforms/deadCode.js +528 -27
  24. package/dist/transforms/dispatcher.js +110 -108
  25. package/dist/transforms/es5/antiClass.js +70 -44
  26. package/dist/transforms/es5/antiDestructuring.js +14 -38
  27. package/dist/transforms/es5/antiES6Object.js +39 -48
  28. package/dist/transforms/es5/antiSpreadOperator.js +5 -14
  29. package/dist/transforms/es5/antiTemplate.js +10 -19
  30. package/dist/transforms/es5/es5.js +7 -40
  31. package/dist/transforms/extraction/classExtraction.js +83 -0
  32. package/dist/transforms/extraction/duplicateLiteralsRemoval.js +45 -79
  33. package/dist/transforms/extraction/objectExtraction.js +27 -54
  34. package/dist/transforms/finalizer.js +6 -20
  35. package/dist/transforms/flatten.js +51 -99
  36. package/dist/transforms/identifier/globalAnalysis.js +8 -26
  37. package/dist/transforms/identifier/globalConcealing.js +35 -54
  38. package/dist/transforms/identifier/movedDeclarations.js +66 -38
  39. package/dist/transforms/identifier/renameVariables.js +29 -68
  40. package/dist/transforms/identifier/variableAnalysis.js +21 -48
  41. package/dist/transforms/lock/antiDebug.js +20 -25
  42. package/dist/transforms/lock/integrity.js +48 -47
  43. package/dist/transforms/lock/lock.js +62 -113
  44. package/dist/transforms/minify.js +77 -108
  45. package/dist/transforms/opaquePredicates.js +11 -48
  46. package/dist/transforms/preparation.js +17 -50
  47. package/dist/transforms/renameLabels.js +5 -22
  48. package/dist/transforms/rgf.js +98 -66
  49. package/dist/transforms/shuffle.js +41 -46
  50. package/dist/transforms/stack.js +35 -98
  51. package/dist/transforms/string/encoding.js +73 -27
  52. package/dist/transforms/string/stringCompression.js +44 -68
  53. package/dist/transforms/string/stringConcealing.js +125 -134
  54. package/dist/transforms/string/stringEncoding.js +6 -26
  55. package/dist/transforms/string/stringSplitting.js +5 -30
  56. package/dist/transforms/transform.js +50 -100
  57. package/dist/traverse.js +11 -18
  58. package/dist/util/compare.js +27 -29
  59. package/dist/util/gen.js +32 -86
  60. package/dist/util/guard.js +0 -1
  61. package/dist/util/identifiers.js +11 -74
  62. package/dist/util/insert.js +27 -77
  63. package/dist/util/math.js +0 -3
  64. package/dist/util/object.js +3 -7
  65. package/dist/util/random.js +5 -36
  66. package/dist/util/scope.js +6 -3
  67. package/docs/ControlFlowFlattening.md +1 -1
  68. package/docs/ES5.md +197 -0
  69. package/package.json +3 -3
  70. package/src/constants.ts +12 -0
  71. package/src/options.ts +13 -0
  72. package/src/order.ts +2 -2
  73. package/src/templates/bufferToString.ts +49 -11
  74. package/src/templates/functionLength.ts +21 -3
  75. package/src/templates/globals.ts +3 -0
  76. package/src/templates/template.ts +85 -25
  77. package/src/transforms/antiTooling.ts +33 -11
  78. package/src/transforms/controlFlowFlattening/controlFlowFlattening.ts +2 -2
  79. package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +46 -10
  80. package/src/transforms/deadCode.ts +0 -16
  81. package/src/transforms/dispatcher.ts +101 -69
  82. package/src/transforms/es5/antiClass.ts +10 -1
  83. package/src/transforms/extraction/classExtraction.ts +168 -0
  84. package/src/transforms/extraction/duplicateLiteralsRemoval.ts +13 -10
  85. package/src/transforms/extraction/objectExtraction.ts +7 -14
  86. package/src/transforms/flatten.ts +20 -5
  87. package/src/transforms/identifier/globalConcealing.ts +29 -65
  88. package/src/transforms/identifier/movedDeclarations.ts +90 -24
  89. package/src/transforms/minify.ts +27 -12
  90. package/src/transforms/rgf.ts +103 -5
  91. package/src/transforms/stack.ts +12 -3
  92. package/src/transforms/string/encoding.ts +85 -51
  93. package/src/transforms/string/stringCompression.ts +5 -8
  94. package/src/transforms/string/stringConcealing.ts +139 -113
  95. package/src/transforms/string/stringEncoding.ts +1 -2
  96. package/src/transforms/string/stringSplitting.ts +1 -2
  97. package/src/transforms/transform.ts +30 -1
  98. package/src/util/compare.ts +39 -5
  99. package/src/util/gen.ts +10 -3
  100. package/src/util/identifiers.ts +6 -3
  101. package/src/util/insert.ts +17 -0
  102. package/src/util/scope.ts +14 -2
  103. package/test/code/Cash.test.ts +10 -4
  104. package/test/code/StrictMode.src.js +65 -0
  105. package/test/code/StrictMode.test.js +37 -0
  106. package/test/compare.test.ts +62 -2
  107. package/test/options.test.ts +111 -55
  108. package/test/transforms/controlFlowFlattening/expressionObfuscation.test.ts +37 -18
  109. package/test/transforms/dispatcher.test.ts +82 -0
  110. package/test/transforms/extraction/classExtraction.test.ts +86 -0
  111. package/test/transforms/extraction/duplicateLiteralsRemoval.test.ts +29 -8
  112. package/test/transforms/extraction/objectExtraction.test.ts +37 -15
  113. package/test/transforms/identifier/globalConcealing.test.ts +42 -2
  114. package/test/transforms/identifier/movedDeclarations.test.ts +61 -0
  115. package/test/transforms/lock/integrity.test.ts +24 -0
  116. package/test/transforms/minify.test.ts +37 -0
  117. package/test/transforms/rgf.test.ts +50 -0
  118. package/test/util/identifiers.test.ts +21 -0
  119. package/dist/transforms/controlFlowFlattening/choiceFlowObfuscation.js +0 -62
  120. package/dist/transforms/controlFlowFlattening/controlFlowObfuscation.js +0 -159
  121. package/dist/transforms/controlFlowFlattening/switchCaseObfuscation.js +0 -106
  122. package/dist/transforms/eval.js +0 -84
  123. package/dist/transforms/hexadecimalNumbers.js +0 -63
  124. package/dist/transforms/hideInitializingCode.js +0 -270
  125. package/dist/transforms/identifier/nameRecycling.js +0 -218
  126. package/dist/transforms/label.js +0 -67
  127. package/dist/transforms/preparation/nameConflicts.js +0 -116
  128. package/dist/transforms/preparation/preparation.js +0 -188
@@ -4,105 +4,92 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
-
8
7
  var _assert = require("assert");
9
-
10
8
  var _order = require("../../order");
11
-
12
9
  var _probability = require("../../probability");
13
-
14
10
  var _template = _interopRequireDefault(require("../../templates/template"));
15
-
16
11
  var _compare = require("../../util/compare");
17
-
18
12
  var _gen = require("../../util/gen");
19
-
20
13
  var _insert = require("../../util/insert");
21
-
22
14
  var _transform = _interopRequireDefault(require("../transform"));
23
-
24
- var _stringConcealing = require("./stringConcealing");
25
-
26
- var _random = require("../../util/random");
27
-
28
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
29
-
30
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
31
-
15
+ var _constants = require("../../constants");
16
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
17
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
18
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
19
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
32
20
  function LZ_encode(c) {
33
21
  (0, _assert.ok)(c);
34
22
  var x = "charCodeAt",
35
- b,
36
- e = {},
37
- f = c.split(""),
38
- d = [],
39
- a = f[0],
40
- g = 256;
41
-
23
+ b,
24
+ e = {},
25
+ f = c.split(""),
26
+ d = [],
27
+ a = f[0],
28
+ g = 256;
42
29
  for (b = 1; b < f.length; b++) c = f[b], null != e[a + c] ? a += c : (d.push(1 < a.length ? e[a] : a[x](0)), e[a + c] = g, g++, a = c);
43
-
44
30
  d.push(1 < a.length ? e[a] : a[x](0));
45
-
46
31
  for (b = 0; b < d.length; b++) d[b] = String.fromCharCode(d[b]);
47
-
48
32
  return d.join("");
49
33
  }
50
-
51
34
  function LZ_decode(b) {
52
35
  (0, _assert.ok)(b);
53
36
  var o,
54
- f,
55
- a,
56
- e = {},
57
- d = b.split(""),
58
- c = f = d[0],
59
- g = [c],
60
- h = o = 256;
61
-
37
+ f,
38
+ a,
39
+ e = {},
40
+ d = b.split(""),
41
+ c = f = d[0],
42
+ g = [c],
43
+ h = o = 256;
62
44
  for (var i = 1; i < d.length; i++) a = d[i].charCodeAt(0), a = h > a ? d[i] : e[a] ? e[a] : f + c, g.push(a), c = a.charAt(0), e[o] = f + c, o++, f = a;
63
-
64
45
  return g.join("");
65
46
  }
66
-
67
- const DecodeTemplate = (0, _template.default)("function {name}(b){\n var o,\n f,\n a,\n e = {},\n d = b.split(\"\"),\n c = (f = d[0]),\n g = [c],\n h = (o = 256);\n for (b = 1; b < d.length; b++)\n (a = d[b].charCodeAt(0)),\n (a = h > a ? d[b] : e[a] ? e[a] : f + c),\n g.push(a),\n (c = a.charAt(0)),\n (e[o] = f + c),\n o++,\n (f = a);\n return g.join(\"\").split(\"{delimiter}\");\n }");
68
-
47
+ const DecodeTemplate = (0, _template.default)(`function {name}(b){
48
+ var o,
49
+ f,
50
+ a,
51
+ e = {},
52
+ d = b.split(""),
53
+ c = (f = d[0]),
54
+ g = [c],
55
+ h = (o = 256);
56
+ for (b = 1; b < d.length; b++)
57
+ (a = d[b].charCodeAt(0)),
58
+ (a = h > a ? d[b] : e[a] ? e[a] : f + c),
59
+ g.push(a),
60
+ (c = a.charAt(0)),
61
+ (e[o] = f + c),
62
+ o++,
63
+ (f = a);
64
+ return g.join("").split("{delimiter}");
65
+ }`);
69
66
  class StringCompression extends _transform.default {
70
67
  constructor(o) {
71
68
  super(o, _order.ObfuscateOrder.StringCompression);
72
-
73
69
  _defineProperty(this, "map", void 0);
74
-
75
70
  _defineProperty(this, "ignore", void 0);
76
-
77
71
  _defineProperty(this, "string", void 0);
78
-
79
72
  _defineProperty(this, "delimiter", "|");
80
-
81
73
  _defineProperty(this, "fnName", void 0);
82
-
83
74
  this.map = new Map();
84
75
  this.ignore = new Set();
85
76
  this.string = "";
86
- this.fnName = this.getPlaceholder();
77
+ this.fnName = this.getPlaceholder() + _constants.predictableFunctionTag;
87
78
  }
88
-
89
79
  apply(tree) {
90
80
  super.apply(tree);
91
81
  this.string = this.string.slice(0, this.string.length - 1);
92
-
93
82
  if (!this.string.length) {
94
83
  return;
95
84
  }
96
-
97
85
  var split = this.getPlaceholder();
98
86
  var decoder = this.getPlaceholder();
99
- var getStringName = this.getPlaceholder();
100
- var encoded = LZ_encode(this.string);
87
+ var getStringName = this.getPlaceholder() + _constants.predictableFunctionTag; // Returns the string payload
101
88
 
89
+ var encoded = LZ_encode(this.string);
102
90
  if (LZ_decode(encoded) !== this.string) {
103
91
  this.error(new Error("String failed to be decoded. Try disabling the 'stringCompression' option."));
104
92
  }
105
-
106
93
  var getStringParamName = this.getPlaceholder();
107
94
  var decoderParamName = this.getPlaceholder();
108
95
  var callExpression = (0, _gen.CallExpression)((0, _gen.Identifier)(decoderParamName), [(0, _gen.CallExpression)((0, _gen.Identifier)(getStringParamName), [])]);
@@ -114,50 +101,39 @@ class StringCompression extends _transform.default {
114
101
  delimiter: this.delimiter
115
102
  }));
116
103
  }
117
-
118
104
  match(object, parents) {
119
- return object.type == "Literal" && typeof object.value === "string" && object.value && object.value.length > 3 && !(0, _compare.isDirective)(object, parents) && !(0, _stringConcealing.isModuleSource)(object, parents);
105
+ return object.type == "Literal" && typeof object.value === "string" && object.value && object.value.length > 3 && !(0, _compare.isDirective)(object, parents) && !(0, _compare.isModuleSource)(object, parents);
120
106
  }
121
-
122
107
  transform(object, parents) {
123
108
  if (!object.value) {
124
109
  return;
125
110
  }
126
-
127
111
  if (this.ignore.has(object.value) || object.value.includes(this.delimiter)) {
128
112
  return;
129
113
  }
130
-
131
114
  if (!parents[0] || parents[0].type == "CallExpression" && parents[0].callee.type == "Identifier" && parents[0].callee.name == this.fnName) {
132
115
  return;
133
116
  }
134
-
135
117
  if (!(0, _probability.ComputeProbabilityMap)(this.options.stringCompression, x => x, object.value)) {
136
118
  return;
137
- } // HARD CODED LIMIT of 10,000 (after 1,000 elements)
138
-
139
-
140
- if (this.map.size > 1000 && !(0, _random.chance)(this.map.size / 100)) return;
141
- var index = this.map.get(object.value); // New string, add it!
119
+ }
120
+ var index = this.map.get(object.value);
142
121
 
122
+ // New string, add it!
143
123
  if (typeof index !== "number") {
144
124
  // Ensure the string gets properly decoded
145
125
  if (LZ_decode(LZ_encode(object.value)) !== object.value) {
146
126
  this.ignore.add(object.value);
147
127
  return;
148
128
  }
149
-
150
129
  index = this.map.size;
151
130
  this.map.set(object.value, index);
152
131
  this.string += object.value + this.delimiter;
153
132
  }
154
-
155
133
  (0, _assert.ok)(typeof index === "number");
156
134
  return () => {
157
135
  this.replaceIdentifierOrLiteral(object, (0, _gen.CallExpression)((0, _gen.Identifier)(this.fnName), [(0, _gen.Literal)(index)]), parents);
158
136
  };
159
137
  }
160
-
161
138
  }
162
-
163
139
  exports.default = StringCompression;
@@ -4,236 +4,230 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
- exports.isModuleSource = isModuleSource;
8
-
9
7
  var _assert = require("assert");
10
-
11
8
  var _order = require("../../order");
12
-
13
9
  var _template = _interopRequireDefault(require("../../templates/template"));
14
-
15
10
  var _traverse = require("../../traverse");
16
-
17
11
  var _compare = require("../../util/compare");
18
-
19
12
  var _gen = require("../../util/gen");
20
-
21
13
  var _insert = require("../../util/insert");
22
-
23
14
  var _random = require("../../util/random");
24
-
25
15
  var _transform = _interopRequireDefault(require("../transform"));
26
-
27
- var _encoding = _interopRequireDefault(require("./encoding"));
28
-
16
+ var _encoding = require("./encoding");
29
17
  var _probability = require("../../probability");
30
-
31
18
  var _bufferToString = require("../../templates/bufferToString");
32
-
33
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
34
-
35
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
36
-
37
- function isModuleSource(object, parents) {
38
- if (!parents[0]) {
39
- return false;
40
- }
41
-
42
- if (parents[0].type == "ImportDeclaration" && parents[0].source == object) {
43
- return true;
44
- }
45
-
46
- if (parents[0].type == "ImportExpression" && parents[0].source == object) {
47
- return true;
48
- }
49
-
50
- if (parents[1] && parents[1].type == "CallExpression" && parents[1].arguments[0] === object && parents[1].callee.type == "Identifier") {
51
- if (parents[1].callee.name == "require" || parents[1].callee.name == "import") {
52
- return true;
53
- }
54
- }
55
-
56
- return false;
57
- }
58
-
19
+ var _constants = require("../../constants");
20
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
21
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
22
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
23
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
59
24
  class StringConcealing extends _transform.default {
60
25
  constructor(o) {
61
26
  super(o, _order.ObfuscateOrder.StringConcealing);
62
-
63
27
  _defineProperty(this, "arrayExpression", void 0);
64
-
65
28
  _defineProperty(this, "set", void 0);
66
-
67
29
  _defineProperty(this, "index", void 0);
68
-
30
+ // index, fnName, block
69
31
  _defineProperty(this, "arrayName", this.getPlaceholder());
70
-
71
32
  _defineProperty(this, "ignore", new Set());
72
-
73
33
  _defineProperty(this, "variablesMade", 1);
74
-
75
- _defineProperty(this, "encoding", Object.create(null));
76
-
77
34
  _defineProperty(this, "gen", void 0);
78
-
79
- _defineProperty(this, "hasAllEncodings", void 0);
80
-
35
+ _defineProperty(this, "functionObjects", []);
81
36
  this.set = new Set();
82
37
  this.index = Object.create(null);
83
38
  this.arrayExpression = (0, _gen.ArrayExpression)([]);
84
- this.hasAllEncodings = false;
85
- this.gen = this.getGenerator(); // Pad array with useless strings
39
+ this.gen = this.getGenerator();
40
+ }
41
+ apply(tree) {
42
+ super.apply(tree);
86
43
 
44
+ // Pad array with useless strings
87
45
  var dead = (0, _random.getRandomInteger)(5, 15);
88
-
89
46
  for (var i = 0; i < dead; i++) {
90
47
  var str = (0, _random.getRandomString)((0, _random.getRandomInteger)(5, 40));
91
- var fn = this.transform((0, _gen.Literal)(str), []);
92
-
48
+ var fn = this.transform((0, _gen.Literal)(str), [tree]);
93
49
  if (fn) {
94
50
  fn();
95
51
  }
96
52
  }
97
- }
98
-
99
- apply(tree) {
100
- super.apply(tree);
101
53
  var cacheName = this.getPlaceholder();
102
- var bufferToStringName = this.getPlaceholder(); // This helper functions convert UInt8 Array to UTf-string
54
+ var bufferToStringName = this.getPlaceholder() + _constants.predictableFunctionTag;
103
55
 
56
+ // This helper functions convert UInt8 Array to UTf-string
104
57
  (0, _insert.prepend)(tree, ..._bufferToString.BufferToStringTemplate.compile({
105
- name: bufferToStringName
58
+ name: bufferToStringName,
59
+ getGlobalFnName: this.getPlaceholder() + _constants.predictableFunctionTag
106
60
  }));
107
- Object.keys(this.encoding).forEach(type => {
61
+ for (var functionObject of this.functionObjects) {
108
62
  var {
109
- template
110
- } = _encoding.default[type];
111
- var decodeFn = this.getPlaceholder();
112
- var getterFn = this.encoding[type];
113
- (0, _insert.append)(tree, template.single({
114
- name: decodeFn,
115
- bufferToString: bufferToStringName
63
+ block,
64
+ fnName: getterFnName,
65
+ encodingImplementation
66
+ } = functionObject;
67
+ var decodeFn = this.getPlaceholder() + _constants.predictableFunctionTag + _constants.criticalFunctionTag;
68
+ (0, _insert.append)(block, encodingImplementation.template.single({
69
+ __fnName__: decodeFn,
70
+ __bufferToString__: bufferToStringName
116
71
  }));
117
- (0, _insert.append)(tree, (0, _template.default)("\n \n function ".concat(getterFn, "(x, y, z, a = ").concat(decodeFn, ", b = ").concat(cacheName, "){\n if ( z ) {\n return y[").concat(cacheName, "[z]] = ").concat(getterFn, "(x, y);\n } else if ( y ) {\n [b, y] = [a(b), x || z]\n }\n \n return y ? x[b[y]] : ").concat(cacheName, "[x] || (z=(b[x], a), ").concat(cacheName, "[x] = z(").concat(this.arrayName, "[x]))\n }\n \n ")).single());
118
- });
119
- var flowIntegrity = this.getPlaceholder();
120
- (0, _insert.prepend)(tree, (0, _gen.VariableDeclaration)([(0, _gen.VariableDeclarator)(cacheName, (0, _gen.ArrayExpression)([])), (0, _gen.VariableDeclarator)(flowIntegrity, (0, _gen.Literal)(0)), (0, _gen.VariableDeclarator)(this.arrayName, (0, _gen.CallExpression)((0, _gen.FunctionExpression)([], [(0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)("a", this.arrayExpression)), (0, _template.default)("return (".concat(flowIntegrity, " ? a[\"pop\"]() : ").concat(flowIntegrity, "++, a)")).single()]), []))]));
121
- }
72
+ // All these are fake and never ran
73
+ var ifStatements = (0, _template.default)(`if ( z == x ) {
74
+ return y[${cacheName}[z]] = ${getterFnName}(x, y);
75
+ }
76
+ if ( y ) {
77
+ [b, y] = [a(b), x || z]
78
+ return ${getterFnName}(x, b, z)
79
+ }
80
+ if ( z && a !== ${decodeFn} ) {
81
+ ${getterFnName} = ${decodeFn}
82
+ return ${getterFnName}(x, -1, z, a, b)
83
+ }
84
+ if ( a === ${getterFnName} ) {
85
+ ${decodeFn} = y
86
+ return ${decodeFn}(z)
87
+ }
88
+ if( a === undefined ) {
89
+ ${getterFnName} = b
90
+ }
91
+ if( z == a ) {
92
+ return y ? x[b[y]] : ${cacheName}[x] || (z=(b[x] || a), ${cacheName}[x] = z(${this.arrayName}[x]))
93
+ }
94
+ `).compile();
122
95
 
123
- match(object, parents) {
124
- return object.type == "Literal" && typeof object.value === "string" && object.value.length >= 3 && !isModuleSource(object, parents) && !(0, _compare.isDirective)(object, parents) //&&
96
+ // Not all fake if-statements are needed
97
+ ifStatements = ifStatements.filter(() => (0, _random.chance)(50));
125
98
 
126
- /*!parents.find((x) => x.$dispatcherSkip)*/
127
- ;
99
+ // This one is always used
100
+ ifStatements.push((0, _template.default)(`
101
+ if ( x !== y ) {
102
+ return b[x] || (b[x] = a(${this.arrayName}[x]))
103
+ }
104
+ `).single());
105
+ (0, _random.shuffle)(ifStatements);
106
+ var varDeclaration = (0, _template.default)(`
107
+ var ${getterFnName} = (x, y, z, a, b)=>{
108
+ if(typeof a === "undefined") {
109
+ a = ${decodeFn}
110
+ }
111
+ if(typeof b === "undefined") {
112
+ b = ${cacheName}
113
+ }
114
+ }
115
+ `).single();
116
+ varDeclaration.declarations[0].init.body.body.push(...ifStatements);
117
+ (0, _insert.prepend)(block, varDeclaration);
118
+ }
119
+ (0, _insert.prepend)(tree, (0, _gen.VariableDeclaration)([(0, _gen.VariableDeclarator)(cacheName, (0, _gen.ArrayExpression)([])), (0, _gen.VariableDeclarator)(this.arrayName, this.arrayExpression)]));
120
+ }
121
+ match(object, parents) {
122
+ return object.type == "Literal" && typeof object.value === "string" && object.value.length >= 3 && !(0, _compare.isModuleSource)(object, parents) && !(0, _compare.isDirective)(object, parents) //&&
123
+ /*!parents.find((x) => x.$dispatcherSkip)*/;
128
124
  }
129
-
130
125
  transform(object, parents) {
131
126
  return () => {
132
127
  // Empty strings are discarded
133
128
  if (!object.value || this.ignore.has(object.value) || object.value.length == 0) {
134
129
  return;
135
- } // Allow user to choose which strings get changed
136
-
130
+ }
137
131
 
132
+ // Allow user to choose which strings get changed
138
133
  if (!(0, _probability.ComputeProbabilityMap)(this.options.stringConcealing, x => x, object.value)) {
139
134
  return;
140
- } // HARD CODED LIMIT of 10,000 (after 1,000 elements)
141
-
142
-
143
- if (this.set.size > 1000 && !(0, _random.chance)(this.set.size / 100)) return;
144
- var types = Object.keys(this.encoding);
145
- var type = (0, _random.choice)(types);
146
-
147
- if (!type || !this.hasAllEncodings && (0, _random.chance)(10)) {
148
- var allowed = Object.keys(_encoding.default).filter(type => !this.encoding[type]);
149
-
150
- if (!allowed.length) {
151
- this.hasAllEncodings = true;
152
- } else {
153
- var random = (0, _random.choice)(allowed);
154
- type = random;
155
- this.encoding[random] = this.getPlaceholder();
156
- }
157
135
  }
158
-
159
- var fnName = this.encoding[type];
160
- var encoder = _encoding.default[type]; // The decode function must return correct result
161
-
162
- var encoded = encoder.encode(object.value);
163
-
164
- if (encoder.decode(encoded) != object.value) {
165
- this.ignore.add(object.value);
166
- this.warn(type, object.value.slice(0, 100));
167
- return;
136
+ var currentBlock = (0, _traverse.getBlock)(object, parents);
137
+
138
+ // Find created functions
139
+ var functionObjects = parents.filter(node => node.$stringConcealingFunctionObject).map(item => item.$stringConcealingFunctionObject);
140
+
141
+ // Choose random functionObject to use
142
+ var functionObject = (0, _random.choice)(functionObjects);
143
+ if (!functionObject || !(0, _encoding.hasAllEncodings)() && (0, _random.chance)(25 / this.functionObjects.length) && !currentBlock.$stringConcealingFunctionObject) {
144
+ // No functions, create one
145
+
146
+ var newFunctionObject = {
147
+ block: currentBlock,
148
+ encodingImplementation: (0, _encoding.createEncodingImplementation)(),
149
+ fnName: this.getPlaceholder() + _constants.predictableFunctionTag
150
+ };
151
+ this.functionObjects.push(newFunctionObject);
152
+ currentBlock.$stringConcealingFunctionObject = newFunctionObject;
153
+ functionObject = newFunctionObject;
168
154
  }
169
-
155
+ var {
156
+ fnName,
157
+ encodingImplementation
158
+ } = functionObject;
170
159
  var index = -1;
171
160
 
172
- if (!this.set.has(object.value)) {
161
+ // String already decoded?
162
+ if (this.set.has(object.value)) {
163
+ var row = this.index[object.value];
164
+ if (parents.includes(row[2])) {
165
+ [index, fnName] = row;
166
+ (0, _assert.ok)(typeof index === "number");
167
+ }
168
+ }
169
+ if (index == -1) {
170
+ // The decode function must return correct result
171
+ var encoded = encodingImplementation.encode(object.value);
172
+ if (encodingImplementation.decode(encoded) !== object.value) {
173
+ this.ignore.add(object.value);
174
+ this.warn(encodingImplementation.identity, object.value.slice(0, 100));
175
+ delete _encoding.EncodingImplementations[encodingImplementation.identity];
176
+ return;
177
+ }
173
178
  this.arrayExpression.elements.push((0, _gen.Literal)(encoded));
174
179
  index = this.arrayExpression.elements.length - 1;
175
- this.index[object.value] = [index, fnName];
180
+ this.index[object.value] = [index, fnName, currentBlock];
176
181
  this.set.add(object.value);
177
- } else {
178
- [index, fnName] = this.index[object.value];
179
- (0, _assert.ok)(typeof index === "number");
180
182
  }
181
-
182
183
  (0, _assert.ok)(index != -1, "index == -1");
183
- var callExpr = (0, _gen.CallExpression)((0, _gen.Identifier)(fnName), [(0, _gen.Literal)(index)]); // use `.apply` to fool automated de-obfuscators
184
+ var callExpr = (0, _gen.CallExpression)((0, _gen.Identifier)(fnName), [(0, _gen.Literal)(index)]);
184
185
 
186
+ // use `.apply` to fool automated de-obfuscators
185
187
  if ((0, _random.chance)(10)) {
186
188
  callExpr = (0, _gen.CallExpression)((0, _gen.MemberExpression)((0, _gen.Identifier)(fnName), (0, _gen.Literal)("apply"), true), [(0, _gen.Identifier)("undefined"), (0, _gen.ArrayExpression)([(0, _gen.Literal)(index)])]);
187
- } // use `.call`
189
+ }
190
+
191
+ // use `.call`
188
192
  else if ((0, _random.chance)(10)) {
189
193
  callExpr = (0, _gen.CallExpression)((0, _gen.MemberExpression)((0, _gen.Identifier)(fnName), (0, _gen.Literal)("call"), true), [(0, _gen.Identifier)("undefined"), (0, _gen.Literal)(index)]);
190
194
  }
191
-
192
195
  var referenceType = "call";
193
-
194
196
  if (parents.length && (0, _random.chance)(50 - this.variablesMade)) {
195
197
  referenceType = "constantReference";
196
198
  }
197
-
198
199
  var newExpr = callExpr;
199
-
200
200
  if (referenceType === "constantReference") {
201
201
  // Define the string earlier, reference the name here
202
202
  this.variablesMade++;
203
203
  var constantReferenceType = (0, _random.choice)(["variable", "array", "object"]);
204
- var place = (0, _random.choice)(parents.filter(node => (0, _traverse.isBlock)(node)));
205
-
204
+ var place = currentBlock;
206
205
  if (!place) {
207
206
  this.error(new Error("No lexical block to insert code"));
208
207
  }
209
-
210
208
  switch (constantReferenceType) {
211
209
  case "variable":
212
210
  var name = this.getPlaceholder();
213
211
  (0, _insert.prepend)(place, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(name, callExpr)));
214
212
  newExpr = (0, _gen.Identifier)(name);
215
213
  break;
216
-
217
214
  case "array":
218
215
  if (!place.$stringConcealingArray) {
219
216
  place.$stringConcealingArray = (0, _gen.ArrayExpression)([]);
220
217
  place.$stringConcealingArrayName = this.getPlaceholder();
221
218
  (0, _insert.prepend)(place, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(place.$stringConcealingArrayName, place.$stringConcealingArray)));
222
219
  }
223
-
224
220
  var arrayIndex = place.$stringConcealingArray.elements.length;
225
221
  place.$stringConcealingArray.elements.push(callExpr);
226
222
  var memberExpression = (0, _gen.MemberExpression)((0, _gen.Identifier)(place.$stringConcealingArrayName), (0, _gen.Literal)(arrayIndex), true);
227
223
  newExpr = memberExpression;
228
224
  break;
229
-
230
225
  case "object":
231
226
  if (!place.$stringConcealingObject) {
232
227
  place.$stringConcealingObject = (0, _gen.ObjectExpression)([]);
233
228
  place.$stringConcealingObjectName = this.getPlaceholder();
234
229
  (0, _insert.prepend)(place, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(place.$stringConcealingObjectName, place.$stringConcealingObject)));
235
230
  }
236
-
237
231
  var propName = this.gen.generate();
238
232
  var property = (0, _gen.Property)((0, _gen.Literal)(propName), callExpr, true);
239
233
  place.$stringConcealingObject.properties.push(property);
@@ -242,11 +236,8 @@ class StringConcealing extends _transform.default {
242
236
  break;
243
237
  }
244
238
  }
245
-
246
239
  this.replaceIdentifierOrLiteral(object, newExpr, parents);
247
240
  };
248
241
  }
249
-
250
242
  }
251
-
252
243
  exports.default = StringConcealing;
@@ -4,42 +4,28 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
-
8
7
  var _transform = _interopRequireDefault(require("../transform"));
9
-
10
8
  var _random = require("../../util/random");
11
-
12
9
  var _compare = require("../../util/compare");
13
-
14
- var _stringConcealing = require("./stringConcealing");
15
-
16
10
  var _probability = require("../../probability");
17
-
18
11
  var _gen = require("../../util/gen");
19
-
20
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
21
-
12
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
22
13
  function pad(x, len) {
23
14
  while (x.length < len) {
24
15
  x = "0" + x;
25
16
  }
26
-
27
17
  return x;
28
18
  }
29
-
30
19
  function even(x) {
31
20
  if (x.length % 2 != 0) {
32
21
  return "0" + x;
33
22
  }
34
-
35
23
  return x;
36
24
  }
37
-
38
25
  function toHexRepresentation(str) {
39
26
  var escapedString = "";
40
27
  str.split("").forEach(char => {
41
28
  var code = char.charCodeAt(0);
42
-
43
29
  if (code < 128) {
44
30
  escapedString += "\\x" + even(pad(code.toString(16), 2));
45
31
  } else {
@@ -48,12 +34,10 @@ function toHexRepresentation(str) {
48
34
  });
49
35
  return escapedString;
50
36
  }
51
-
52
37
  function toUnicodeRepresentation(str) {
53
38
  var escapedString = "";
54
39
  str.split("").forEach(char => {
55
40
  var code = char.charCodeAt(0);
56
-
57
41
  if (code < 128) {
58
42
  escapedString += "\\u" + even(pad(code.toString(16), 4));
59
43
  } else {
@@ -62,6 +46,7 @@ function toUnicodeRepresentation(str) {
62
46
  });
63
47
  return escapedString;
64
48
  }
49
+
65
50
  /**
66
51
  * [String Encoding](https://docs.jscrambler.com/code-integrity/documentation/transformations/string-encoding) transforms a string into an encoded representation.
67
52
  *
@@ -69,29 +54,24 @@ function toUnicodeRepresentation(str) {
69
54
  * - Resilience Low
70
55
  * - Cost Low
71
56
  */
72
-
73
-
74
57
  class StringEncoding extends _transform.default {
75
58
  constructor(o) {
76
59
  super(o);
77
60
  }
78
-
79
61
  match(object, parents) {
80
- return object.type == "Literal" && typeof object.value === "string" && object.value.length > 0 && !(0, _stringConcealing.isModuleSource)(object, parents) && !(0, _compare.isDirective)(object, parents);
62
+ return object.type == "Literal" && typeof object.value === "string" && object.value.length > 0 && !(0, _compare.isModuleSource)(object, parents) && !(0, _compare.isDirective)(object, parents);
81
63
  }
82
-
83
64
  transform(object, parents) {
84
65
  // Allow percentages
85
66
  if (!(0, _probability.ComputeProbabilityMap)(this.options.stringEncoding, x => x, object.value)) return;
86
67
  var type = (0, _random.choice)(["hexadecimal", "unicode"]);
87
68
  var escapedString = (type == "hexadecimal" ? toHexRepresentation : toUnicodeRepresentation)(object.value);
88
69
  return () => {
89
- if (object.type !== "Literal") return; // ESCodeGen tries to escape backslashes, here is a work-around
70
+ if (object.type !== "Literal") return;
90
71
 
91
- this.replace(object, (0, _gen.Identifier)("'".concat(escapedString, "'")));
72
+ // ESCodeGen tries to escape backslashes, here is a work-around
73
+ this.replace(object, (0, _gen.Identifier)(`'${escapedString}'`));
92
74
  };
93
75
  }
94
-
95
76
  }
96
-
97
77
  exports.default = StringEncoding;