AST嵌套解密函数:传参数量混淆+传参乱序混淆+传参加入运算符混淆

传参乱序+传参加入运算符

  1. 案例代码:
// 解密函数
function _0x1313(_0xa597ae, _0x23dcdc) {}

_0x1d90d1 = function(_0x4d75b8, _0x6bc281, _0x38b421, _0xc12c0b, _0x4626cc) {
    return _0x1313(_0x4626cc - 0x164, _0xc12c0b);
}
_0x18c3fa = function(_0x2a92a3, _0x560b5b, _0x159389, _0x11cce9, _0x3578bf) {
    return _0x1313(_0x3578bf - 0x164, _0x11cce9);
}
_0x4d3356[_0x18c3fa(0x501, 0xa8c, 0xf98, '4[E4', 0xa3a)] = _0x1d90d1(0xa4d, 0xa8a, 0xb90, 'xVxp', 0x8aa),
  1. 逆向代码
function parseTools(ast_code)
{
    this.ast_code = ast_code
    this.decrypt_function = {}
    // 1.输出初始化的代码获取解密字符串的函数
    this.get_init_js_code = function (init_code_row) {
        let init_ast_code = parse('')
        for (let i = 0; i < init_code_row.length; i++) {
            init_ast_code.program.body.push(this.ast_code.program.body[init_code_row[i]])
        }
        return generator(init_ast_code, {'compact': true}).code
    }

    // 2.嵌套加密函数脱壳并获取所有的解密函数
    this.get_all_decrypt_function = function () {
        let that = this
        traverse(this.ast_code, {
            VariableDeclarator(path) {
                if (type.isFunctionExpression(path.node.init) &&
                    type.isReturnStatement(path.node.init.body.body[0]) &&
                    type.isCallExpression(path.node.init.body.body[0].argument)
                    // && path.node.init.body.body[0].argument.callee.name === '_0x1313'
                ) {
                    let function_call_expression = that.parse_nest_function(path.node.init, path.node.init.params)
                    if (function_call_expression) {
                        if (!that.decrypt_function[path.node.id.name]) {
                            that.decrypt_function[path.node.id.name] = {}
                        }
                        path.node.init.body.body[0] = type.returnStatement(function_call_expression)
                        that.decrypt_function[path.node.id.name] = path.node.init
                    }
                }
            }
        })
    }

    // 脱壳查找加密函数,arguments是实参
    this.parse_nest_function = function (function_node, arguments) {
        if (!type.isReturnStatement(function_node.body.body[0]) ||
            !type.isCallExpression(function_node.body.body[0].argument)) {
            return false
        }

        let function_callee = function_node.body.body[0].argument.callee

        if (!this.decrypt_function[function_callee.name] && function_callee.name !== '_0x1313') {
            return false
        }

        let source_params = function_node.params // 当前函数的参数
        let function_params = function_node.body.body[0].argument.arguments // 传递给下一个函数的参数
        // 获取参数名和对应的下标组成键值对
        let param_name_index = {}
        for (let i = 0; i < source_params.length; i++) {
            param_name_index[source_params[i].name] = i
        }

        let new_arguments = []
        for (let i = 0; i < function_params.length; i++) {
            new_arguments.push(this.change_node_by_type(function_params[i], param_name_index, arguments))
        }
        arguments = new_arguments
        if (function_callee.name === '_0x1313') {
            return type.callExpression(function_callee, arguments)
        }
        return this.parse_nest_function(this.decrypt_function[function_callee.name], arguments)
    }

    // 根据传入给下个函数的参数转成不同的节点
    this.change_node_by_type = function (argument, params_name_index, arguments) {
        if (type.isIdentifier(argument)) {
            return arguments[params_name_index[argument.name]]
        }

        if (type.isBinaryExpression(argument)) {
            let left = this.change_node_by_type(argument.left, params_name_index, arguments)
            let right = this.change_node_by_type(argument.right, params_name_index, arguments)
            return type.binaryExpression(argument.operator, left, right)
        }
        return argument
    }

    // 根据类型产生节点
    this.binary_expression_create_code = function (source_node, argument_node) {
        if (type.isIdentifier(source_node)) {
            return source_node
        }
        if (type.isBinaryExpression(source_node)) {

        }
    }

    // 3.转换嵌套混淆函数,全部转成_0x1313 TODO 这里可能存在BUG,自动转换了全部
    this.change_nest_confuse_function = function () {
        let that = this
        traverse(this.ast_code, {
            CallExpression(path) {
                if (type.isIdentifier(path.node.callee) && that.decrypt_function[path.node.callee.name]) {
                    let nest_decrypt_function = that.decrypt_function[path.node.callee.name]
                    let source_params = path.node.arguments

                    // 获取参数名和对应的下标组成键值对
                    let params_name_index = {}
                    for (let i = 0; i < nest_decrypt_function.params.length; i++) {
                        params_name_index[nest_decrypt_function.params[i].name] = i
                    }
                    let arguments = []
                    let call_function_params = nest_decrypt_function.body.body[0].argument.arguments // 调用解密函数时传入的参数
                    for (let i = 0; i < call_function_params.length; i++) {
                        let new_node = that.parse_confuse_by_node(call_function_params[i], params_name_index, source_params)
                        arguments.push(new_node)
                    }

                    path.replaceWith(type.callExpression(nest_decrypt_function.body.body[0].argument.callee, arguments))
                    path.skip()
                }
            }
        })
    }

    // 解析嵌套加密函数,并返回一个新的函数
    this.parse_confuse_by_node = function (node, params_name_index, source_params) {
        if (type.isIdentifier(node)) {
            return source_params[params_name_index[node.name]]
        } else if (type.isBinaryExpression(node) && type.isIdentifier(node.left)) {
            node.left = source_params[params_name_index[node.left.name]]
            return node
        }
        return node
    }

let parse_tools = new parseTools(ast_code)
parse_tools.get_all_decrypt_function()

利用eval函数去解密嵌套加密函数

function parseTools(ast_code, decrypt_function_name)
{
    this.ast_code = ast_code
    this.decrypt_function_name = decrypt_function_name
    this.all_define_obj = {}
    // 1.输出初始化的代码获取解密字符串的函数
    this.get_init_js_code = function (init_code_row) {
        let init_ast_code = parse('')
        for (let i = 0; i < init_code_row.length; i++) {
            init_ast_code.program.body.push(this.ast_code.program.body[init_code_row[i]])
        }
        return generator(init_ast_code, {'compact': true}).code
    }

    // 2.获取所有对象以及其属性
    this.generate_all_obj = function () {
        let that = this
        traverse(this.ast_code, {
            VariableDeclarator(path) {
                if (type.isIdentifier(path.node.init)) {
                    that.all_define_obj[path.node.id.name] = that.all_define_obj[path.node.init.name]
                } else {
                    that.all_define_obj[path.node.id.name] = path.node.init
                }
            },
            AssignmentExpression(path) {
                if (type.isMemberExpression(path.node.left)) {
                    if (!that.all_define_obj[path.node.left.object.name]) {
                        that.all_define_obj[path.node.left.object.name] = {}
                    }
                    that.all_define_obj[path.node.left.object.name][path.node.left.property.value] = path.node.right
                }
            }
        })
    }

    // 3.解析字符串混淆
    this.parse_string_confuse = function () {
        let that = this
        traverse(this.ast_code, {
            CallExpression(path) {
                // type.isMemberExpression(path.parentPath) &&
                if (!type.isReturnStatement(path.parentPath) &&type.isIdentifier(path.node.callee) && path.node.callee.name !== '$') {
                    let need_init_function_name_list = that.find_need_init_function(path.node.callee.name, [path.node.callee.name])
                    if (need_init_function_name_list.length > 0) {
                        for (let i = 0; i < need_init_function_name_list.length; i++) {
                            let function_name = need_init_function_name_list[i]
                            let init_function = type.variableDeclaration('var',
                                [type.variableDeclarator(type.identifier(function_name), that.all_define_obj[function_name])]
                            )
                            eval(generator(init_function).code)
                        }
                        let run_result = eval(generator(path.node).code)
                        path.replaceWith(type.valueToNode(run_result))
                    }
                }
            }
        })
    }

    // 寻找需要初始化的嵌套函数
    this.find_need_init_function = function (callee_name, need_init_function_list) {
        let function_expression = this.all_define_obj[callee_name]
        if (!function_expression || !function_expression.body) {
            return []
        }
        // 判断是否嵌套函数
        if (function_expression.body.body.length === 1 && type.isCallExpression(function_expression.body.body[0].argument)) {
            let new_callee_name = function_expression.body.body[0].argument.callee.name

            if (new_callee_name === this.decrypt_function_name) {
                return need_init_function_list
            }

            // 下一个还是嵌套函数继续解析
            if (this.all_define_obj[new_callee_name]) {
                need_init_function_list.push(new_callee_name)
                return this.find_need_init_function(new_callee_name, need_init_function_list)
            }
        }
        return []
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Python标准库`ast`模块中,`filter`方法的第一个数期望一个callable对象,这个callable对象的作用是对AST语法树中的每个节点进行判断,如果判断结果为True,则将该节点筛选出来。 在`javalang`中,`filter`方法的第一个数也期望一个callable对象,这个callable对象的作用是对Java语法树中的每个节点进行判断,如果判断结果为True,则将该节点筛选出来。 因此,不同的解析工具对于`filter`方法的第一个数期望的类型可能不同,需要根据具体的解析工具来确定。 通常情况下,我们可以定义一个函数作为`filter`方法的第一个数,这个函数需要接受一个数,表示当前需要判断的节点,根据节点的类型和属性进行判断并返回True或False。例如,如果我们想要筛选Python代码中的`print`语句,可以定义如下的筛选函数: ```python import ast def filter_print_nodes(node): if isinstance(node, ast.Call) and isinstance(node.func, ast.Name) and node.func.id == 'print': return True else: return False ``` 这个函数接受一个数`node`,表示当前需要判断的节点,根据节点的类型和属性进行判断,如果节点是一个`Call`节点,函数名为一个`Name`节点,函数名为`print`,则返回True,否则返回False。 然后,我们就可以使用`filter`方法对AST语法树进行筛选: ```python print_nodes = list(filter(filter_print_nodes, ast_tree.body)) ``` 注意,不同解析工具对于节点类型和属性的定义可能不同,需要根据具体的解析工具来定义对应的筛选函数

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值