【AST 混淆】五、代码逐行加密(可以指定某一行)

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

思路

遍历FunctionExpression函数节点,然后把其中的 body 逐行加密,然后使用时解密,使用 eval 执行,但是大范围使用,特征太明显,所以可以在 源代码中 写上需要加密行标上注释,就可以指定关键行使用这种混淆方式

let encFun = (str) => {
    return Buffer.from(str, 'utf-8').toString('base64');
}
traverse(ast, {
    FunctionExpression(path) {
        let blockStatement = path.node.body
        let body = blockStatement.body.map((v) => {
            if (type.isReturnStatement(v)) {
                return v; // 返回节点处理
            }
            // 遍历 生成 eval(stob('xxx')) 这种节点
            let code = generator(v).code;
            let cipherText = encFun(code);
            return type.expressionStatement(
                expression = type.callExpression(
                    callee = type.identifier(name = 'eval'),
                    _arguments = [
                        type.callExpression(
                            callee = type.identifier('atob'),
                            _arguments = [type.stringLiteral(cipherText)])]
                )
            )
        })
        path.get('body').replaceWith(type.blockStatement(body = body)) // 替换
    }
})

mark

指定行

指定行就是 判断这一行是否有指定的注释,然后再把 注释删掉

mark

// 指定行 加密
let encFun = (str) => {
    return Buffer.from(str, 'utf-8').toString('base64');
}
traverse(ast, {
    FunctionExpression(path) {
        let blockStatement = path.node.body
        let statement = blockStatement.body.map((v) => {
            if (type.isReturnStatement(v)) {
                return v; // 返回节点处理
            }
            v.leadingComments && v.leadingComments[0].value.replace(' ', '') == 'encrypt' && delete v.leadingComments; // 删 加密标识注释 的兼容处理
            // 判断是否是注释行
            if (!(v.trailingComments && v.trailingComments[0].value.replace(' ', '') == 'encrypt')) {
                return v
            }
            delete v.trailingComments; // 删除注释
            // 遍历 生成 eval(stob('xxx')) 这种节点
            let code = generator(v).code;
            let cipherText = encFun(code);
            return type.expressionStatement(
                expression = type.callExpression(
                    callee = type.identifier(name = 'eval'),
                    _arguments = [
                        type.callExpression(
                            callee = type.identifier('atob'),
                            _arguments = [type.stringLiteral(cipherText)])]
                )
            )
        })
        path.get('body').replaceWith(type.blockStatement(statement)) // 替换
    }
})

mark

发表评论 / Comment

用心评论~