js-confuser 1.5.8 → 1.5.9
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.
- package/CHANGELOG.md +37 -0
- package/dist/index.js +45 -4
- package/dist/obfuscator.js +10 -5
- package/dist/options.js +2 -3
- package/dist/order.js +3 -3
- package/dist/transforms/antiTooling.js +1 -1
- package/dist/transforms/controlFlowFlattening/expressionObfuscation.js +4 -2
- package/dist/transforms/dispatcher.js +3 -3
- package/dist/transforms/es5/antiClass.js +6 -2
- package/dist/transforms/es5/antiDestructuring.js +1 -1
- package/dist/transforms/eval.js +11 -0
- package/dist/transforms/extraction/duplicateLiteralsRemoval.js +4 -4
- package/dist/transforms/extraction/objectExtraction.js +6 -1
- package/dist/transforms/flatten.js +73 -50
- package/dist/transforms/hexadecimalNumbers.js +34 -9
- package/dist/transforms/identifier/movedDeclarations.js +1 -1
- package/dist/transforms/minify.js +22 -6
- package/dist/transforms/rgf.js +4 -4
- package/dist/transforms/stack.js +1 -1
- package/dist/transforms/string/stringConcealing.js +2 -2
- package/dist/traverse.js +0 -8
- package/dist/util/compare.js +2 -2
- package/dist/util/insert.js +20 -6
- package/package.json +1 -1
- package/src/index.ts +57 -19
- package/src/obfuscator.ts +6 -1
- package/src/options.ts +10 -2
- package/src/order.ts +3 -3
- package/src/transforms/antiTooling.ts +1 -1
- package/src/transforms/controlFlowFlattening/expressionObfuscation.ts +14 -2
- package/src/transforms/dispatcher.ts +4 -3
- package/src/transforms/es5/antiClass.ts +10 -1
- package/src/transforms/es5/antiDestructuring.ts +1 -1
- package/src/transforms/eval.ts +18 -0
- package/src/transforms/extraction/duplicateLiteralsRemoval.ts +5 -5
- package/src/transforms/extraction/objectExtraction.ts +12 -5
- package/src/transforms/flatten.ts +181 -128
- package/src/transforms/hexadecimalNumbers.ts +37 -9
- package/src/transforms/identifier/movedDeclarations.ts +1 -1
- package/src/transforms/minify.ts +37 -5
- package/src/transforms/rgf.ts +4 -3
- package/src/transforms/stack.ts +3 -1
- package/src/transforms/string/stringConcealing.ts +2 -2
- package/src/traverse.ts +1 -8
- package/src/types.ts +9 -1
- package/src/util/compare.ts +2 -2
- package/src/util/insert.ts +37 -8
- package/test/code/ES6.src.js +14 -0
- package/test/code/NewFeatures.test.ts +19 -0
- package/test/index.test.ts +13 -1
- package/test/transforms/antiTooling.test.ts +30 -0
- package/test/transforms/controlFlowFlattening/controlFlowFlattening.test.ts +22 -0
- package/test/transforms/dispatcher.test.ts +24 -0
- package/test/transforms/es5/antiClass.test.ts +33 -0
- package/test/transforms/eval.test.ts +53 -0
- package/test/transforms/extraction/objectExtraction.test.ts +21 -0
- package/test/transforms/flatten.test.ts +146 -3
- package/test/transforms/identifier/renameVariables.test.ts +26 -0
- package/test/transforms/minify.test.ts +66 -0
- package/test/transforms/rgf.test.ts +56 -0
- package/test/transforms/string/stringConcealing.test.ts +33 -0
- package/test/util/compare.test.ts +23 -1
|
@@ -21,6 +21,8 @@ var _assert = require("assert");
|
|
|
21
21
|
|
|
22
22
|
var _scope = require("../util/scope");
|
|
23
23
|
|
|
24
|
+
var _template = _interopRequireDefault(require("../templates/template"));
|
|
25
|
+
|
|
24
26
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
25
27
|
|
|
26
28
|
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; }
|
|
@@ -34,12 +36,13 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
|
|
|
34
36
|
* - `x['y']` **->** `x.y`
|
|
35
37
|
*/
|
|
36
38
|
class Minify extends _transform.default {
|
|
39
|
+
/**
|
|
40
|
+
* A helper function that is introduced preserve function semantics
|
|
41
|
+
*/
|
|
37
42
|
constructor(o) {
|
|
38
43
|
super(o, _order.ObfuscateOrder.Minify);
|
|
39
44
|
|
|
40
|
-
_defineProperty(this, "
|
|
41
|
-
|
|
42
|
-
this.variables = new Map();
|
|
45
|
+
_defineProperty(this, "arrowFunctionName", void 0);
|
|
43
46
|
}
|
|
44
47
|
|
|
45
48
|
match(object, parents) {
|
|
@@ -212,15 +215,28 @@ class Minify extends _transform.default {
|
|
|
212
215
|
});
|
|
213
216
|
|
|
214
217
|
if (canTransform) {
|
|
218
|
+
if (!this.arrowFunctionName) {
|
|
219
|
+
this.arrowFunctionName = this.getPlaceholder();
|
|
220
|
+
(0, _insert.append)(parents[parents.length - 1] || object, (0, _template.default)("\n function ".concat(this.arrowFunctionName, "(arrowFn){\n return function(){ return arrowFn(...arguments) }\n }\n ")).single());
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const wrap = object => {
|
|
224
|
+
return (0, _gen.CallExpression)((0, _gen.Identifier)(this.arrowFunctionName), [(0, _insert.clone)(object)]);
|
|
225
|
+
};
|
|
226
|
+
|
|
215
227
|
if (object.type == "FunctionExpression") {
|
|
216
228
|
object.type = "ArrowFunctionExpression";
|
|
229
|
+
this.replace(object, wrap((0, _insert.clone)(object)));
|
|
217
230
|
} else {
|
|
218
231
|
var arrow = { ...(0, _insert.clone)(object),
|
|
219
232
|
type: "ArrowFunctionExpression"
|
|
220
233
|
};
|
|
221
|
-
this.replace(object, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(object.id.name, arrow)));
|
|
234
|
+
this.replace(object, (0, _gen.VariableDeclaration)((0, _gen.VariableDeclarator)(object.id.name, wrap(arrow))));
|
|
222
235
|
var x = this.transform(arrow, []);
|
|
223
|
-
|
|
236
|
+
|
|
237
|
+
if (typeof x === "function") {
|
|
238
|
+
x();
|
|
239
|
+
}
|
|
224
240
|
}
|
|
225
241
|
}
|
|
226
242
|
};
|
|
@@ -372,7 +388,7 @@ class Minify extends _transform.default {
|
|
|
372
388
|
object.alternate = null;
|
|
373
389
|
}
|
|
374
390
|
|
|
375
|
-
if (object.consequent.body.length == 1 && object.alternate && object.alternate.body.length == 1) {
|
|
391
|
+
if (object.consequent && object.consequent.body && object.consequent.body.length == 1 && object.alternate && object.alternate.body.length == 1) {
|
|
376
392
|
var stmt1 = (0, _insert.clone)(object.consequent.body[0]);
|
|
377
393
|
var stmt2 = (0, _insert.clone)(object.alternate.body[0]); // if (a) {return b;} else {return c;} -> return a ? b : c;
|
|
378
394
|
|
package/dist/transforms/rgf.js
CHANGED
|
@@ -241,7 +241,8 @@ class RGF extends _transform.default {
|
|
|
241
241
|
// fn
|
|
242
242
|
// In most cases the identifier is being used like this (call expression, or referenced to be called later)
|
|
243
243
|
// Replace it with a simple wrapper function that will pass on the reference array
|
|
244
|
-
var conditionalExpression = (0, _gen.ConditionalExpression)((0, _template.default)("typeof ".concat(referenceArray, "[").concat(index, "] === \"function\" && ").concat(referenceArray, "[").concat(index, "][\"").concat(referenceSignatures[index] || "_", "\"]")).single().expression, (0, _gen.FunctionExpression)([], [(0, _gen.ReturnStatement)(
|
|
244
|
+
var conditionalExpression = (0, _gen.ConditionalExpression)((0, _template.default)("typeof ".concat(referenceArray, "[").concat(index, "] === \"function\" && ").concat(referenceArray, "[").concat(index, "][\"").concat(referenceSignatures[index] || "_", "\"]")).single().expression, (0, _gen.FunctionExpression)([], [(0, _gen.ReturnStatement)( // clone() is required!
|
|
245
|
+
(0, _gen.CallExpression)((0, _insert.clone)(memberExpression), [(0, _gen.Identifier)(referenceArray), (0, _gen.SpreadElement)((0, _gen.Identifier)("arguments"))]))]), memberExpression);
|
|
245
246
|
this.replace(o, conditionalExpression);
|
|
246
247
|
}
|
|
247
248
|
}
|
|
@@ -258,8 +259,6 @@ class RGF extends _transform.default {
|
|
|
258
259
|
|
|
259
260
|
let [object, parents] = _ref2;
|
|
260
261
|
var name = object === null || object === void 0 ? void 0 : (_object$id2 = object.id) === null || _object$id2 === void 0 ? void 0 : _object$id2.name;
|
|
261
|
-
var hasName = !!name;
|
|
262
|
-
var params = object.params.map(x => x.name) || [];
|
|
263
262
|
var signature = referenceSignatures[names.get(name)];
|
|
264
263
|
var embeddedName = name || this.getPlaceholder(); // Since `new Function` is completely isolated, create an entire new obfuscator and run remaining transformations.
|
|
265
264
|
// RGF runs early and needs completed code before converting to a string.
|
|
@@ -272,7 +271,8 @@ class RGF extends _transform.default {
|
|
|
272
271
|
integrity: false
|
|
273
272
|
},
|
|
274
273
|
eval: false,
|
|
275
|
-
hideInitializingCode: false
|
|
274
|
+
hideInitializingCode: false,
|
|
275
|
+
stringEncoding: false
|
|
276
276
|
});
|
|
277
277
|
var transforms = Object.values(obfuscator.transforms).filter(x => x.priority > this.priority);
|
|
278
278
|
var embeddedFunction = { ...object,
|
package/dist/transforms/stack.js
CHANGED
|
@@ -44,7 +44,7 @@ class Stack extends _transform.default {
|
|
|
44
44
|
return () => {
|
|
45
45
|
// Uncaught SyntaxError: Getter must not have any formal parameters.
|
|
46
46
|
// Uncaught SyntaxError: Setter must have exactly one formal parameter
|
|
47
|
-
var propIndex = parents.findIndex(x => x.type
|
|
47
|
+
var propIndex = parents.findIndex(x => x.type === "Property" || x.type === "MethodDefinition");
|
|
48
48
|
|
|
49
49
|
if (propIndex !== -1) {
|
|
50
50
|
if (parents[propIndex].value === (parents[propIndex - 1] || object)) {
|
|
@@ -166,10 +166,10 @@ class StringConcealing extends _transform.default {
|
|
|
166
166
|
var callExpr = (0, _gen.CallExpression)((0, _gen.Identifier)(fnName), [(0, _gen.Literal)(index)]); // use `.apply` to fool automated de-obfuscators
|
|
167
167
|
|
|
168
168
|
if (Math.random() > 0.5) {
|
|
169
|
-
callExpr = (0, _gen.CallExpression)((0, _gen.MemberExpression)((0, _gen.Identifier)(fnName), (0, _gen.Identifier)("apply"), false), [(0, _gen.
|
|
169
|
+
callExpr = (0, _gen.CallExpression)((0, _gen.MemberExpression)((0, _gen.Identifier)(fnName), (0, _gen.Identifier)("apply"), false), [(0, _gen.Identifier)("undefined"), (0, _gen.ArrayExpression)([(0, _gen.Literal)(index)])]);
|
|
170
170
|
} // use `.call`
|
|
171
171
|
else if (Math.random() > 0.5) {
|
|
172
|
-
callExpr = (0, _gen.CallExpression)((0, _gen.MemberExpression)((0, _gen.Identifier)(fnName), (0, _gen.Identifier)("call"), false), [(0, _gen.
|
|
172
|
+
callExpr = (0, _gen.CallExpression)((0, _gen.MemberExpression)((0, _gen.Identifier)(fnName), (0, _gen.Identifier)("call"), false), [(0, _gen.Identifier)("undefined"), (0, _gen.Literal)(index)]);
|
|
173
173
|
}
|
|
174
174
|
|
|
175
175
|
var referenceType = "call";
|
package/dist/traverse.js
CHANGED
|
@@ -40,15 +40,7 @@ function isBlock(object) {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
function walk(object, parents, onEnter) {
|
|
43
|
-
let seen = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : new Set();
|
|
44
|
-
|
|
45
43
|
if (typeof object === "object" && object) {
|
|
46
|
-
if (seen.has(object)) {
|
|
47
|
-
console.log(object);
|
|
48
|
-
throw new Error("Already seen: " + object.type);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
seen.add(object);
|
|
52
44
|
var newParents = [object, ...parents];
|
|
53
45
|
|
|
54
46
|
if (!Array.isArray(object)) {
|
package/dist/util/compare.js
CHANGED
|
@@ -59,8 +59,8 @@ function isValidIdentifier(name) {
|
|
|
59
59
|
return false;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
var x = name.match(/^[A-z$_][A-z0-9$_]*/);
|
|
63
|
-
return x && x[0] == name;
|
|
62
|
+
var x = name.match(/^[A-Za-z$_][A-Za-z0-9$_]*/);
|
|
63
|
+
return !!(x && x[0] == name);
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
function isInsideType(type, object, parents) {
|
package/dist/util/insert.js
CHANGED
|
@@ -139,8 +139,12 @@ function getDefiningContext(o, p) {
|
|
|
139
139
|
var variableDeclaration = p.find(x => x.type == "VariableDeclaration");
|
|
140
140
|
(0, _assert.ok)(variableDeclaration);
|
|
141
141
|
|
|
142
|
-
if (variableDeclaration.kind === "let") {
|
|
143
|
-
|
|
142
|
+
if (variableDeclaration.kind === "let" || variableDeclaration.kind === "const") {
|
|
143
|
+
var context = getVarContext(o, p);
|
|
144
|
+
|
|
145
|
+
if (context && context.type === "Program") {
|
|
146
|
+
return getLexContext(o, p);
|
|
147
|
+
}
|
|
144
148
|
}
|
|
145
149
|
}
|
|
146
150
|
|
|
@@ -287,15 +291,21 @@ function prepend(block) {
|
|
|
287
291
|
}
|
|
288
292
|
|
|
289
293
|
if (block.type == "Program") {
|
|
290
|
-
var
|
|
294
|
+
var moveBy = 0;
|
|
291
295
|
block.body.forEach((stmt, i) => {
|
|
292
296
|
if (stmt.type == "ImportDeclaration") {
|
|
293
|
-
if (
|
|
294
|
-
|
|
297
|
+
if (moveBy == i) {
|
|
298
|
+
moveBy++;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
if (stmt.type === "ExpressionStatement" && typeof stmt.directive === "string") {
|
|
303
|
+
if (moveBy == i) {
|
|
304
|
+
moveBy++;
|
|
295
305
|
}
|
|
296
306
|
}
|
|
297
307
|
});
|
|
298
|
-
block.body.splice(
|
|
308
|
+
block.body.splice(moveBy, 0, ...nodes);
|
|
299
309
|
} else {
|
|
300
310
|
getBlockBody(block).unshift(...nodes);
|
|
301
311
|
}
|
|
@@ -351,6 +361,10 @@ function isForInitialize(o, p) {
|
|
|
351
361
|
(0, _identifiers.validateChain)(o, p);
|
|
352
362
|
var forIndex = p.findIndex(x => x.type == "ForStatement" || x.type == "ForInStatement" || x.type == "ForOfStatement");
|
|
353
363
|
|
|
364
|
+
if (p.slice(0, forIndex).find(x => ["ArrowFunctionExpression", "BlockStatement"].includes(x.type))) {
|
|
365
|
+
return false;
|
|
366
|
+
}
|
|
367
|
+
|
|
354
368
|
if (forIndex !== -1) {
|
|
355
369
|
if (p[forIndex].type == "ForStatement") {
|
|
356
370
|
if (p[forIndex].init == (p[forIndex - 1] || o)) {
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -4,6 +4,7 @@ import Obfuscator from "./obfuscator";
|
|
|
4
4
|
import Transform from "./transforms/transform";
|
|
5
5
|
import { remove$Properties } from "./util/object";
|
|
6
6
|
import presets from "./presets";
|
|
7
|
+
import { performance } from "perf_hooks";
|
|
7
8
|
|
|
8
9
|
import * as assert from "assert";
|
|
9
10
|
import { correctOptions, ObfuscateOptions, validateOptions } from "./options";
|
|
@@ -85,8 +86,8 @@ var JsConfuser: IJsConfuser = async function (
|
|
|
85
86
|
return result;
|
|
86
87
|
} as any;
|
|
87
88
|
|
|
88
|
-
export
|
|
89
|
-
async function
|
|
89
|
+
export const debugTransformations: IJsConfuserDebugTransformations =
|
|
90
|
+
async function (
|
|
90
91
|
code: string,
|
|
91
92
|
options: ObfuscateOptions
|
|
92
93
|
): Promise<{ name: string; code: string; ms: number }[]> {
|
|
@@ -115,28 +116,65 @@ export var debugTransformations: IJsConfuserDebugTransformations =
|
|
|
115
116
|
return frames;
|
|
116
117
|
};
|
|
117
118
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
119
|
+
/**
|
|
120
|
+
* This method is used by the obfuscator website to display a progress bar and additional information
|
|
121
|
+
* about the obfuscation.
|
|
122
|
+
*
|
|
123
|
+
* @param code - Source code to obfuscate
|
|
124
|
+
* @param options - Options
|
|
125
|
+
* @param callback - Progress callback, called after each transformation
|
|
126
|
+
* @returns
|
|
127
|
+
*/
|
|
128
|
+
export const debugObfuscation: IJsConfuserDebugObfuscation = async function (
|
|
129
|
+
code: string,
|
|
130
|
+
options: ObfuscateOptions,
|
|
131
|
+
callback: (name: string, complete: number, totalTransforms: number) => void
|
|
132
|
+
) {
|
|
133
|
+
const startTime = performance.now();
|
|
126
134
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
var totalTransforms = obfuscator.array.length;
|
|
135
|
+
validateOptions(options);
|
|
136
|
+
options = await correctOptions(options);
|
|
130
137
|
|
|
131
|
-
|
|
132
|
-
callback(name, i, totalTransforms);
|
|
133
|
-
});
|
|
138
|
+
const beforeParseTime = performance.now();
|
|
134
139
|
|
|
135
|
-
|
|
140
|
+
var tree = parseSync(code);
|
|
141
|
+
|
|
142
|
+
const parseTime = performance.now() - beforeParseTime;
|
|
143
|
+
|
|
144
|
+
var obfuscator = new Obfuscator(options);
|
|
145
|
+
var totalTransforms = obfuscator.array.length;
|
|
146
|
+
|
|
147
|
+
var transformationTimes = Object.create(null);
|
|
148
|
+
var currentTransformTime = performance.now();
|
|
149
|
+
|
|
150
|
+
obfuscator.on("debug", (name: string, tree: Node, i: number) => {
|
|
151
|
+
var nowTime = performance.now();
|
|
152
|
+
transformationTimes[name] = nowTime - currentTransformTime;
|
|
153
|
+
currentTransformTime = nowTime;
|
|
154
|
+
|
|
155
|
+
callback(name, i, totalTransforms);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
await obfuscator.apply(tree, true);
|
|
159
|
+
|
|
160
|
+
const beforeCompileTime = performance.now();
|
|
161
|
+
|
|
162
|
+
var output = await compileJs(tree, options);
|
|
163
|
+
|
|
164
|
+
const compileTime = performance.now() - beforeCompileTime;
|
|
165
|
+
|
|
166
|
+
const endTime = performance.now();
|
|
136
167
|
|
|
137
|
-
|
|
138
|
-
|
|
168
|
+
return {
|
|
169
|
+
obfuscated: output,
|
|
170
|
+
transformationTimes: transformationTimes,
|
|
171
|
+
obfuscationTime: endTime - startTime,
|
|
172
|
+
parseTime: parseTime,
|
|
173
|
+
compileTime: compileTime,
|
|
174
|
+
totalTransforms: totalTransforms,
|
|
175
|
+
totalPossibleTransforms: obfuscator.totalPossibleTransforms,
|
|
139
176
|
};
|
|
177
|
+
};
|
|
140
178
|
|
|
141
179
|
JsConfuser.obfuscate = obfuscate;
|
|
142
180
|
JsConfuser.obfuscateAST = obfuscateAST;
|
package/src/obfuscator.ts
CHANGED
|
@@ -47,17 +47,22 @@ export default class Obfuscator extends EventEmitter {
|
|
|
47
47
|
state: "transform" | "eval" = "transform";
|
|
48
48
|
generated: Set<string>;
|
|
49
49
|
|
|
50
|
+
totalPossibleTransforms: number;
|
|
51
|
+
|
|
50
52
|
constructor(public options: ObfuscateOptions) {
|
|
51
53
|
super();
|
|
52
54
|
|
|
53
55
|
this.varCount = 0;
|
|
54
56
|
this.transforms = Object.create(null);
|
|
55
57
|
this.generated = new Set();
|
|
58
|
+
this.totalPossibleTransforms = 0;
|
|
56
59
|
|
|
57
60
|
this.push(new Preparation(this));
|
|
58
61
|
this.push(new RenameLabels(this));
|
|
59
62
|
|
|
60
63
|
const test = <T>(map: ProbabilityMap<T>, ...transformers: any[]) => {
|
|
64
|
+
this.totalPossibleTransforms += transformers.length;
|
|
65
|
+
|
|
61
66
|
if (isProbabilityMapProbable(map)) {
|
|
62
67
|
// options.verbose && console.log("+ Added " + transformer.name);
|
|
63
68
|
|
|
@@ -97,7 +102,7 @@ export default class Obfuscator extends EventEmitter {
|
|
|
97
102
|
test(options.stack, Stack);
|
|
98
103
|
test(true, AntiTooling);
|
|
99
104
|
test(options.hideInitializingCode, HideInitializingCode);
|
|
100
|
-
test(
|
|
105
|
+
test(true, HexadecimalNumbers); // BigInt support is included
|
|
101
106
|
|
|
102
107
|
if (
|
|
103
108
|
options.lock &&
|
package/src/options.ts
CHANGED
|
@@ -867,8 +867,7 @@ export async function correctOptions(
|
|
|
867
867
|
options.compact = true; // self defending forcibly enables this
|
|
868
868
|
}
|
|
869
869
|
|
|
870
|
-
// options.globalVariables
|
|
871
|
-
// GlobalConcealing implicitly determines a global to be a variable referenced but never defined or modified.
|
|
870
|
+
// options.globalVariables outlines generic globals that should be present in the execution context
|
|
872
871
|
if (!options.hasOwnProperty("globalVariables")) {
|
|
873
872
|
options.globalVariables = new Set([]);
|
|
874
873
|
|
|
@@ -908,6 +907,10 @@ export async function correctOptions(
|
|
|
908
907
|
"Array",
|
|
909
908
|
"Proxy",
|
|
910
909
|
"Error",
|
|
910
|
+
"TypeError",
|
|
911
|
+
"ReferenceError",
|
|
912
|
+
"RangeError",
|
|
913
|
+
"EvalError",
|
|
911
914
|
"setTimeout",
|
|
912
915
|
"clearTimeout",
|
|
913
916
|
"setInterval",
|
|
@@ -919,6 +922,11 @@ export async function correctOptions(
|
|
|
919
922
|
"module",
|
|
920
923
|
"isNaN",
|
|
921
924
|
"isFinite",
|
|
925
|
+
"Set",
|
|
926
|
+
"Map",
|
|
927
|
+
"WeakSet",
|
|
928
|
+
"WeakMap",
|
|
929
|
+
"Symbol",
|
|
922
930
|
].forEach((x) => options.globalVariables.add(x));
|
|
923
931
|
}
|
|
924
932
|
|
package/src/order.ts
CHANGED
|
@@ -20,7 +20,13 @@ export default class ExpressionObfuscation extends Transform {
|
|
|
20
20
|
if (stmt.type == "ExpressionStatement") {
|
|
21
21
|
var expr = stmt.expression;
|
|
22
22
|
|
|
23
|
-
if (
|
|
23
|
+
if (
|
|
24
|
+
expr.type == "UnaryExpression" &&
|
|
25
|
+
!(
|
|
26
|
+
expr.operator === "typeof" && expr.argument.type === "Identifier"
|
|
27
|
+
) &&
|
|
28
|
+
exprs.length // typeof is special
|
|
29
|
+
) {
|
|
24
30
|
expr.argument = SequenceExpression([
|
|
25
31
|
...exprs,
|
|
26
32
|
{ ...expr.argument },
|
|
@@ -38,7 +44,13 @@ export default class ExpressionObfuscation extends Transform {
|
|
|
38
44
|
stmt.test.type == "BinaryExpression" &&
|
|
39
45
|
stmt.test.operator !== "**"
|
|
40
46
|
) {
|
|
41
|
-
if (
|
|
47
|
+
if (
|
|
48
|
+
stmt.test.left.type == "UnaryExpression" &&
|
|
49
|
+
!(
|
|
50
|
+
stmt.test.left.operator === "typeof" &&
|
|
51
|
+
stmt.test.left.argument.type === "Identifier"
|
|
52
|
+
) // typeof is special
|
|
53
|
+
) {
|
|
42
54
|
stmt.test.left.argument = SequenceExpression([
|
|
43
55
|
...exprs,
|
|
44
56
|
{ ...stmt.test.left.argument },
|
|
@@ -97,14 +97,15 @@ export default class Dispatcher extends Transform {
|
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
// Map of FunctionDeclarations
|
|
100
|
-
var functionDeclarations: { [name: string]: Location } =
|
|
100
|
+
var functionDeclarations: { [name: string]: Location } =
|
|
101
|
+
Object.create(null);
|
|
101
102
|
|
|
102
103
|
// Array of Identifier nodes
|
|
103
104
|
var identifiers: Location[] = [];
|
|
104
105
|
var illegalFnNames: Set<string> = new Set();
|
|
105
106
|
|
|
106
107
|
// New Names for Functions
|
|
107
|
-
var newFnNames: { [name: string]: string } =
|
|
108
|
+
var newFnNames: { [name: string]: string } = Object.create(null); // [old name]: randomized name
|
|
108
109
|
|
|
109
110
|
var context = isVarContext(object)
|
|
110
111
|
? object
|
|
@@ -469,7 +470,7 @@ export default class Dispatcher extends Transform {
|
|
|
469
470
|
}
|
|
470
471
|
|
|
471
472
|
var newName = newFnNames[o.name];
|
|
472
|
-
if (!newName) {
|
|
473
|
+
if (!newName || typeof newName !== "string") {
|
|
473
474
|
return;
|
|
474
475
|
}
|
|
475
476
|
|
|
@@ -110,7 +110,16 @@ export default class AntiClass extends Transform {
|
|
|
110
110
|
);
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
|
|
113
|
+
// Support class fields
|
|
114
|
+
if (methodDefinition.type === "PropertyDefinition") {
|
|
115
|
+
var assignmentExpression = AssignmentExpression(
|
|
116
|
+
"=",
|
|
117
|
+
key,
|
|
118
|
+
value || Identifier("undefined")
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
pushingTo.push(ExpressionStatement(assignmentExpression));
|
|
122
|
+
} else if (
|
|
114
123
|
methodDefinition.kind == "constructor" ||
|
|
115
124
|
methodDefinition.kind == "method"
|
|
116
125
|
) {
|
|
@@ -266,7 +266,7 @@ export default class AntiDestructuring extends Transform {
|
|
|
266
266
|
]);
|
|
267
267
|
|
|
268
268
|
if (object.type == "VariableDeclarator") {
|
|
269
|
-
var i = getIndexDirect(object, parents);
|
|
269
|
+
var i = getIndexDirect(object, parents[0]);
|
|
270
270
|
|
|
271
271
|
var extra = Array.from(names).map((x) => {
|
|
272
272
|
return {
|
package/src/transforms/eval.ts
CHANGED
|
@@ -28,6 +28,24 @@ export default class Eval extends Transform {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
transform(object, parents) {
|
|
31
|
+
// Don't apply to getter/setters or class methods
|
|
32
|
+
if (parents[0]) {
|
|
33
|
+
if (
|
|
34
|
+
parents[0].type === "MethodDefinition" &&
|
|
35
|
+
parents[0].value === object
|
|
36
|
+
) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (
|
|
41
|
+
parents[0].type === "Property" &&
|
|
42
|
+
parents[0].value === object &&
|
|
43
|
+
(parents[0].kind !== "init" || parents[0].method)
|
|
44
|
+
) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
31
49
|
if (
|
|
32
50
|
!ComputeProbabilityMap(
|
|
33
51
|
this.options.eval,
|
|
@@ -159,7 +159,7 @@ export default class DuplicateLiteralsRemoval extends Transform {
|
|
|
159
159
|
var body = [];
|
|
160
160
|
var thisShift = getRandomInteger(-250, 250);
|
|
161
161
|
// the name of the getter
|
|
162
|
-
getterName = this.getPlaceholder();
|
|
162
|
+
getterName = this.getPlaceholder() + "_dLR_" + this.fnGetters.size;
|
|
163
163
|
|
|
164
164
|
if (basedOn) {
|
|
165
165
|
var shift = this.fnShifts.get(basedOn);
|
|
@@ -268,20 +268,20 @@ export default class DuplicateLiteralsRemoval extends Transform {
|
|
|
268
268
|
this.arrayExpression = ArrayExpression([]);
|
|
269
269
|
}
|
|
270
270
|
|
|
271
|
-
var
|
|
272
|
-
if (
|
|
271
|
+
var firstLocation = this.first.get(value);
|
|
272
|
+
if (firstLocation) {
|
|
273
273
|
this.first.set(value, null);
|
|
274
274
|
var index = this.map.size;
|
|
275
275
|
|
|
276
276
|
ok(!this.map.has(value));
|
|
277
277
|
this.map.set(value, index);
|
|
278
278
|
|
|
279
|
-
this.toCaller(first[0], first[1], index);
|
|
280
|
-
|
|
281
279
|
var pushing = clone(object);
|
|
282
280
|
this.arrayExpression.elements.push(pushing);
|
|
283
281
|
|
|
284
282
|
ok(this.arrayExpression.elements[index] === pushing);
|
|
283
|
+
|
|
284
|
+
this.toCaller(firstLocation[0], firstLocation[1], index);
|
|
285
285
|
}
|
|
286
286
|
|
|
287
287
|
var index = this.map.get(value);
|
|
@@ -100,11 +100,18 @@ export default class ObjectExtraction extends Transform {
|
|
|
100
100
|
);
|
|
101
101
|
|
|
102
102
|
if (nonInitOrComputed) {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
103
|
+
if (nonInitOrComputed.key) {
|
|
104
|
+
this.log(
|
|
105
|
+
name +
|
|
106
|
+
" has non-init/computed property: " +
|
|
107
|
+
nonInitOrComputed.key.name || nonInitOrComputed.key.value
|
|
108
|
+
);
|
|
109
|
+
} else {
|
|
110
|
+
this.log(
|
|
111
|
+
name + " has spread-element or other type of property"
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
108
115
|
illegal.add(name);
|
|
109
116
|
return;
|
|
110
117
|
} else {
|