@dacely/toildefender 0.1.3 → 0.1.5
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/README.md +86 -57
- package/docs/all-modes-output.demo.js +1016 -670
- package/esutils.js +11 -1
- package/obfuscator.js +194 -23
- package/package.json +3 -26
- package/processors/deadCode.js +5 -1
- package/processors/flattener.js +56 -32
- package/processors/identifiers.js +9 -15
- package/processors/methods.js +109 -7
- package/processors/normalizer.js +946 -22
- package/processors/numericVm.js +179 -77
- package/processors/scopes.js +25 -0
- package/processors/variables.js +86 -2
- package/traverser.js +8 -2
package/processors/methods.js
CHANGED
|
@@ -18,7 +18,14 @@ function veilmark$sliceArguments(args, num) {
|
|
|
18
18
|
return Array.prototype.slice.call(args, num);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
var veilmark$objectKeys = {};
|
|
22
|
+
|
|
23
|
+
function veilmark$toObject(cacheKey, schema, values) {
|
|
24
|
+
if (values === undefined && Array.isArray(cacheKey)) {
|
|
25
|
+
values = schema;
|
|
26
|
+
schema = cacheKey;
|
|
27
|
+
cacheKey = "";
|
|
28
|
+
}
|
|
22
29
|
var obj = {};
|
|
23
30
|
if (values === undefined) {
|
|
24
31
|
for (var legacy = 0; legacy < schema.length; legacy += 2) {
|
|
@@ -26,20 +33,45 @@ function veilmark$toObject(schema, values) {
|
|
|
26
33
|
}
|
|
27
34
|
return obj;
|
|
28
35
|
}
|
|
36
|
+
var decoded = cacheKey ? veilmark$objectKeys[cacheKey] : null;
|
|
37
|
+
if (decoded) {
|
|
38
|
+
for (var cached = 0; cached < decoded.length; cached += 1) {
|
|
39
|
+
obj[decoded[cached]] = values[cached];
|
|
40
|
+
}
|
|
41
|
+
return obj;
|
|
42
|
+
}
|
|
29
43
|
var cursor = 2;
|
|
30
44
|
var salt = schema[0];
|
|
31
45
|
var count = schema[1];
|
|
46
|
+
var keys = new Array(count);
|
|
32
47
|
for (var i = 0; i < count; i += 1) {
|
|
33
48
|
var len = schema[cursor++] ^ ((salt + i * 131) & 65535);
|
|
34
49
|
var key = "";
|
|
35
50
|
for (var j = 0; j < len; j += 1) {
|
|
36
51
|
key += String.fromCharCode(schema[cursor++] ^ ((salt + i * 257 + j * 17) & 65535));
|
|
37
52
|
}
|
|
53
|
+
keys[i] = key;
|
|
38
54
|
obj[key] = values[i];
|
|
39
55
|
}
|
|
56
|
+
if (cacheKey) {
|
|
57
|
+
veilmark$objectKeys[cacheKey] = keys;
|
|
58
|
+
}
|
|
40
59
|
return obj;
|
|
41
60
|
}
|
|
42
61
|
|
|
62
|
+
function veilmark$objectWithoutKeys(source, excluded) {
|
|
63
|
+
var target = {};
|
|
64
|
+
if (source == null) {
|
|
65
|
+
return target;
|
|
66
|
+
}
|
|
67
|
+
for (var key in source) {
|
|
68
|
+
if (Object.prototype.hasOwnProperty.call(source, key) && excluded.indexOf(key) < 0) {
|
|
69
|
+
target[key] = source[key];
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return target;
|
|
73
|
+
}
|
|
74
|
+
|
|
43
75
|
function veilmark$decodeString(arr) {
|
|
44
76
|
return arr.map(function(x) { return String.fromCharCode(x & ~0 >>> 16) + String.fromCharCode(x >> 16); }).join("");
|
|
45
77
|
}
|
|
@@ -94,6 +126,74 @@ function anonymousMethodName(node) {
|
|
|
94
126
|
return node[ANON_METHOD_ID];
|
|
95
127
|
}
|
|
96
128
|
|
|
129
|
+
function functionDeclarationName(node) {
|
|
130
|
+
assert.equal(node.type, "FunctionDeclaration");
|
|
131
|
+
|
|
132
|
+
if (!node.id || !node.id.name) {
|
|
133
|
+
if (!node[ANON_METHOD_ID]) {
|
|
134
|
+
Object.defineProperty(node, ANON_METHOD_ID, {
|
|
135
|
+
configurable: false,
|
|
136
|
+
enumerable: false,
|
|
137
|
+
value: `veilmark$anon$${utils.hash(node)}`
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
node.id = { type: "Identifier", name: node[ANON_METHOD_ID] };
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return node.id.name;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function isReferenceIdentifier(node, stack) {
|
|
147
|
+
var parentFrame = stack[1];
|
|
148
|
+
if (!parentFrame) {
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
var parent = parentFrame.node;
|
|
153
|
+
var key = parentFrame.key;
|
|
154
|
+
|
|
155
|
+
if ((parent.type == "FunctionDeclaration" || parent.type == "FunctionExpression") && (key == "id" || key == "params")) {
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
if (parent.type == "VariableDeclarator" && key == "id") {
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
if (parent.type == "CatchClause" && key == "param") {
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
if ((parent.type == "MemberExpression" || parent.type == "Property") && key == "property" && parent.computed === false) {
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
if (parent.type == "Property" && key == "key" && parent.computed === false) {
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
if ((parent.type == "LabeledStatement" || parent.type == "BreakStatement" || parent.type == "ContinueStatement") && key == "label") {
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return true;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function renameFunctionExpressionSelfReferences(node, name) {
|
|
178
|
+
assert.equal(node.type, "FunctionExpression");
|
|
179
|
+
|
|
180
|
+
if (!node.id || !node.id.name || node.id.name == name) {
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
var oldName = node.id.name;
|
|
185
|
+
traverser.traverse(node.body, [], (child, stack) => {
|
|
186
|
+
if (child.type == "Identifier" && child.name == oldName && isReferenceIdentifier(child, stack)) {
|
|
187
|
+
child.name = name;
|
|
188
|
+
}
|
|
189
|
+
return child;
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function isClassMethodFunction(stack) {
|
|
194
|
+
return stack.some(frame => frame.node.type == "MethodDefinition" || frame.node.type == "ClassBody");
|
|
195
|
+
}
|
|
196
|
+
|
|
97
197
|
/**
|
|
98
198
|
* Get index of argument in function.
|
|
99
199
|
* @param {Function} method Function
|
|
@@ -129,8 +229,7 @@ module.exports = class Methods {
|
|
|
129
229
|
assert.ok(estest.isNode(ast));
|
|
130
230
|
|
|
131
231
|
var code = esprima.parse(METHODS_INJECT);
|
|
132
|
-
|
|
133
|
-
ast.body.splice(0, 0, code);
|
|
232
|
+
ast.body.splice.apply(ast.body, [0, 0].concat(code.body));
|
|
134
233
|
}
|
|
135
234
|
|
|
136
235
|
/**
|
|
@@ -200,8 +299,8 @@ module.exports = class Methods {
|
|
|
200
299
|
|
|
201
300
|
traverser.traverse(ast, [], (node, stack) => {
|
|
202
301
|
if (node.type == "FunctionDeclaration") { // Statement
|
|
203
|
-
methods.push(node
|
|
204
|
-
} else if (node.type == "FunctionExpression") { // Expression
|
|
302
|
+
methods.push(functionDeclarationName(node));
|
|
303
|
+
} else if (node.type == "FunctionExpression" && !isClassMethodFunction(stack)) { // Expression
|
|
205
304
|
methods.push(anonymousMethodName(node));
|
|
206
305
|
}
|
|
207
306
|
|
|
@@ -223,10 +322,12 @@ module.exports = class Methods {
|
|
|
223
322
|
|
|
224
323
|
traverser.traverse(ast, [], (node, stack) => {
|
|
225
324
|
if (node.type == "FunctionDeclaration") { // Statement
|
|
325
|
+
functionDeclarationName(node);
|
|
226
326
|
methods.push(node);
|
|
227
327
|
return { type: "ExpressionStatement", expression: createMethodStub(node.id) }; // This is not ideal
|
|
228
|
-
} else if (node.type == "FunctionExpression") { // Expression
|
|
328
|
+
} else if (node.type == "FunctionExpression" && !isClassMethodFunction(stack)) { // Expression
|
|
229
329
|
var id = anonymousMethodName(node);
|
|
330
|
+
renameFunctionExpressionSelfReferences(node, id);
|
|
230
331
|
// Merge into old object instead of creating a new one to preserve object references
|
|
231
332
|
methods.push(_.assign(node, {
|
|
232
333
|
type: "FunctionDeclaration",
|
|
@@ -293,11 +394,12 @@ module.exports = class Methods {
|
|
|
293
394
|
|
|
294
395
|
traverser.traverse(ast, [], (node, stack) => {
|
|
295
396
|
if (node.type == "Identifier" && methodEntryExitPoints[node.name] && methodEntryExitPoints[node.name].entry) {
|
|
397
|
+
var dispatcher = methodEntryExitPoints[node.name].dispatcher || "main";
|
|
296
398
|
return {
|
|
297
399
|
type: "CallExpression",
|
|
298
400
|
callee: { type: "Identifier", name: "veilmark$bind" },
|
|
299
401
|
arguments: [
|
|
300
|
-
{ type: "Identifier", name:
|
|
402
|
+
{ type: "Identifier", name: dispatcher },
|
|
301
403
|
{ type: "Identifier", name: methodEntryExitPoints[node.name].entry }
|
|
302
404
|
]
|
|
303
405
|
};
|