临时所写,可能有bug
// 变量传播
function varibalePropagation(ast) {
var update = false;
traverse(ast, {
VariableDeclaration(path) {
try {
const {
declarations
} = path.node;
if (declarations.length !== 1) return;
const {
id,
init
} = declarations[0];
if (!(te.isIdentifier(id) && te.isIdentifier(init))) return;
const targetBinding = path.scope.getBinding(init.name);
if (!targetBinding) return;
const binding = path.scope.getBinding(id.name);
if (!binding) return;
if (!binding.references || binding.references.length === 0) return; // 其实这里可以remove path
const referencePaths = binding.referencePaths;
referencePaths.forEach((refPath) => {
// 跳过更新表达式,如 a++、a--
if (te.isUpdateExpression(refPath.parentPath.node)) return;
// 跳过赋值表达式的左侧,如 a = 1、a += 1
if (refPath.parentPath.isAssignmentExpression() && refPath.parentPath.node.left === refPath.node) return;
// 跳过 delete 操作数,如 delete a
if (refPath.parentPath.isUnaryExpression({
operator: 'delete'
}) && refPath.parentPath.node.argument === refPath.node) return;
// 防止自引用(几乎不会发生,保留也无妨)
if (refPath.node === init) return;
refPath.replaceWith(te.identifier(init.name));
console.log(`Variable propagation: ${id.name} -> ${init.name}`);
update = true;
});
} catch (error) {
console.log(`Error in variable propagation: ${error.message}`);
}
}
});
if (update) {
try {
const code = generator(ast).code;
ast = parser.parse(code);
} catch (e) {
console.error('varibalePropagation 重新解析错误:', e.message);
}
}
return {
ast: ast,
update_: update
};
}
// 函数越狱
function replaceParams(exprNode, paramNames, argNodes) {
const newExpr = te.cloneNode(exprNode);
var can_replace = true;
function replaceNode(node) {
if (!te.isNode(node)) return node;
if (te.isIdentifier(node)) {
const index = paramNames.indexOf(node.name);
if (index > -1) {
return te.cloneNode(argNodes[index]);
} else {
can_replace = false;
}
} else if (te.isThisExpression(node)) {
can_replace = false;
}
for (const key in node) {
if (node[key] && typeof node[key] === 'object') {
if (Array.isArray(node[key])) {
node[key] = node[key].map(item => replaceNode(item));
} else {
node[key] = replaceNode(node[key]);
}
}
}
return node;
}
if (!can_replace) return exprNode;
return replaceNode(newExpr);
}
function functionConfinement(ast) {
var update = false;
traverse(ast, {
FunctionDeclaration(path) {
const {
id,
params,
body
} = path.node;
const blockBody = body.body;
if (blockBody.length !== 1) return;
const firstStatement = blockBody[0];
if (!te.isReturnStatement(firstStatement)) return;
const returnExpr = firstStatement.argument;
if (generator(returnExpr).code.length > 50) return; // 如果很长的话,可能有复杂表达式,这里粗略跳过
const funcName = id.name;
const paramNames = params.map(param => param.name);
const binding = path.parentPath.scope.getBinding(funcName);
if (!binding || !binding.referencePaths.length) {
if (!binding.referencePaths.length) {
path.remove();
update = true;
}
return;
}
try {
binding.referencePaths.forEach(ref => {
const refParentPath = ref.parentPath;
if (!te.isCallExpression(refParentPath.node)) return;
const args = refParentPath.node.arguments;
if (!args) return;
const nCode = generator(refParentPath.node).code;
const newExpr = replaceParams(returnExpr, paramNames, args);
if (newExpr === returnExpr) return;
refParentPath.replaceWith(newExpr);
console.log(`Function confinement: ${nCode} -> ${generator(newExpr).code}`);
update = true;
});
} catch (error) {
console.error(`Function confinement error: ${error.message}`);
}
path.scope.crawl();
}
});
if (update) {
try {
const code = generator(ast).code;
ast = parser.parse(code);
} catch (e) {
console.error('functionConfinement 重新解析错误:', e.message);
}
}
return {
ast: ast,
update_: update
};
}
示例:
原代码:
! function(e, t) {
function n(e, t, n, o, r) {
return m$5(e - -127, r);
}
const o = A$5();
function r(e, t, n, o, r) {
return m$5(e - -51, r);
}
function a(e, t, n, o, r) {
return m$5(e - -421, n);
}
function i(e, t, n, o, r) {
return m$5(r - 544, o);
}
for (;;) try {
if (573587 === -parseInt((l = 607, s = "6]qe", m$5(l - -25, s))) / 1 * (parseInt(n(233, 0, 0, 0, "#upy")) / 2) + -parseInt(r(490, 0, 0, 0, "DgCf")) / 3 + -parseInt(a(157, 0, "29Uu")) / 4 * (-parseInt(r(324, 0, 0, 0, "g]^N")) / 5) + parseInt(i(0, 0, 0, "*S7N", 1294)) / 6 + -parseInt(a(235, 0, "AmNL")) / 7 + -parseInt(a(-54, 0, "AmNL")) / 8 * (-parseInt(i(0, 0, 0, "Q4Q]", 1288)) / 9) + -parseInt(i(0, 0, 0, "!zsp", 1330)) / 10 * (-parseInt(n(212, 0, 0, 0, "5QdF")) / 11)) {
break;
}
o.push(o.shift());
} catch (s) {
o.push(o.shift());
}
var l;
var s;
}();
var a = 'a',
b = 10;
function c(a, b) {
var d = b++;
var e = a;
console.log(e);
return a + b + d;
}
运行后:
!function (e, t) {
function n(e, t, n, o, r) {
return m$5(e - -127, r);
}
const o = A$5();
function r(e, t, n, o, r) {
return m$5(e - -51, r);
}
function a(e, t, n, o, r) {
return m$5(e - -421, n);
}
function i(e, t, n, o, r) {
return m$5(r - 544, o);
}
for (;;) try {
if (573587 === -parseInt((l = 607, s = "6]qe", m$5(l - -25, s))) / 1 * (parseInt(m$5(233 - -127, "#upy")) / 2) + -parseInt(m$5(490 - -51, "DgCf")) / 3 + -parseInt(m$5(157 - -421, "29Uu")) / 4 * (-parseInt(m$5(324 - -51, "g]^N")) / 5) + parseInt(m$5(1294 - 544, "*S7N")) / 6 + -parseInt(m$5(235 - -421, "AmNL")) / 7 + -parseInt(m$5(-54 - -421, "AmNL")) / 8 * (-parseInt(m$5(1288 - 544, "Q4Q]")) / 9) + -parseInt(m$5(1330 - 544, "!zsp")) / 10 * (-parseInt(m$5(212 - -127, "5QdF")) / 11)) {
break;
}
o.push(o.shift());
} catch (s) {
o.push(o.shift());
}
var l;
var s;
}();
var a = 'a',
b = 10;
function c(a, b) {
var d = b++;
var e = a;
console.log(a);
return a + b + d;
}
浙公网安备 33010602011771号