ast还原ob1-多级return返回处理

目标

在这里插入图片描述

先将要处理的目标代码放到ast解析网站中

1.1 找到指定的函数

在这里插入图片描述

const fs = require("fs") //文件操作
const {parse} = require("@babel/parser")  //将js转成ast格式,{parse}=pase.parse
const traverse = require("@babel/traverse").default  //进行遍历节点
const types = require("@babel/types")  //用于增加节点
const generator = require("@babel/generator").default  // 将ast转成js文件


//0 导入要进行处理的js文件
var originJsCode = fs.readFileSync('001 test.js', {encoding: 'utf-8'})

//0.1 将js转成ast
var originAstCode = parse(originJsCode)

try {
    //TODO 1 多级return回调还原,还原之后就要对加密函数进行解密,也就是解密函数的调用
    astCode1 = func_return(originAstCode)
    console.log("<1> 多级return回调还原已完成")

}catch(error){
    console.log(error)
}

/*在上面的是架构,下面的这个函数是具体实现*/
function func_return(astCode){

    let visitor = {
        //1.对函数定义进行遍历
        FunctionDeclaration(path) {
            //对函数的两个过滤
            //1.1 函数体是块语句
            if (types.isBlockStatement(path.node.body)) {
                //1.2 函数体内只有一个元素,就是返回语句,只有符合这两个条件才能进行下一步的操作
                if (types.isReturnStatement(path.node.body.body[0])) {
                        
                    }
                }
        }
    }
    
    traverse(astCode,visitor)

    fs.writeFileSync("03 operate1.js",generator(astCode).code,{encoding:"utf-8"})

    return astCode
}

1.2 找到调用这个函数的地方

在这里插入图片描述

1.因为已经定位到了函数①的位置,可以拿到函数①的作用域,所谓作用域就是该函数定义的作用范围,就拿这个函数①来讲:
在这里插入图片描述

可以通过path.scope()来拿到目标函数的作用域

2.拿到作用域可以对该函数名进行绑定,通过绑定可以找到所有引用该函数名的位置,这个位置就是我们想要的调用该函数的位置
在这里插入图片描述

那么如何才能拿到真正的调用的js代码,并且验证呢?

实际上上面图片中的paths拿到的是一个数组,对数组进行遍历(使用map函数),传入的是一个回调函数,第一个参数就是遍历的数组存放的path节点,拿到path节点后再取它的parentPath才是真正的调用函数代码

在这里插入图片描述

实际上拿到的referPath.parentPath就是ast中的CallExpression:

在这里插入图片描述

这个函数的调用也有两个特征,referPath.parentPath.type要为CallExpression,且referPath.parentPath.callee要为Identifier才行

1.3 按照函数返回的规则对调用进行改写

在这里插入图片描述

代码如下:

在这里插入图片描述
在这里插入图片描述

整体来看函数的结构如下:
在这里插入图片描述

运行一下看一看提示信息和结果:
在这里插入图片描述

来看一看输出的结果:

在这里插入图片描述

在这里插入图片描述

1.4 循环遍历并确定遍历结束的条件

根据上面的结果存在的问题进行改进,首先来手动确定要遍历的次数,假如要循环遍历3次,试一试:

在这里插入图片描述

在这里插入图片描述

处理输出结果:

在这里插入图片描述

那么如何才能确定循环的次数呢?

经过多次的实验,并没有办法能够确定准确的次数,因为结果一次函数的处理得到的结果很可能还要经过另一个函数进行处理。。。

但可以确定的是函数的名称个数,正如上面输出的结果来看,当输出函数名被引用次数为xxx时就将定义的函数名称放入到一个集合当中,如果输出函数名被引用次数为0,进行删除...时就将这个函数名从这个集合中删除,只有当这个集合个数为空(也就是0)时,就可以停止循环遍历。

处理如下:

在这里插入图片描述

在这里插入图片描述

处理结果:

在这里插入图片描述

在这里插入图片描述

1.5 验证

参考文章: https://jia666666.blog.csdn.net/article/details/120267409

根据文章中的例子来验证:

在这里插入图片描述

得到的结果:
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值