Commit 8e04a733 authored by wang's avatar wang

11

parent cea61a23
......@@ -508,7 +508,7 @@ for (let i = 0; i < keys.length; i++) {
var map2 = {};
// 开始还原
let funcTemp = {}
for (let j = 0; j < 3; j++) {
for (let j = 0; j < 20; j++) {
traverse(ast, {
VariableDeclaration(path) {
let {declarations} = path.node;
......@@ -518,9 +518,9 @@ for (let j = 0; j < 3; j++) {
let {id, init} = declaration;
if (!init) return
if (!types.isIdentifier(init)) return;
// if (init.name === '$d') {
// debugger;
// }
if (init.name === 'Bo') {
debugger;
}
if (keys2.includes(init.name)) {
let t = newMap[init.name];
......@@ -540,10 +540,10 @@ for (let j = 0; j < 3; j++) {
let binding = scope.getBinding(id.name);
if (!binding) return;
console.log(id.name, init.name, keys2.includes(init.name), binding.references)
// console.log(id.name, init.name, keys2.includes(init.name), binding.references)
if (id.name === 'xc') {
if (id.name === 'Bo') {
// console.log(id.name, init.name, keys2.includes(init.name), binding.references)
debugger
}
......@@ -558,9 +558,9 @@ for (let j = 0; j < 3; j++) {
}
if (arguments.length === 1 && types.isNumericLiteral(arguments[0])) {
let res = funcTemp[t.name](arguments[0].value)
if (id.name === 'zo') {
if (init.name === 'Bo') {
// console.log(arguments[0].value, res)
console.log(init.name, id.name, arguments[0].value, res)
}
referencePath.parentPath.replaceWith(types.StringLiteral(res))
}
......@@ -617,7 +617,7 @@ var i = function () {
function o(n) {
var r = t();
for (var c = i(n), u = "", l = 0; l < c.length; ++l) {
var s = "XsS5yUA".charCodeAt(l % 7);
var s = "flEpkiz".charCodeAt(l % 7);
u += String.fromCharCode(s ^ c.charCodeAt(l));
}
return u;
......@@ -632,13 +632,13 @@ traverse(ast, {
let {id, init} = declaration;
if (!init) return
if (!types.isIdentifier(init)) return;
if (init.name === 'o') {
if (init.name === 'i') {
let binding = scope.getBinding(id.name);
if (id.name === 'xs') {
debugger
}
if (!binding) return;
// console.log(id.name, init.name, binding.references)
console.log(id.name, init.name, binding.references)
for (const referencePath of binding.referencePaths) {
// console.log(referencePath);
......
const acorn = require('acorn')
const fs = require('fs');
const types = require("@babel/types");
const parser = require("@babel/parser");
const {log} = require('console');
const traverse = require("@babel/traverse").default;
const generator = require("@babel/generator").default;
//js混淆代码读取
process.argv.length > 2 ? encodeFile = process.argv[2] : encodeFile = "./main.js";
process.argv.length > 3 ? decodeFile = process.argv[3] : decodeFile = "./decodeResult.js";
process.argv.length > 2 ? encodeFile = process.argv[2] : encodeFile = "./main_ok.js";
process.argv.length > 3 ? decodeFile = process.argv[3] : decodeFile = "./decodeResult22.js";
//将源代码解析为AST
let sourceCode = fs.readFileSync(encodeFile, {encoding: "utf-8"});
const ast = acorn.parse(sourceCode, {
sourceType:"script"
})
let ast = parser.parse(sourceCode, {sourceType: 'script'});
console.time("处理完毕,耗时");
function getRandomName(length) {
let initArr = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
let puzzleArr = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
let ranInx = Math.floor(Math.random() * initArr.length);
let randomName = initArr[ranInx];
for (var i = 1; i < length; i++) {
ranInx = Math.floor(Math.random() * puzzleArr.length);
randomName += puzzleArr[ranInx];
}
return randomName;
}
let allNewNames = new Map(); //定义一个全局变量,保存需要处理的函数
function getUnusedIdentifier() {//获取未被使用的名称,返回 Identifier 类型。
do {
var newName = "$C_" + getRandomName(3);
} while (allNewNames.has(newName))
allNewNames.set(newName, 1);
let UnusedIdentifier = types.Identifier(newName);
return UnusedIdentifier;
}
const renameFunc =
{
FunctionDeclaration(path) {
let {node, parentPath} = path;
let {id, params, body} = node;
let name = id.name;
if (params.length != 2 ||
!types.isVariableDeclaration(body.body[0]) || !types.isReturnStatement(body.body[1])) {
return;
}
let binding = parentPath.scope.getBinding(name);
if (!binding || !binding.constant) {
return;
}
let newNameId = getUnusedIdentifier();
// console.log('rename',name,newNameId)
// console.log(generator(path.parent).code)
for (let referPath of binding.referencePaths) {
referPath.replaceWith(newNameId);
}
let newName = newNameId.name;
allNewNames.set(newName, name)
path.node.id.name = newName;
}
}
// traverse(ast, renameFunc);
allNewNames.clear();
function getBinding(scope, name, func) {
let binding = scope.getBinding(name);
// console.log(`scope.get(${name}).length = ${binding.references}`)
if (binding.references > 0) {
for (const referencePath of binding.referencePaths) {
func(referencePath)
}
}
}
var globalFuncs = {}
function restoreValue(inName, scope, funcName) {
let binding3 = scope.getBinding(inName);
if (!binding3) return;
console.log(funcName, inName, binding3.references)
for (const inReferencePath of binding3.referencePaths) {
console.log(generator(inReferencePath.parent).code, inReferencePath.parent.type)
if (types.isCallExpression(inReferencePath.parent)) {
let {arguments} = inReferencePath.parent
if (arguments.length !== 1) continue
let res = globalFuncs[funcName](arguments[0].value)
// console.log(funcName,inName,arguments[0].value,res)
inReferencePath.parentPath.replaceWith(types.valueToNode(res))
} else if (types.isVariableDeclarator(inReferencePath.parent)) {
// 如果是继续引用 直接再找
let inName2 = inReferencePath.parent.id.name;
restoreValue(inName2, inReferencePath.parentPath.scope, funcName)
}
}
}
for (let i = 0; i < 1; i++) {
traverse(ast, {
FunctionDeclaration(path) {
// 先找
// function ip() {
// var t = ["NjR0QllZTQ", "bind", "reload", "NjR0QltQTw", "NjR0QV1dTw", "pxInit", "uid", "pxvid", "length", "72630ywVgnM", "platform", "vid", "trigger", "NjR0QVxRSA", "random", "67349mopHGY", "NjR0Ql9cQg", "306744MLTLsI", "NjR0QV9fTw", "_pxvid", "getTime", "xhrFailure", "527700doOldY", "_pxRootUrl", "_pxmvid", "top", "NjR0QVNQQg", "xhrResponse", "NjR0QVhbSg", "NjR0QV5QSg", "getItem", "_pxVid", "removeItem", "one", "NjR0QllfTg", "_asyncInit", "NjQ", "3060155IbqKSZ", "subscribe", "1026255lNKhiL", "self", "588762aejAEn", "xhrSuccess"];
// return (ip = function () {
// return t;
// })();
// }
// 这样的函数 解密内容的
let {id, body, params} = path.node;
let bodys = body.body;
if (bodys.length !== 2 || params.length !== 0) return;
let varDeclar = bodys[0];
if (!types.isVariableDeclaration(varDeclar)) return;
if (varDeclar.declarations.length !== 1 || !types.isArrayExpression(varDeclar.declarations[0].init)) return;
if (!types.isReturnStatement(bodys[1])) return;
let name = id.name;
let code = generator(path.node).code;
// if (name !== 'nv') return;
let binding = path.parentPath.scope.getBinding(name);
if (!binding)return;
console.log(`scope.get(${name}).length = ${binding.references}`)
if (binding.references > 0) {
let code1, code2, funcName;
for (const referencePath of binding.referencePaths) {
// console.log(code2);
// console.log('111',referencePath.parentPath.parent.type)
if (types.isUnaryExpression(referencePath.parentPath.parent)) {
code1 = generator(referencePath.parentPath.parent).code;
// console.groupCollapsed(['改变顺序', code1])
} else if (types.isVariableDeclarator(referencePath.parentPath.parent)) {
code2 = generator(referencePath.parentPath.parentPath.parentPath.parentPath.parent).code;
funcName = referencePath.parentPath.parentPath.parentPath.parentPath.parent.id.name
// console.groupCollapsed(['使用', code2])
}
}
let resCode = code + ';;;\n' + code1 + ';;;\n' + code2;
resCode += `
globalFuncs['${funcName}'] = ${funcName}
`
// console.groupCollapsed([funcName, resCode])
if (!globalFuncs[funcName]) {
eval(resCode)
}
// console.log(eval(`${funcName}(195)`))
let binding2 = path.parentPath.scope.getBinding(funcName);
// 找到Tp 的引用地方
for (const referencePath of binding2.referencePaths) {
console.log('referencePath', generator(referencePath.parent).code)
// if (types.isBlockStatement(referencePath.parentPath.parentPath.parent) ) {
if (!types.isUnaryExpression(referencePath.parentPath.parentPath.parentPath.parentPath.parentPath.parentPath.parent)) {
// 找到引用点 排除掉 修改变量顺序的引用
console.log(generator(referencePath.parent).code, referencePath.parent.type)
if (types.isCallExpression(referencePath.parent)) {
let {arguments} = referencePath.parent
if (arguments.length !== 1) continue
let res = globalFuncs[funcName](arguments[0].value)
// console.log(funcName,inName,arguments[0].value,res)
referencePath.parentPath.replaceWith(types.valueToNode(res))
} else {
if (!referencePath.parent.id) continue;
// 继续找引用
let inName = referencePath.parent.id.name;
let binding3 = referencePath.scope.getBinding(inName);
if (!binding3) continue;
console.log('find', funcName, inName, binding3.references)
for (const inReferencePath of binding3.referencePaths) {
console.log('code ', generator(inReferencePath.parent).code, inReferencePath.parent.type)
if (types.isCallExpression(inReferencePath.parent)) {
let {arguments} = inReferencePath.parent
if (arguments.length !== 1) continue
let res = globalFuncs[funcName](arguments[0].value)
console.log('444', funcName, inName, arguments[0].value, res)
if (res === 'getTime') {
let {code} = generator(ast, opts = {jsescOption: {"minimal": true}});
fs.writeFile('./tmp.js', code, (err) => {
});
}
console.log('before', res, generator(inReferencePath.parent).code)
inReferencePath.parentPath.replaceWith(types.valueToNode(res))
console.log('afterr', res, generator(inReferencePath.parent).code)
inReferencePath.skip()
} else if (types.isVariableDeclarator(inReferencePath.parent)) {
// 如果是继续引用 直接再找
let inName2 = inReferencePath.parent.id.name;
restoreValue(inName2, inReferencePath.parentPath.scope, funcName)
}
}
}
function walkNode(node, callback) {
callback(node)
// 有 type 字段的我们认为是一个节点
Object.keys(node).forEach((key) => {
const item = node[key]
if (Array.isArray(item)) {
item.forEach((sub) => {
sub.type && walkNode(sub, callback)
})
}
item && item.type && walkNode(item, callback)
}
}
// console.log(name, code);
}
})
}
walkNode(ast, function (e){
console.log(e)
// 字符串还原铭文
var o = {};
var a = function () {
try {
if (atob && "test" === atob("dGVzdA==")) {
return atob;
}
} catch (t) {
}
function t(t) {
this["message"] = t;
}
t["prototype"] = new Error();
t["prototype"]["name"] = "InvalidCharacterError";
return function (e) {
var n = String(e)["replace"](/[=]+$/, "");
if (n["length"] % 4 == 1) {
throw new t("'atob' failed: The string to be decoded is not correctly encoded.");
}
for (var r, a, o = 0, i = 0, c = ""; a = n["charAt"](i++); ~a && (r = o % 4 ? 64 * r + a : a, o++ % 4) ? c += String["fromCharCode"](255 & r >> (-2 * o & 6)) : 0) {
a = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="["indexOf"](a);
}
return c;
};
}();
function i(n) {
if (o[n]) {
u = o[n];
} else {
for (var c = a(n), u = "", f = 0; f < c["length"]; ++f) {
var s = "bhDTSyS"["charCodeAt"](f % 7);
u += String["fromCharCode"](s ^ c["charCodeAt"](f));
}
o[n] = u;
}
return u;
}
traverse(ast, {
FunctionDeclaration(path) {
let {id, body} = path.node;
if (id.name !== 'i') return;
if (body.body.length !== 4) return
let binding = path.scope.getBinding(id.name)
console.log(id.name, binding.references)
for (const referencePath of binding.referencePaths) {
// console.log(generator(referencePath.parent).code, referencePath.parent.type)
if (types.isVariableDeclarator(referencePath.parent)) {
let idName = referencePath.parent.id.name;
getBinding(referencePath.scope, idName, function (p) {
if (types.isCallExpression(p.parent)) {
let arguments = p.parent.arguments;
if (arguments.length !== 1) return
try {
let res = i(arguments[0].value);
if (res === 'PX12571') debugger;
p.parentPath.replaceWith(types.valueToNode((res)))
} catch (e) {
// console.error(generator(p.parent).code)
}
}
})
} else if (types.isCallExpression(referencePath.parent)) {
let arguments = referencePath.parent.arguments;
if (arguments.length !== 1) continue
try {
let res = i(arguments[0].value);
referencePath.parentPath.replaceWith(types.valueToNode((res)))
} catch (e) {
// console.error(generator(p.parent).code)
}
}
}
}
})
// U
function U(t) {
return f(J) === "function" ? J(t) : function (t) {
var e;
var n;
var r;
var a;
var o = [];
var i = 0;
var c = t["length"];
try {
if (/[^+/=0-9A-Za-z]/["test"](t) || /=/["test"](t) && (/=[^=]/["test"](t) || /={3}/["test"](t))) {
return null;
}
for (c % 4 > 0 && (c = (t += v["Array"](4 - c % 4 + 1)["join"]("="))["length"]); i < c;) {
n = [];
for (a = i; i < a + 4;) {
n["push"]("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="["indexOf"](t["charAt"](i++)));
}
r = [((e = (n[0] << 18) + (n[1] << 12) + ((63 & n[2]) << 6) + (63 & n[3])) & 255 << 16) >> 16, 64 === n[2] ? -1 : (65280 & e) >> 8, 64 === n[3] ? -1 : 255 & e];
for (a = 0; a < 3; ++a) {
(r[a] >= 0 || 0 === a) && o["push"](String["fromCharCode"](r[a]));
}
}
return o["join"]("");
} catch (t) {
return null;
}
}(t);
}
var J = function () {
try {
return atob;
} catch (t) {}
}();
function f(t) {
f = "function" == typeof Symbol && "symbol" == typeof Symbol["iterator"] ? function (t) {
return typeof t;
} : function (t) {
return t && "function" == typeof Symbol && t["constructor"] === Symbol && t !== Symbol["prototype"] ? "symbol" : typeof t;
};
return f(t);
}
traverse(ast, {
FunctionDeclaration(path) {
let {id, body} = path.node;
if (id.name !== 'U') return;
let binding = path.scope.getBinding(id.name)
console.log(id.name, binding.references)
for (const referencePath of binding.referencePaths) {
// console.log(generator(referencePath.parent).code, referencePath.parent.type)
if (types.isVariableDeclarator(referencePath.parent)) {
let idName = referencePath.parent.id.name;
getBinding(referencePath.scope, idName, function (p) {
if (types.isCallExpression(p.parent)) {
let arguments = p.parent.arguments;
if (arguments.length !== 1) return
try {
let res = i(arguments[0].value);
if (res === 'PX12571') debugger;
p.parentPath.replaceWith(types.valueToNode((res)))
} catch (e) {
// console.error(generator(p.parent).code)
}
}
})
} else if (types.isCallExpression(referencePath.parent)) {
let arguments = referencePath.parent.arguments;
if (arguments.length !== 1) continue
try {
let res = U(arguments[0].value);
referencePath.parentPath.replaceWith(types.valueToNode((res)))
} catch (e) {
// console.error(generator(p.parent).code)
}
}
}
}
})
//end
console.timeEnd("处理完毕,耗时");
let {code} = generator(ast, opts = {jsescOption: {"minimal": true}});
fs.writeFile(decodeFile, code, (err) => {
});
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
const fs = require('fs');
const types = require("@babel/types");
const parser = require("@babel/parser");
const template = require("@babel/template").default;
const traverse = require("@babel/traverse").default;
const generator = require("@babel/generator").default;
//js混淆代码读取
process.argv.length > 2 ? encodeFile = process.argv[2] : encodeFile = "./main.js"; //默认的js文件
process.argv.length > 3 ? decodeFile = process.argv[3] : decodeFile = encodeFile.replace(".js", "") + "_ok.js";
//将源代码解析为AST
let sourceCode = fs.readFileSync(encodeFile, { encoding: "utf-8" });
let ast = parser.parse(sourceCode);
console.time("处理完毕,耗时");
const keyToLiteral = {
MemberExpression:
{
exit({ node }) {
const prop = node.property;
if (!node.computed && types.isIdentifier(prop)) {
node.property = types.StringLiteral(prop.name);
node.computed = true;
}
}
},
ObjectProperty:
{
exit({ node }) {
const key = node.key;
if (!node.computed && types.isIdentifier(key)) {
node.key = types.StringLiteral(key.name);
return;
}
if (node.computed && types.isStringLiteral(key)) {
node.computed = false;
}
}
},
}
traverse(ast, keyToLiteral);
const standardLoop =
{
"ForStatement|WhileStatement|ForInStatement|ForOfStatement"({ node }) {
if (!types.isBlockStatement(node.body)) {
node.body = types.BlockStatement([node.body]);
}
},
IfStatement(path) {
const consequent = path.get("consequent");
const alternate = path.get("alternate");
if (!consequent.isBlockStatement()) {
consequent.replaceWith(types.BlockStatement([consequent.node]));
}
if (alternate.node !== null && !alternate.isBlockStatement()) {
alternate.replaceWith(types.BlockStatement([alternate.node]));
}
},
}
traverse(ast, standardLoop);
const DeclaratorToDeclaration =
{
VariableDeclaration(path) {
let { parentPath, node } = path;
if (!parentPath.isBlock()) {
return;
}
let { declarations, kind } = node;
if (declarations.length == 1) {
return;
}
let newNodes = [];
for (const varNode of declarations) {
let newDeclartionNode = types.VariableDeclaration(kind, [varNode]);
newNodes.push(newDeclartionNode);
}
path.replaceWithMultiple(newNodes);
},
}
traverse(ast, DeclaratorToDeclaration);
function SequenceOfStatement(path) {
let { scope, parentPath, node } = path;
if (parentPath.parentPath.isLabeledStatement()) {//标签节点无法往前插入。
return;
}
let expressions = node.expressions;
if (parentPath.isReturnStatement({ "argument": node }) ||
parentPath.isThrowStatement({ "argument": node })) {
parentPath.node.argument = expressions.pop();
}
else if (parentPath.isIfStatement({ "test": node }) ||
parentPath.isWhileStatement({ "test": node })) {
parentPath.node.test = expressions.pop();
}
else if (parentPath.isForStatement({ "init": node })) {
parentPath.node.init = expressions.pop();
}
else if (parentPath.isForInStatement({ "right": node }) ||
parentPath.isForOfStatement({ "right": node })) {
parentPath.node.right = expressions.pop();
}
else if (parentPath.isSwitchStatement({ "discriminant": node })) {
parentPath.node.discriminant = expressions.pop();
}
else if (parentPath.isExpressionStatement({ "expression": node })) {
parentPath.node.expression = expressions.pop();
}
else {
return;
}
for (let expression of expressions) {
parentPath.insertBefore(types.ExpressionStatement(expression = expression));
}
}
function SequenceOfExpression(path) {
let { scope, parentPath, node, parent } = path;
let ancestorPath = parentPath.parentPath;
let expressions = node.expressions;
if (parentPath.isConditionalExpression({ "test": node }) &&
ancestorPath.isExpressionStatement({ "expression": parent })) {
parentPath.node.test = expressions.pop();
}
else if (parentPath.isVariableDeclarator({ "init": node }) &&
ancestorPath.parentPath.isBlock()) {
parentPath.node.init = expressions.pop();
}
else if (parentPath.isAssignmentExpression({ "right": node }) &&
ancestorPath.isExpressionStatement({ "expression": parent })) {
parentPath.node.right = expressions.pop();
}
else if ((parentPath.isCallExpression({ "callee": node }) ||
parentPath.isNewExpression({ "callee": node })) &&
ancestorPath.isExpressionStatement({ "expression": parent })) {
parentPath.node.callee = expressions.pop();
}
else {
return;
}
for (let expression of expressions) {
ancestorPath.insertBefore(types.ExpressionStatement(expression = expression));
}
}
const resolveSequence =
{
SequenceExpression:
{//对同一节点遍历多个方法
exit: [SequenceOfStatement, SequenceOfExpression]
}
}
traverse(ast, resolveSequence);
const removeDeadCode = {
"IfStatement|ConditionalExpression"(path) {
let { consequent, alternate } = path.node;
let testPath = path.get('test');
const evaluateTest = testPath.evaluateTruthy();
if (evaluateTest === true) {
if (types.isBlockStatement(consequent)) {
consequent = consequent.body;
}
path.replaceWithMultiple(consequent);
return;
}
if (evaluateTest === false) {
if (alternate != null) {
if (types.isBlockStatement(alternate)) {
alternate = alternate.body;
}
path.replaceWithMultiple(alternate);
}
else {
path.remove();
}
}
},
"LogicalExpression"(path) {
let { left, operator, right } = path.node;
let leftPath = path.get('left');
const evaluateLeft = leftPath.evaluateTruthy();
if ((operator == "||" && evaluateLeft == true) ||
(operator == "&&" && evaluateLeft == false)) {
path.replaceWith(left);
return;
}
if ((operator == "||" && evaluateLeft == false) ||
(operator == "&&" && evaluateLeft == true)) {
path.replaceWith(right);
}
},
"EmptyStatement|DebuggerStatement"(path) {
path.remove();
},
}
traverse(ast, removeDeadCode); //PS:因为有赋值语句和定义语句同时存在,因此该插件可能需要运行多次才能删除干净。
const simplifyLiteral = {
NumericLiteral({ node }) {
if (node.extra && /^0[obx]/i.test(node.extra.raw)) {
node.extra = undefined;
}
},
StringLiteral({ node }) {
if (node.extra && /\\[ux]/gi.test(node.extra.raw)) {
node.extra = undefined;
}
},
}
traverse(ast, simplifyLiteral);
function isNodePure(node, scope) {
if (types.isLiteral(node)) {
return true;
}
if (types.isUnaryExpression(node)) {
return isNodePure(node.argument, scope)
}
if (types.isIdentifier(node)) {//处理 var c = String;
if (scope && scope.isPure(node, true)) {
return true;
}
if (typeof this[node.name] != 'undefined') {
return true;
}
return false;
}
if (types.isMemberExpression(node)) {//处理 var d = String.fromCharCode;
let {object, property, computed} = node;
if (computed && !isNodePure(property, scope)) {
return false;
}
if (isNodePure(object, scope)) {
return true;
}
if (types.isIdentifier(object)) {
let name = object.name;
if (typeof this[name] != 'undefined' && name != 'window') {//注意object为window时,可能会还原出错
return true;
}
return false;
}
if (types.isMemberExpression(object)) {
return isNodePure(object, scope);
}
return false;
}
if (types.isBinary(node) && scope) {
return isNodePure(node.left, scope) && isNodePure(node.right, scope);
}
return false;
}
traverse(ast, {
VariableDeclaration(path) {
let {node} = path;
let {declarations} = node;
let res = [];
// console.log(path.parentPath.type)
if (types.isForStatement(path.parentPath)) return
if (!declarations || declarations.length == 1) return
for (let i = 0; i < declarations.length; i++) {
let declaration = declarations[i];
res.push(types.VariableDeclaration('var', [declaration]))
}
path.replaceWithMultiple(res)
path.skip()
}
})
const restoreVarDeclarator = {
VariableDeclarator(path) {
let scope = path.scope;
let {id, init} = path.node;
if (!init && (!types.isNumericLiteral(init) || !types.isStringLiteral(init))) return
if (id.name === 'c' && init.value === 0) return
if (!types.isIdentifier(id) || !isNodePure(init, scope)) {
return;
}
const binding = scope.getBinding(id.name);
try {
var {
constant, referencePaths, constantViolations
} = binding; //变量的定义一定会有binding.
} catch (e) {
return;
}
if (constantViolations.length > 1) {
return;
}
if (constant || constantViolations[0] == path) {
for (let referPath of referencePaths) {
// console.log(init.value)
// console.log(id.name, referPath.type, generator(referPath.container).code, generator(init).code)
referPath.replaceWith(init);
}
// console.log(path.toString())
path.remove();//没有被引用,或者替换完成,可直接删除
}
},
}
traverse(ast, restoreVarDeclarator)
//还原object
function isBaseLiteral(node) {
if (types.isLiteral(node)) {
return true;
}
if (types.isUnaryExpression(node, {operator: "-"}) ||
types.isUnaryExpression(node, {operator: "+"})) {
return isBaseLiteral(node.argument);
}
return false;
}
const decodeValueOfObject =
{//当一个object里面的value全部为字面量时的还原,没有考虑单个key重新赋值的情况。
VariableDeclarator(path) {
let { node, scope } = path;
const { id, init } = node;
if (!types.isObjectExpression(init)) return;
let properties = init.properties;
if (properties.length == 0 || !properties.every(property => isBaseLiteral(property.value)))
return;
let binding = scope.getBinding(id.name);
if (!binding)return;
let { constant, referencePaths } = binding;
if (!constant) return;
let newMap = new Map();
for (const property of properties) {
let { key, value } = property;
newMap.set(key.value, value);
}
let canBeRemoved = true;
for (const referPath of referencePaths) {
let { parentPath } = referPath;
if (!parentPath.isMemberExpression()) {
canBeRemoved = false;
return;
}
let AncestorPath = parentPath.parentPath;
if (AncestorPath.isAssignmentExpression({"left":parentPath.node}))
{
canBeRemoved = false;
return;
}
if (AncestorPath.isUpdateExpression() && ['++','--'].includes(AncestorPath.node.operator))
{
canBeRemoved = false;
return;
}
let curKey = parentPath.node.property.value;
if (!newMap.has(curKey)) {
canBeRemoved = false;
break;
}
parentPath.replaceWith(newMap.get(curKey));
}
canBeRemoved && path.remove();
newMap.clear();
},
}
traverse(ast, decodeValueOfObject);
console.timeEnd("处理完毕,耗时");
let { code } = generator(ast, opts = {
"compact": false, // 是否压缩代码
"comments": false, // 是否保留注释
"jsescOption": { "minimal": true }, //Unicode转义
});
fs.writeFile(decodeFile, code, (err) => { });
\ No newline at end of file
......@@ -60,7 +60,8 @@ a2 = "KysrKytSHj0SGlAeUVFSHgcbKFMrCA0LLBg3GjgmLxUvJTcWLCY7UiwbUhovNTQOLjUnFSw1Mx
a2 = "UisrUitSHhEBDRAHHlIeAAsMAxAbHBwcHCsrKysrUh49EhpQHlFRUh4HGyhTKwgNCzsINA8sJjsYLA87FiwmO1IsG1IaLzU0Di41J1MsJSsWLBgjUiwYM1csJglSOwgBGysLFQsGCytUKw8zFS01M1ctNjNTLjYzUCwmARYvNiQOODFTCiw2MAsuNjMYLyYGCi9QJxg4NScaOCErESsMMwstCDcYLzYzUiwIMxUvIRULAyErVCsICg4tJiQPLwgnGi8lJxosJg4POxg3FTg2MA4tNTtTLAg3Vzg1Oxo7UDAJOCYzVzsYOA4vGCtRO1AnGDgIN1MsJicYLTUnGDsPM1IvGDgPO1A7Gi8YAQsEM19fHhYQFwceUVJSHBwcHFIrK1IrUh4RAQ0QBx5SHgALDAMQGxwcHBxSKysrK1JSUh49EhoGBx5RUVIeUVRRU1JRBlEAVFJUA1pQV1QEB1VXBgFXVAcHUQQHVVVUBFFRV1paV1VSAVYHVgRUAVdXAAFQAFoAWgdbUFEGBlgHGyhSAzVTDgFRMAoAOiMLLQgnUC02LxstNgVTLBg3ViwIMFseFhAXBx5RUlIcHBwcUisrK1IrUlIeUhwcHBxSUitSK1IeARc="
a2 = "B1lZB1lZFF1dWV8JWwteRVBaDAlFWVkNDUUJWApZRV4LDgteUQoJWVFbXRYWFhYHWVkHWVkHBxRdXVlfCV5QUUVQWgwJRVlZDQ1FCVgKWUVeCw4LXlEKCVlRW10UHBodDRYWFhZZWVkHB1kUCwsUXlgUPVouHDI+JhgMLz1RPC8uXCcfVVUWFhYWWQcHBwdZFAsEUQMcAQ0bXxwGBVpcGQJfCQsPFhYWFgdZWVkHBwcHFFBeWVAWFhYWWVlZB1kHFFlRUVteWVpQWF5ZXl1fWFFbX1xZFhYWFgdZWVkHBwdZFFleUVFRXVBcX1tfW1sWFhYWWVkHWVlZFFEKX1tQWQtdXF5ZDFhRXg4JDAlcW1FYXF1RWFAMDlhaDVhcCV4OWl0KDgwLUVgJDFxQCVwKXgsJXgpfC18LWF0WFhYWB1kHWVlZFAsdFhYWFgdZBwdZBxRdWl1fDFEKC0VQWgwJRVlZDQ1FUQleX0UJCVBcXl4ODg4OXl4UW1ldW15YWFgUHBodDRYWFhYHWVlZBwdZBxQ3GBAMDRRbW1gUC1wOUAwKXF9QXVkKUFFYW1sMX19fXVhfWgsJDg1aWVFZXQ5dCwpcXA5aWlhfWgsOXVtbUQwMDlwKDgwNUAtbW1INESJYCT9ZBAtbOgAKMCkBJwItWic8A10mPA9YJhIlWyUSJlEUHBodDRRbWFg="
a2 = "B1lZWQcHB1kUWV9YWFhZXF5YWltaWxYWFhYHWQcHWQcUWFpbClpcWVBFUFtdDEVZWQ0NRQlcDFtFCQsMDltRDFxRX19eFFtZXVteWFhYFBwaHQ0WFhYWWVlZBwdZFAsLFF5YFD1aLhwyPiYYDC89UTwvLlwnH1VVFhYWFgdZWVkHB1kHFDcYEAwNFFtbWBRZC1sNWV4NWV8LDAxeXFpdC18KWwoNDF8OCw4KXl9dWlBdDVBfC1AOXl8OXgwOUQwJW14NDAlcW1wKXFFQCloOUg0RIlgJP1kEC1s6AAowKQEnAi1bJSwpHyU8OVolLCESJQImURQcGh0NFFtYWBYWFhYHWVkHWVkUWFxdXQwOUVFFUFtdDEVZWQ0NRVFdDF9FClFfUFwJCQlRXVFRFhYWFgdZWQdZWQcHFFhcXV0NWl9ZRVBbXQxFWVkNDUVRXQxfRQpRX1BcCQkJUV1RURQcGh0NFhYWFllZB1lZWRRfWFwLCw1dUFsJWQtZDlsMXw5bDQtYCQ5RWFleXFkNDFxQW1gMDQsNXAsNDlANW14KDA5eWVxbDl0OCgxfWVlRFhYWFlkHBwcHWRQLBAlaA1oFUQcPWwVaXB0ZBlECWBYWFhZZWVkHWQcUUV1dWVpQXlldX1hbWFpcUVxZXVEWFhYWB1kHWVlZFAsdFhYWFgdZWVkHBwcHFFBfWl8="
# a2 = "B1lZWQcHWQcUNxgQDA0UW1tYFFkJWF9dC1teXVAJXV5ZWQtfCl9dWVoLCVEODVhYUQldXg4LDl5QUFBYX1xbDVpeDl5aC19aWlwNDlEKW14KWFBSDREiWAk/WQQLWzoACjApAScCLVonPANdJjwPWCYSOVslEgxRFBwaHQ0UW1hYFhYWFllZBwcHWRQ3GBBaFFtbWBQNESJZIQIHASY8OgAyLyVZMjwpHCcsIgMxO1gQJT8+BCQ8D1wmLyUcJgItWTIsLVglWjFcJiwEASEBHwEMASFeIQI9ESY8DAMnPyICJDwPETIvLRwlPC4EMjtYXTE8MVskPy4AJyw5WiYFMgUyBTFaJgEhGyEGOQEnAi1aJzwDXSY8D1smEjlbJRILGyEFDwEnASICJi8tXSUFPVglWiYCJz8iBCU/MRAmLD0QJgU5WzI8OVwmPANaJjwxETIsAxEmPD1bJjwlESYCJVkxPyFZJhI5ECYSDxIxAilYJzw9WzIsIVwmLC1ZIQZYVRQcGh0NFFtYWBYWFhYHWQdZB1kUGwsHGg0UWBQKAQYJGhEWFhYWB1kHWVlZFAsd"
# 0III0I00 判断是否通过
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment