ast反混淆进阶--自执行空实参替换顺序语句

实现目的:自执行空实参替换顺序语句
处理前:
(function() {
    b = 123;
    c = 456;
}())
处理后:
b = 123;
c = 456;
demo.js

//第一种自执行无参数
(function () {
    b = 123;
    c = 456;
    console.log(c);
}());
//第一种自执行带参数
(function (a) {
    if (!a) {
        a = 10
    }
    b = 123;
    c = 456;
    console.log(a);
}());
//第二种,自执行不带参数
!function () {
    b = 123;
    c = 456;
    console.log(b);
}();
//第二种,自执行带参数
!function (a) {
    if (!a) {
        a = 20
    }
    b = 123;
    c = 456;
    console.log(a);
}();
dec_main.js

const fs = require("fs");//文件读写
const parse = require("@babel/parser"); //解析为ast
const traverse = require('@babel/traverse').default;//遍历节点
const t = require('@babel/types');//类型
const generator = require('@babel/generator').default;//ast解析为代码


//读取js文件
const jscode = fs.readFileSync(
    './demo.js', {
        encoding: 'utf-8'
    }
);
let ast = parse.parse(jscode);//js转ast
function delConvParam(path) {
    // 替换空参数的自执行方法为顺序语句
    let node = path.node;//路径节点
    let node_exp = node.expression;//节点表达式

    //回调表达式|一元表达式
    if (!t.isCallExpression(node_exp) && !t.isUnaryExpression(node_exp))
        return;
    //实参列表为空且长度不大于0
    if (node.expression.arguments !== undefined && node.expression.arguments.length > 0)
        return;
    if(t.isUnaryExpression(node_exp)&&node_exp.operator=='!'){//第二种自执行修改为第一种类型
        node_exp=node_exp.argument;
    }
    if (t.isCallExpression(node_exp)) {//第一种自执行
        if (!t.isFunctionExpression(node_exp.callee))//函数表达式判断
            return;
        let paramsList=node_exp.callee.params//形参列表
        if(paramsList.length>0){
            paramsList.map(function (letname){
                if(t.isIdentifier(letname)){
                    //定义一个变量,并添加到结构体中
                    let varDec = t.VariableDeclarator(t.identifier(letname.name))//
                    let localAST = t.VariableDeclaration('var', [varDec]);//
                    node_exp.callee.body.body.unshift(localAST);//添加
                }
            })
        }
        // 替换节点
        path.replaceInline(node_exp.callee.body.body);
    }

}
traverse(ast, {ExpressionStatement: delConvParam,})      // 替换空参数的自执行方法为顺序语句

let {code} = generator(ast,opts = {jsescOption:{"minimal":true}})
//文件保存
fs.writeFile('./demoNew.js', code, (err) => {
});
demoNew.js

//第一种自执行无形参
b = 123;
c = 456;
console.log(c);
//第一种自执行有形参
var a;
if (!a) {
    a = 10;
}
b = 123;
c = 456;
console.log(a);

//第二种自执行无形参
b = 123;
c = 456;
console.log(b);
//第二种自执行有形参
var a;
if (!a) {
    a = 20;
}
b = 123;
c = 456;
console.log(a);
优化及说明:
一、优化自执行种类适配
原来:只适配第一种自执行类型
现在:适配两种自执行类型
二、可以携带形参
原来:形参与实参都为空
现在:现在可以允许有形参,处理后,会将形参重新定义
需要注意:形参重新定义,会涉及作用域,存在同名等问题会冲突报错,
三、尽可能维护上下文,不修改执行逻辑依赖的变量,更安全

ast反混淆进阶--自执行实参替换形参
https://jia666666.blog.csdn.net/article/details/120301341
推荐搭配:自执行实参替换形参+执行自执行空实参替换顺序语句,效果较佳

须知:自执行空实参替换顺序语句作用域问题
1.原来语句的作用域会提升到上一级作用域(局部->全局等情况)
2.若上一级作用域存在同名/已定义的变量,会影响上下文,且失去简化意义
3.谨慎执行此操作,若风险自己可控,建议执行

------------------------------------------------------------
特别说明及感谢:
此处核心源码来自于作者:丁仔
参考ob解混淆源码
https://github.com/DingZaiHub/ob-decrypt
----------------------------------------------------------
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jia666666

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值