js逆向

阅读: 评论:0

js逆向

js逆向

基础练一练,不喜勿喷。

jscode对应visitor,jscode1对应visitor1,以此类推。

 

/*
* 安装 npm install @babel/core
* */// 将JS源码转换成语法树
const parser = require("@babel/parser");
// 为parser提供模板引擎
const template = require("@babel/template").default;
// 遍历AST
const traverse = require("@babel/traverse").default;
// 操作节点,比如判断节点类型,生成新的节点等
const t = require("@babel/types");
// 将语法树转换为源代码
const generator = require("@babel/generator").default;
// 操作文件
const fs = require("fs");///
/*
type: 表示当前路径的类型;
start:表示当前节点的起始位置;
end: 表示当前节点的结束位置;
loc: 表示当前节点所在源代码中的起始和结束的行号和列号。
declarations :声明
kind:表示定义的类型*/const visitor = {VariableDeclarator(path) {// 当前路径所对应的源代码,使用toString方法console.String());// a = 123   b = 'ccc'//获取path的上一级路径,使用parentPathlet parent = path.parentPath;console.de.kind) //var let//获取path的子路径,使用 get方法,得到id节点let id = ('id');console.de.name); //a b//获取当前路径的节点const node = de;console.log(node.init.value);//123 ccc//得到init节点let init = ('init');//判断node下的init节点类型if (t.isNumericLiteral(node.init)) {id.replaceWith(t.Identifier('A'));console.de.name); //placeWith(t.NumericLiteral(4));console.log(node.init.value);//4}//直接拿init节点来判断类型if (init.isStringLiteral()) {id.replaceWith(t.Identifier('B'));console.de.name); //placeWith({type: "StringLiteral", value: 'qqq'});console.de.value);//qqq// 删除init节点// ve()// de.init;}}
};
//替换path,单路径可以使用replaceWith方法,多路径则使用replaceWithMultiple方法
//placeWith 和 placeWith区别:前者只是替换当前遍历节点里的init节点,后者是把当前遍历节点整个替换const visitor1 = {CallExpression(path) {console.String());           //aaa(1, 2)const node = de;// 获取CallExpression节点结构// console.log(JSON.stringify(node,null,'t'));console.log(node.callee.name);          //aaaconsole.log(node.arguments[0].value);   //1console.log(node.arguments[1].value);   //2let callee = ('callee');// console.String());         //aaaconsole.de.name)           //aaa}
};const visitor2 = {'StringLiteral|NumericLiteral'(path) {// let value = de.value// //此行效果等于上行// // let {value} = de// console.log(value)//之所以会以十六进制显示,完全是 raw这个节点造成的,那就删除de.extra}
};
const visitor3 = {MemberExpression(path) {// const node = de;// let property = ('property')// if (t.isStringLiteral(node.property)) {//     let value = node.property.value;//     console.log(value)//     //原为true,改后的效果把[]变为.//     nodeputed = false//     //如果写成placeWith是将整个MemberExpression节点换为value,节点类型也变为Identifier,例:window.btoa变为btoa//     //我们仅需要替换property节点//     placeWith(t.Identifier(value))//     }//效果同上let property = ('property')if (property.isStringLiteral()) {let value = de.value;console.log(deputed = placeWith(t.Identifier(value))}}
};
const visitor4 = {VariableDeclaration(path) {const operator = '='; //赋值语句的运算符是 =const left = t.Identifier('b'); //新建赋值语句左边的节点;const right = t.NumericLiteral(456);//新建赋值语句右边的节点;const new_assign = t.AssignmentExpression(operator, left, right) //构造一个赋值语句节点const new_express = t.ExpressionStatement(new_assign); //再构造成表达式语句path.insertBefore(new_express);//在变量声明语句前面插入const new_vdtor = t.VariableDeclarator(left, right)const new_vdtion = t.VariableDeclaration('let', [new_vdtor])path.insertAfter(new_vdtion); //在变量声明语句后面插入var str = String()const new_memberexp = t.MemberExpression(t.Identifier('console'), t.Identifier('log'),)const new_callexp = t.CallExpression(new_memberexp, [t.StringLiteral(str)])path.insertAfter(new_callexp); //在变量声明语句后面插入path.stop()   //不停止会无限循环下去}}
const visitor5 = {SwitchCase(path) {const node = de;let consequent = ('consequent');//数组类型//长度// console.log(consequent.length)for (var i = 0; i < consequent.length; i++) {if (t.isContinueStatement(consequent[i])) continueconst conqt = consequent[i].toString();const new_memberexp = t.MemberExpression(t.Identifier('console'), t.Identifier('log'),);const new_callexp = t.CallExpression(new_memberexp, [t.StringLiteral(conqt)]);consequent[i].insertBefore(new_callexp); //在变量声明语句后面插入// 可删除原来的节点// t.isReturnStatement(consequent[i]) ?  consequent[i].node.argument = null : consequent[i].remove()consequent[i].stop();  //不停止会无限循环下去}//运行得到的代码得到混淆前的代码}}
const visitor6 = {NumericLiteral(path) {// const node = de;// const value = node.value//等效上2行const value = String()const first = 0 - Math.floor(Math.random() * 10000000 + 10000000);const second = value ^ first;const binexp = t.BinaryExpression('^', t.NumericLiteral(first), t.NumericLiteral(second))placeWith(binexp)path.stop()}
}const visitor7 = {//默认是enter,先遍历顶层,修改为exit,则是先遍历底层,看visitor7_1'BinaryExpression|UnaryExpression|ConditionalExpression'(path) {// const value = path.evaluate().value;const {value} = path.evaluate();// console.String(),'   ',value)switch (typeof value) {case 'boolean':placeWith(t.BooleanLiteral(value))break;case 'string':placeWith(t.StringLiteral(value))break;case 'number':placeWith(t.NumericLiteral(value))break;default:break;}}}
// visitor7另一种写法
const visitor7_1 = function (path) {// const value = path.evaluate().value;const {value} = path.evaluate();console.String(), '   ', value)// switch (typeof value) {//     case 'boolean'://         placeWith(t.BooleanLiteral(value))//         break;//     case 'string'://         placeWith(t.StringLiteral(value))//         break;//     case 'number'://         placeWith(t.NumericLiteral(value))//         break;//     default://         break;// }
}
const visitor8 = {VariableDeclarator(path) {//此法为替换原init,console.String())const init = ('init')           //a = 123 | 456const left = de.left.value       //123const right = de.right.value     //456//重新构造一个函数const p_left = t.Identifier('s'), p_right = t.Identifier('h')  //设定2个形参const params = [p_left, p_right]                  //数组类型const retsta = [t.ReturnStatement(t.BinaryExpression('|', p_left, p_right))]//数组类型const body = t.BlockStatement(retsta,)          //第二参数默认[]const callee = t.functionExpression(null, params, body,)const arguments = [t.NumericLiteral(left), t.NumericLiteral(right)]      //数组类型const new_callexp = t.callExpression(callee, placeWith(new_callexp)// 还可以直接在原init上修改// const init = ('init')           //a = 123 | 456// const left = de.left.value       //123// const right = de.right.value     //456//// const p_left = t.Identifier('s'), p_right = t.Identifier('h')  //设定2个形参// const params = [p_left, p_right]                  //数组类型// const retsta = [t.ReturnStatement(t.BinaryExpression('|', p_left, p_right))]//数组类型// const body = t.BlockStatement(retsta,)// pe = "CallExpression";// de.arguments = [t.NumericLiteral(left), t.NumericLiteral(right)];// de.callee = t.functionExpression(null, params, body,)}
}
const visitor9 = {StringLiteral(path) {de.extra;// 发现英文的Unicode形式被还原了,但是中文的没有被还原// 需要给generator(ast,)添加参数{jsescOption:{"minimal":true}}}}
const visitor10 = {VariableDeclarator(path) {const init = ('init');if (init.isFunctionExpression()) {const {init, id} = de;const name = id.name;const params = init.params;if (params.length !== 2) return;let first_arg = params[0].name;let second_arg = params[1].name;const body = init.body;if (!body.body || body.body.length !== 1) return;let return_body = body.body[0];let argument = return_body.argument;if (!t.isReturnStatement(return_body) ||!t.isBinaryExpression(argument)) return;let {left, right, operator} = argument;if (!t.isIdentifier(left, {name: first_arg}) ||!t.isIdentifier(right, {name: second_arg})) return;let scope = path.scope;console.log(scope)traverse(scope.block, {CallExpression: function(_path){let _node = _de;let args = _node.arguments;if (args.length === 2 && t.isIdentifier(_node.callee, {name: name}))_placeWith(t.BinaryExpression(operator, args[0], args[1]))},});}}
};const visitor11 = {}
const visitor12 = {}var jscode = `var a = 123;let b='ccc';`
var jscode1 = `function aaa(a,b){}aaa(1,2);`
var jscode2 = `h[$b('x30x78x37x31', 'x31x21x58x47') + 'x4ax61'] = function (Q, R) {return Q + R;}var num = 0x30+0x31;var $a = ['x77x71x78x70x55x41x3dx3d']`
var jscode3 = `if (!j) {g['setCookie'](['*'], 'counter', 0x1);} else if (j) {i = g['getCookie'](null, 'counter');} else {g['removeCookie']();}(function (_0x1a61bd) {})()['constructor']("while (true) {}")["apply"]("counter");`
var jscode4 = `var a = 123;`
var jscode5 = `function test() {var _0x238e3e = {'puzUT': '4|3|2|1|0', 'Rgtsl': function (_0x3a9ad8, _0x312b1a) {return _0x3a9ad8 < _0x312b1a;}, 'HFHYB': function (_0x13ea88, _0x2533df) {return _0x13ea88 + _0x2533df;}};var _0x388255 = _0x238e3e['puzUT']['split']('|');var _0xfbda52 = 0x0;while (!![]) {switch (_0x388255[_0xfbda52++]) {case'0':return _0x2ce383;case'1':for (var _0x1fa16b = 0x0; _0x238e3e['Rgtsl'](_0x1fa16b, _0x3c5b0c['length']); _0x1fa16b++) {_0x2ce383['push'](String['fromCharCode'](_0x3c5b0c[_0x1fa16b]));}continue;case'2':var _0x2ce383 = [];continue;case'3':_0x3c5b0c[0x0] = _0x238e3e['HFHYB'](_0x3c5b0c[0x0], 0x1);continue;case'4':var _0x3c5b0c = [0x67, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64];continue;}break;}
}
var s = test();`
var jscode6 = `var value = 12345678;`
var jscode7 = `var a=!![],b='hello '+'world '+'!',c=2+3*50,d=Math.abs(-200)%19,e=true ? 123:456;`
var jscode8 = `var a = 123 | 456;`
var jscode9 = `var test ='u4f60u597du4e16u754cu0054u0068u0069u0073u0020u0069u0073u0020u0061u0020u0074u0065u0073u0074u0021'`
var jscode10 = `var Xor = function (p,q){return p ^ q;}let a = Xor(111,222);`
var jscode11 = ``
var jscode12 = ``let ast = parser.parse(jscode10);  //修改此处
// console.log(JSON.stringify(ast,null,'t'))
// traverse(ast,visitor)        //var a = 123;let b='ccc';
// traverse(ast,visitor1)       //aaa(1,2);
// traverse(ast, visitor2)          //将x30x78x37x31转变为可识别字符串,十六进制数值还原成十进制
// traverse(ast, visitor3)          //将a["length"]转变为a.length
// traverse(ast, visitor4)          //插入节点
// traverse(ast, visitor5)             //SwitchCase插入节点,平坦化还原
// traverse(ast, visitor6)             //把12345678拆成两个数的异或操作
// traverse(ast, visitor7)            //合并Literal类型的计算表达式
// traverse(ast, {                     //visitor7 的另一种写法
//     'BinaryExpression|UnaryExpression|ConditionalExpression': {
//         enter: [visitor7_1]
//         //exit: [visitor7_1]
//     }
// })
// traverse(ast, visitor8)   //将 BinaryExpression 类型转换为 CallExpression 类型
// traverse(ast, visitor9)  //将unicode码转为可识别的字符
traverse(ast, visitor10)    //CallExpression  -> BinaryExpression
// traverse(ast, visitor11)
// traverse(ast, visitor12)let {code} = generator(ast,); //第9需要添加参数{jsescOption:{"minimal":true}}
console.log(code)
// fs.writeFile('xxxx.js', code, (err)=>{});

 

本文发布于:2024-01-27 20:48:33,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/17063597132548.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:js
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23