{{format('0')}} {{format('304')}} {{format('3484')}}

【AST 混淆】四、代码块的混淆 [ 编程杂谈 ]

大数据男孩 文章 正文

想做一个技术博客,奈何实力不够
分享

明妃

{{nature("2022-08-14 17:23:20")}}更新

特别说明:本文 生成节点时,函数的使用对于 Js 来说是错误的(不能指定参数给值),这样写是方便 看节点属性

二项式 转 函数花指令

花指令用来更好的隐藏 源代码的真实意图,还能增加代码量,增加分析难度

类型一

// 源代码
var num = a + b;

// 变成
function xxx(c, d){
    return c + d;
}
var num = xxx(a, b)

类型二

// 源代码
var num = add(a);

// 变成
function xxx(c, v){
    return c(v);
}
var num = xxx(add, v)

类型一 思路

获取 二项式符号左右部分,然后 生成 函数节点,把函数节点添加到当前代码块最前面,然后把原始二项式 替换为 调用表达式

// 二项式转花指令
traverse(ast, {
    BinaryExpression(path) {
        let operator = path.node.operator;
        let left_ = path.node.left; // 加个下滑线 防止 冲突
        let right_ = path.node.right;

        // 构造函数节点
        let funName = path.scope.generateUidIdentifier('xxx');
        let a = type.identifier(name = 'a');
        let b = type.identifier(name = 'b');
        let func = type.functionDeclaration(
            id = funName,
            params = [a, b],
            body = type.blockStatement(
                body = [type.returnStatement(
                    argument = type.binaryExpression(
                        operator = operator,
                        left=a,
                        right = b
                    )
                )]
            )
        )

        // 把生成的函数节点添加到当前代码的最前面
        let blockStatement = path.findParent(function (p) {
            return p.isBlockStatement()
        })
        blockStatement.node.body.unshift(func);

        // 替换原节点 为 调用表达式
        path.replaceWith(type.callExpression(
            callee = funName, _arguments = [left_, oright_]
        ))
    }
})

[mark]()

类型二 思路

获取 调用表达式函数参数,然后 生成 函数节点,把函数节点添加到当前代码块最前面,然后把原始调用表达式 替换为 新的调用表达式,只处理 一层的 fun('aa') 不处理 fun.fun('aa')

例子

function add(a, b) {
    return a + b;
}

console.log(add(2, 3))

代码

 // 调用表达式 转 花指令
traverse(ast, {
    CallExpression(path) {
        let callee_ = path.node.callee;
        let arguments_ = path.node.arguments;
        if(!type.isIdentifier(callee_)){ // 只处理 一层的 `fun('aa')` 不处理 `fun.fun('aa')`
            return
        }

        // 构造函数节点
        let funName = path.scope.generateUidIdentifier('fff');
        let f = type.identifier(name = 'f') // 第一个参数,是 函数
        let params_ = []; // 参数列表
        for (let arg in arguments_) {
            params_.push(name = path.scope.generateUidIdentifier('arg'))
        }
        let func = type.functionDeclaration(
            id = funName,
            params = [f].concat(params_),
            body = type.blockStatement(
                body = [type.returnStatement(
                    type.callExpression(
                        callee = f, _arguments = params_
                    )
                )]
            )
        )

        // 把生成的函数节点添加到当前代码的最前面
        let blockStatement = path.findParent(function (p) {
            return p.isBlockStatement() || p.isProgram() // 兼容处理 如何函数需要添加到 最外面层
        })
        blockStatement.node.body.unshift(func);

        // 替换原节点 为 调用表达式
        arguments_.unshift(callee_)
        path.replaceWith(type.callExpression(
            callee = funName, _arguments = arguments_
        ))
        path.skip()
    }
})

[mark]()

评论 0
0
{{userInfo.data?.nickname}}
{{userInfo.data?.email}}
TOP 2
Spark 2.0 单机模式与集群模式 安装

{{nature('2020-01-02 16:47:07')}} {{format('12520')}}人已阅读

TOP 3
Office 2016 Pro Plus 激活

{{nature('2019-12-11 20:43:10')}} {{format('9408')}}人已阅读

TOP 4
Linux上 MySQL 开启远程登陆的两种方法

{{nature('2019-12-26 17:20:52')}} {{format('7404')}}人已阅读

TOP 5
Linux 安装 MySQL 5.7

{{nature('2019-12-26 16:03:55')}} {{format('4878')}}人已阅读

目录

标签云

AST基础 AST混淆

一言

# {{hitokoto.data.from || '来自'}} #
{{hitokoto.data.hitokoto || '内容'}}
作者:{{hitokoto.data.from_who || '作者'}}
自定义UI
配色方案

侧边栏