mirror of
https://git.mirrors.martin98.com/https://github.com/cilame/v_jstools
synced 2025-07-06 07:25:13 +08:00
add
This commit is contained in:
parent
29c464bfe0
commit
62c2f8f44a
@ -1 +1,27 @@
|
||||
// background.js
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 后续想做一个右键将选中的代码进行优化处理的功能。
|
||||
// chrome.contextMenus.create({
|
||||
// title: "测试右键菜单",
|
||||
// onclick: function(){alert('您点击了右键菜单!');}
|
||||
// });
|
||||
|
||||
|
||||
// chrome.contextMenus.create({
|
||||
// title: '使用度娘搜索:%s', // %s表示选中的文字
|
||||
// contexts: ['selection'], // 只有当选中文字时才会出现此右键菜单
|
||||
// onclick: function(params)
|
||||
// {
|
||||
// // 注意不能使用location.href,因为location是属于background的window对象
|
||||
// chrome.tabs.create({url: 'https://www.baidu.com/s?ie=utf-8&wd=' + encodeURI(params.selectionText)});
|
||||
// }
|
||||
// });
|
@ -2,7 +2,8 @@
|
||||
"name": "v_jstools",
|
||||
"version": "0.0.0",
|
||||
"description": "v_jstools js hook工具",
|
||||
"permissions": ["storage", "activeTab", "tabs", "debugger", "storage", "extension", "scripting"],
|
||||
"permissions": ["storage", "activeTab", "tabs", "debugger", "storage", "extension", "scripting", "contextMenus"],
|
||||
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
|
||||
"browser_action": {
|
||||
"default_popup": "popup.html"
|
||||
},
|
||||
|
31
popup.html
31
popup.html
@ -7,13 +7,15 @@
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body style="width: 600px;">
|
||||
<label ><input type="checkbox" data-key="config-hook-global">是否挂钩总开关</label>
|
||||
<br/>
|
||||
<label ><input type="checkbox" data-key="config-hook-test">test</label>
|
||||
<br/>
|
||||
<label ><input type="checkbox" data-key="config-hook-console">hook-console</label>
|
||||
<label ><input type="checkbox" data-key="config-hook-console">hook-console(使用 v_log 替换 console.log 并将其他属性设置为空函数)</label>
|
||||
<br/>
|
||||
<label ><input type="checkbox" data-key="config-hook-Function">hook-Function</label>
|
||||
<br/>
|
||||
<label ><input type="checkbox" data-key="config-hook-eval">hook-eval</label>
|
||||
<label ><input type="checkbox" data-key="config-hook-eval">hook-eval(eval函数会记录上下文,若 eval 用到封闭的上下文参数可能报错)</label>
|
||||
<br/>
|
||||
<label ><input type="checkbox" data-key="config-hook-remove-dyn-debugger">remove-dyn-debugger(need selected "hook-Function" or "hook-eval")</label>
|
||||
<br/>
|
||||
@ -41,20 +43,29 @@
|
||||
<br/>
|
||||
<label ><input type="checkbox" data-key="config-hook-domobj">hook-domobj</label>
|
||||
<br/>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<label ><input type="checkbox" data-key="config-hook-domobj-get"> - hook-domobj-显示get输出</label>
|
||||
<br/>
|
||||
<label ><input type="checkbox" data-key="config-hook-domobj-set"> - hook-domobj-显示set输出</label>
|
||||
<br/>
|
||||
<label ><input type="checkbox" data-key="config-hook-domobj-func"> - hook-domobj-显示func输出</label>
|
||||
<br/>
|
||||
|
||||
|
||||
<br/>
|
||||
<div>这里暂时考虑是用来做 ast 解混淆的</div>
|
||||
<textarea style="width: 593px; height: 400px">
|
||||
<div>AST解密混淆</div>
|
||||
|
||||
<button id='ob'>解密ob混淆</button>
|
||||
<button id='obnormal'>普通解混淆</button>
|
||||
<button id='uglify'>仅变量压缩</button>
|
||||
<button id='uglify_mini'>完全压缩脚本</button>
|
||||
<br/>
|
||||
<textarea id='txt' style="width: 593px; height: 500px">
|
||||
|
||||
</textarea>
|
||||
<br/>
|
||||
<script src="popup.js"></script>
|
||||
<script src="babel_asttool.js"></script>
|
||||
<script src="tools/babel_asttool.js"></script>
|
||||
<script src="tools/uglify_es.js"></script>
|
||||
<script src="tools/popup_utils.js"></script>
|
||||
</body>
|
||||
</html>
|
@ -32260,3 +32260,516 @@
|
||||
};
|
||||
}, {} ]
|
||||
}, {}, [ 1 ]);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function FormatMember(path) {
|
||||
// _0x19882c['removeCookie']['toString']()
|
||||
// |
|
||||
// |
|
||||
// |
|
||||
// v
|
||||
// _0x19882c.removeCookie.toString()
|
||||
var curNode = path.node;
|
||||
if(!t.isStringLiteral(curNode.property))
|
||||
return;
|
||||
if(curNode.computed === undefined || !curNode.computed === true)
|
||||
return;
|
||||
if (!/[a-zA-Z_$][0-9a-zA-Z_$]*/.test(curNode.property.value))
|
||||
return;
|
||||
curNode.property = t.identifier(curNode.property.value);
|
||||
curNode.computed = false;
|
||||
}
|
||||
|
||||
function TransCondition(path) {
|
||||
// a = m?11:22;
|
||||
// |
|
||||
// |
|
||||
// |
|
||||
// v
|
||||
// m ? a = 11 : a = 22;
|
||||
let {test, consequent, alternate} = path.node;
|
||||
const ParentPath = path.parentPath;
|
||||
if (ParentPath.isAssignmentExpression()) {
|
||||
let {operator, left} = ParentPath.node;
|
||||
if (operator === "=") {
|
||||
consequent = t.AssignmentExpression("=", left, consequent)
|
||||
alternate = t.AssignmentExpression("=", left, alternate)
|
||||
ParentPath.replaceWith(t.conditionalExpression(test, consequent, alternate))
|
||||
}
|
||||
}
|
||||
}
|
||||
function ConditionToIf(path) {
|
||||
// m ? a = 11 : a = 22;
|
||||
// |
|
||||
// |
|
||||
// |
|
||||
// v
|
||||
// if (m) {
|
||||
// a = 11;
|
||||
// } else {
|
||||
// a = 22;
|
||||
// }
|
||||
let {expression} = path.node;
|
||||
if(!t.isConditionalExpression(expression)) return;
|
||||
let {test, consequent, alternate} = expression;
|
||||
path.replaceWith(t.ifStatement(
|
||||
test,
|
||||
t.blockStatement([t.expressionStatement(consequent),]),
|
||||
t.blockStatement([t.expressionStatement(alternate),])
|
||||
));
|
||||
}
|
||||
|
||||
function ConditionVarToIf(path) {
|
||||
// var m ? a = 11 : a = 22;
|
||||
// |
|
||||
// |
|
||||
// |
|
||||
// v
|
||||
// if (m) {
|
||||
// var a = 11;
|
||||
// } else {
|
||||
// var a = 22;
|
||||
// }
|
||||
let {id, init} = path.node;
|
||||
if (!t.isConditionalExpression(init)) return;
|
||||
const ParentPath = path.parentPath;
|
||||
const ParentNode = path.parent;
|
||||
if (!t.isVariableDeclaration(ParentNode)) return;
|
||||
if (t.isForStatement(ParentPath.parentPath)) return;
|
||||
let kind = ParentNode.kind;
|
||||
let {test, consequent, alternate} = init;
|
||||
ParentPath.replaceWith(t.ifStatement(
|
||||
test,
|
||||
t.blockStatement([t.variableDeclaration(kind, [t.variableDeclarator(id, consequent)]),]),
|
||||
t.blockStatement([t.variableDeclaration(kind, [t.variableDeclarator(id, alternate)]),])
|
||||
));
|
||||
}
|
||||
|
||||
function RemoveComma(path) {
|
||||
// a = 1, b = ddd(), c = null;
|
||||
// |
|
||||
// |
|
||||
// |
|
||||
// v
|
||||
// a = 1;
|
||||
// b = ddd();
|
||||
// c = null;
|
||||
let {expression} = path.node
|
||||
if (!t.isSequenceExpression(expression))
|
||||
return;
|
||||
let body = []
|
||||
expression.expressions.forEach(
|
||||
express => {
|
||||
body.push(t.expressionStatement(express))
|
||||
}
|
||||
)
|
||||
path.replaceInline(body)
|
||||
}
|
||||
|
||||
function RemoveVarComma(path) {
|
||||
// var a = 1, b = ddd(), c = null;
|
||||
// |
|
||||
// |
|
||||
// |
|
||||
// v
|
||||
// var a = 1;
|
||||
// var b = ddd();
|
||||
// var c = null;
|
||||
let {kind, declarations} = path.node;
|
||||
if (declarations.length < 2) return;
|
||||
if (t.isForStatement(path.parentPath)) return;
|
||||
temp = [];
|
||||
declarations.forEach(
|
||||
VariableDeclarator => {
|
||||
temp.push(t.variableDeclaration(kind, [VariableDeclarator]))
|
||||
}
|
||||
)
|
||||
path.replaceInline(temp);
|
||||
}
|
||||
|
||||
function MergeObj(path) {
|
||||
// var _0xb28de8 = {};
|
||||
// _0xb28de8["abcd"] = function(_0x22293f, _0x5a165e) {
|
||||
// return _0x22293f == _0x5a165e;
|
||||
// };
|
||||
// _0xb28de8.dbca = function(_0xfbac1e, _0x23462f, _0x556555) {
|
||||
// return _0xfbac1e(_0x23462f, _0x556555);
|
||||
// };
|
||||
// _0xb28de8.aaa = function(_0x57e640) {
|
||||
// return _0x57e640();
|
||||
// };
|
||||
// _0xb28de8["bbb"] = "eee";
|
||||
// var _0x15e145 = _0xb28de8;
|
||||
// |
|
||||
// |
|
||||
// |
|
||||
// v
|
||||
// var _0xb28de8 = {
|
||||
// "abcd": function (_0x22293f, _0x5a165e) {
|
||||
// return _0x22293f == _0x5a165e;
|
||||
// },
|
||||
// "dbca": function (_0xfbac1e, _0x23462f, _0x556555) {
|
||||
// return _0xfbac1e(_0x23462f, _0x556555);
|
||||
// },
|
||||
// "aaa": function (_0x57e640) {
|
||||
// return _0x57e640();
|
||||
// },
|
||||
// "bbb": "eee"
|
||||
// };
|
||||
const {id, init} = path.node;
|
||||
if (!t.isObjectExpression(init)) // 判断是否是定义对象
|
||||
return;
|
||||
let name = id.name;
|
||||
let properties = init.properties;
|
||||
let scope = path.scope;
|
||||
let binding = scope.getBinding(name);
|
||||
if (!binding || binding.constantViolations.length > 0) { // 确认该对象没有被多次定义
|
||||
return;
|
||||
}
|
||||
let paths = binding.referencePaths;
|
||||
scope.traverse(scope.block, {
|
||||
AssignmentExpression: function(_path) {
|
||||
const left = _path.get("left");
|
||||
const right = _path.get("right");
|
||||
if (!left.isMemberExpression())
|
||||
return;
|
||||
const object = left.get("object");
|
||||
const property = left.get("property");
|
||||
if (object.isIdentifier({name: name}) && property.isStringLiteral() && _path.scope == scope) {
|
||||
properties.push(t.ObjectProperty(t.valueToNode(property.node.value), right.node));
|
||||
_path.remove();
|
||||
}
|
||||
if (object.isIdentifier({name: name}) && property.isIdentifier() && _path.scope == scope) {
|
||||
properties.push(t.ObjectProperty(t.valueToNode(property.node.name), right.node));
|
||||
_path.remove();
|
||||
}
|
||||
}
|
||||
})
|
||||
paths.map(function(refer_path) {
|
||||
let bindpath = refer_path.parentPath;
|
||||
if (!t.isVariableDeclarator(bindpath.node)) return;
|
||||
let bindname = bindpath.node.id.name;
|
||||
bindpath.scope.rename(bindname, name, bindpath.scope.block);
|
||||
bindpath.remove();
|
||||
});
|
||||
}
|
||||
|
||||
function CallToStr(path) {
|
||||
// var _0xb28de8 = {
|
||||
// "abcd": function(_0x22293f, _0x5a165e) {
|
||||
// return _0x22293f == _0x5a165e;
|
||||
// },
|
||||
// "dbca": function(_0xfbac1e, _0x23462f, _0x556555) {
|
||||
// return _0xfbac1e(_0x23462f, _0x556555);
|
||||
// },
|
||||
// "aaa": function(_0x57e640) {
|
||||
// return _0x57e640();
|
||||
// },
|
||||
// "bbb": "eee"
|
||||
// };
|
||||
// var aa = _0xb28de8["abcd"](123, 456);
|
||||
// var bb = _0xb28de8["dbca"](bcd, 11, 22);
|
||||
// var cc = _0xb28de8["aaa"](dcb);
|
||||
// var dd = _0xb28de8["bbb"];
|
||||
// |
|
||||
// |
|
||||
// |
|
||||
// v
|
||||
// var aa = 123 == 456;
|
||||
// var bb = bcd(11, 22);
|
||||
// var cc = dcb();
|
||||
// var dd = "eee";
|
||||
var node = path.node;
|
||||
if (!t.isObjectExpression(node.init)) // 判断是否使用对象
|
||||
return;
|
||||
var objPropertiesList = node.init.properties;
|
||||
if (objPropertiesList.length == 0)
|
||||
return;
|
||||
var objName = node.id.name;
|
||||
// 是否可删除该对象:发生替换时可删除,否则不删除
|
||||
var del_flag = false
|
||||
objPropertiesList.forEach(prop => {
|
||||
var key = prop.key.value;
|
||||
if(t.isFunctionExpression(prop.value)) {
|
||||
var retStmt = prop.value.body.body[0];
|
||||
var fnPath = path.getFunctionParent() || path.scope.path;
|
||||
fnPath.traverse({
|
||||
CallExpression: function (_path) {
|
||||
var _node = _path.node.callee;
|
||||
if (!t.isMemberExpression(_path.node.callee))
|
||||
return;
|
||||
if (!t.isIdentifier(_node.object) || _node.object.name !== objName)
|
||||
return;
|
||||
if (!(t.isStringLiteral(_node.property) || t.isIdentifier(_node.property)))
|
||||
return;
|
||||
if (!(_node.property.value == key || _node.property.name == key))
|
||||
return;
|
||||
var args = _path.node.arguments;
|
||||
// 二元运算, 逻辑运算, 函数调用
|
||||
if (t.isBinaryExpression(retStmt.argument) && args.length===2) {
|
||||
_path.replaceWith(t.binaryExpression(retStmt.argument.operator, args[0], args[1]));
|
||||
}
|
||||
else if(t.isLogicalExpression(retStmt.argument) && args.length==2) {
|
||||
_path.replaceWith(t.logicalExpression(retStmt.argument.operator, args[0], args[1]));
|
||||
}
|
||||
else if(t.isCallExpression(retStmt.argument) && t.isIdentifier(retStmt.argument.callee)) {
|
||||
_path.replaceWith(t.callExpression(args[0], args.slice(1)))
|
||||
}
|
||||
del_flag = true;
|
||||
}
|
||||
})
|
||||
}
|
||||
else if (t.isStringLiteral(prop.value)){
|
||||
var retStmt = prop.value.value;
|
||||
var fnPath = path.getFunctionParent() || path.scope.path;
|
||||
fnPath.traverse({
|
||||
MemberExpression:function (_path) {
|
||||
var _node = _path.node;
|
||||
if (!t.isIdentifier(_node.object) || _node.object.name !== objName)
|
||||
return;
|
||||
if (!(t.isStringLiteral(_node.property) || t.isIdentifier(_node.property)))
|
||||
return;
|
||||
if (!(_node.property.value == key || _node.property.name == key))
|
||||
return;
|
||||
_path.replaceWith(t.stringLiteral(retStmt))
|
||||
del_flag = true;
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
if (del_flag) {
|
||||
// 如果发生替换,则删除该对象, 该处可能出问题,因为字典的内容未必会饱和使用
|
||||
path.remove();
|
||||
}
|
||||
}
|
||||
|
||||
function delExtra(path) {
|
||||
// ['\x49\x63\x4b\x72\x77\x70\x2f\x44\x6c\x67\x3d\x3d',0x123];
|
||||
// |
|
||||
// |
|
||||
// |
|
||||
// v
|
||||
// ["IcKrwp/Dlg==", 291];
|
||||
delete path.node.extra;
|
||||
}
|
||||
|
||||
function AddCatchLog(path){
|
||||
var err_name = path.node.param.name
|
||||
path.node.body.body.unshift({
|
||||
"type": "ExpressionStatement",
|
||||
"expression": {
|
||||
"type": "CallExpression",
|
||||
"callee": {
|
||||
"type": "MemberExpression",
|
||||
"computed": false,
|
||||
"object": {
|
||||
"type": "Identifier",
|
||||
"name": "console"
|
||||
},
|
||||
"property": {
|
||||
"type": "Identifier",
|
||||
"name": "log"
|
||||
}
|
||||
},
|
||||
"arguments": [
|
||||
{
|
||||
"type": "Identifier",
|
||||
"name": err_name
|
||||
}
|
||||
]
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function get_ob_enc(ast) {
|
||||
var first_idx = 0
|
||||
for (var i = 0; i < ast.program.body.length; i++) {
|
||||
if (ast.program.body[i].type != 'EmptyStatement'){
|
||||
first_idx = i;
|
||||
break
|
||||
}
|
||||
}
|
||||
var decrypt_code = ast.program.body.slice(first_idx, first_idx+3)
|
||||
var rest_code = ast.program.body.slice(first_idx+3)
|
||||
ast.program.body = decrypt_code
|
||||
var {code} = generator(ast, {
|
||||
compact: true
|
||||
})
|
||||
global_code = code
|
||||
decryptStr = decrypt_code[2].declarations[0].id.name
|
||||
ast.program.body = rest_code
|
||||
return ast
|
||||
}
|
||||
|
||||
function pas_ob_enc(ast) {
|
||||
eval(global_code)
|
||||
traverse(ast, {
|
||||
CallExpression: funToStr,
|
||||
StringLiteral: delExtra,
|
||||
NumericLiteral: delExtra,
|
||||
})
|
||||
return ast;
|
||||
function funToStr(path) {
|
||||
var node = path.node;
|
||||
if (!t.isIdentifier(node.callee, {name: decryptStr}))
|
||||
return;
|
||||
let value = eval(path.toString())
|
||||
// console.log("还原前:" + path.toString(), "还原后:" + value);
|
||||
path.replaceWith(t.valueToNode(value));
|
||||
}
|
||||
function delExtra(path) {
|
||||
delete path.node.extra;
|
||||
}
|
||||
}
|
||||
|
||||
function ReplaceWhile(path) {
|
||||
var node = path.node;
|
||||
if (!(t.isBooleanLiteral(node.test) || t.isUnaryExpression(node.test)))
|
||||
return;
|
||||
if (!(node.test.prefix || node.test.value))
|
||||
return;
|
||||
if (!t.isBlockStatement(node.body))
|
||||
return;
|
||||
var body = node.body.body;
|
||||
if (!t.isSwitchStatement(body[0]) || !t.isMemberExpression(body[0].discriminant) || !t.isBreakStatement(body[1]))
|
||||
return;
|
||||
var swithStm = body[0];
|
||||
var arrName = swithStm.discriminant.object.name;
|
||||
var argName = swithStm.discriminant.property.argument.name
|
||||
let arr = [];
|
||||
let all_presibling = path.getAllPrevSiblings();
|
||||
all_presibling.forEach(pre_path => {
|
||||
const {declarations} = pre_path.node;
|
||||
let {id, init} = declarations[0]
|
||||
if (arrName == id.name) {
|
||||
arr = init.callee.object.value.split('|');
|
||||
pre_path.remove()
|
||||
}
|
||||
if (argName == id.name) {
|
||||
pre_path.remove()
|
||||
}
|
||||
})
|
||||
var caseList = swithStm.cases;
|
||||
var resultBody = [];
|
||||
arr.map(targetIdx => {
|
||||
var targetBody = caseList[targetIdx].consequent;
|
||||
if (t.isContinueStatement(targetBody[targetBody.length - 1]))
|
||||
targetBody.pop();
|
||||
resultBody = resultBody.concat(targetBody)
|
||||
});
|
||||
path.replaceInline(resultBody);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function muti_process_defusion(jscode){
|
||||
var ast = parser.parse(jscode);
|
||||
|
||||
// ob 解混淆处理部分
|
||||
// ast = get_ob_enc(ast)
|
||||
// ast = pas_ob_enc(ast)
|
||||
// traverse(ast, {VariableDeclarator: {exit: MergeObj},}); // 可能出问题(不可通用)
|
||||
// traverse(ast, {VariableDeclarator: {exit: CallToStr},}); // 可能出问题(不可通用)
|
||||
// traverse(ast, {WhileStatement: {exit: [ReplaceWhile]},}); // 反控制流平坦化
|
||||
|
||||
// 通用解混淆部分
|
||||
traverse(ast, {StringLiteral: delExtra,}) // 清理二进制显示内容
|
||||
traverse(ast, {NumericLiteral: delExtra,}) // 清理二进制显示内容
|
||||
traverse(ast, {ConditionalExpression: TransCondition,}); // 三元表达式
|
||||
traverse(ast, {ExpressionStatement: ConditionToIf,}); // 三元表达式转换成if
|
||||
traverse(ast, {VariableDeclarator: ConditionVarToIf,}); // 赋值语句的 三元表达式转换成if
|
||||
traverse(ast, {ExpressionStatement: RemoveComma,}); // 逗号表达式转换
|
||||
traverse(ast, {VariableDeclaration: RemoveVarComma,}); // 赋值语句的 逗号表达式转换
|
||||
traverse(ast, {MemberExpression: FormatMember,}); // obj['func1']['func2']() --> obj.func1.func2()
|
||||
traverse(ast, {CatchClause: AddCatchLog}); // 给所有的 catch(e){} 后面第一条语句添加异常输出。
|
||||
var { code } = generator(ast, { jsescOption: { minimal: true, } });
|
||||
return code;
|
||||
}
|
||||
|
||||
function muti_process_obdefusion(jscode){
|
||||
var ast = parser.parse(jscode);
|
||||
|
||||
// ob 解混淆处理部分
|
||||
ast = get_ob_enc(ast)
|
||||
ast = pas_ob_enc(ast)
|
||||
traverse(ast, {VariableDeclarator: {exit: MergeObj},}); // 可能出问题(不可通用)
|
||||
traverse(ast, {VariableDeclarator: {exit: CallToStr},}); // 可能出问题(不可通用)
|
||||
traverse(ast, {WhileStatement: {exit: [ReplaceWhile]},}); // 反控制流平坦化
|
||||
|
||||
// 通用解混淆部分
|
||||
traverse(ast, {StringLiteral: delExtra,}) // 清理二进制显示内容
|
||||
traverse(ast, {NumericLiteral: delExtra,}) // 清理二进制显示内容
|
||||
traverse(ast, {ConditionalExpression: TransCondition,}); // 三元表达式
|
||||
traverse(ast, {ExpressionStatement: ConditionToIf,}); // 三元表达式转换成if
|
||||
traverse(ast, {VariableDeclarator: ConditionVarToIf,}); // 赋值语句的 三元表达式转换成if
|
||||
traverse(ast, {ExpressionStatement: RemoveComma,}); // 逗号表达式转换
|
||||
traverse(ast, {VariableDeclaration: RemoveVarComma,}); // 赋值语句的 逗号表达式转换
|
||||
traverse(ast, {MemberExpression: FormatMember,}); // obj['func1']['func2']() --> obj.func1.func2()
|
||||
traverse(ast, {CatchClause: AddCatchLog}); // 给所有的 catch(e){} 后面第一条语句添加异常输出。
|
||||
var { code } = generator(ast, { jsescOption: { minimal: true, } });
|
||||
return code;
|
||||
}
|
45
tools/popup_utils.js
Normal file
45
tools/popup_utils.js
Normal file
@ -0,0 +1,45 @@
|
||||
|
||||
var obtn = document.getElementById('ob')
|
||||
var obnormalbtn = document.getElementById('obnormal')
|
||||
var uglifybtn = document.getElementById('uglify')
|
||||
var uglify_minibtn = document.getElementById('uglify_mini')
|
||||
var txt = document.getElementById('txt')
|
||||
|
||||
obtn.addEventListener('click', function(e){
|
||||
try{
|
||||
txt.value = muti_process_obdefusion(txt.value)
|
||||
}catch(e){
|
||||
txt.value = e.stack
|
||||
}
|
||||
})
|
||||
|
||||
uglifybtn.addEventListener('click', function(e){
|
||||
var r = UglifyJS.minify(txt.value, {
|
||||
compress: {
|
||||
drop_debugger: false,
|
||||
hoist_vars: false,
|
||||
join_vars: false,
|
||||
sequences: false,
|
||||
inline: false,
|
||||
loops: false,
|
||||
reduce_funcs: false,
|
||||
reduce_vars: false,
|
||||
collapse_vars: false,
|
||||
comparisons: false,
|
||||
computed_props: false,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
expression: false,
|
||||
},
|
||||
output: {
|
||||
bracketize: true,
|
||||
beautify: true,
|
||||
},
|
||||
})
|
||||
txt.value = r.code?r.code:r.error;
|
||||
})
|
||||
|
||||
uglify_minibtn.addEventListener('click', function(e){
|
||||
var r = UglifyJS.minify(txt.value)
|
||||
txt.value = r.code?r.code:r.error;
|
||||
})
|
12573
tools/uglify_es.js
Normal file
12573
tools/uglify_es.js
Normal file
File diff suppressed because one or more lines are too long
Loading…
x
Reference in New Issue
Block a user