AST去除花指令收集,直接使用ing

const {default: generator} = require("@babel/generator");
const type = require("@babel/types");
const {parse} = require("@babel/parser");
const traverse = require('@babel/traverse').default
function flower_instruction_code (ast_code) {
    this.ast_code = ast_code
    this.all_constant_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
    }
    
    // 替換賦值混淆名
    this.replace_confuse_name = function () {
        let that = this
        traverse(this.ast_code, {
            VariableDeclarator(path) {
                if (type.isIdentifier(path.node.id)) {
                    let can_rename = that.can_rename(path.node.init)
                    if (can_rename) {
                        let binding = path.scope.getOwnBinding(path.node.id.name)
                        if (!binding) {
                            return null
                        }
                        binding.scope.rename(path.node.id.name, path.node.init.name)
                        path.remove()
                    }
                }
            }
        })
    }
    
    // 针对形式:Object['prototype']['hasOwnProperty']["call"](_0x185f56, _0x73e89b)
    this.obj_prototype_hasOwnProperty_call = function () {
        traverse(this.ast_code, {
            'CallExpression'(path) {
                let first_member = path.node.callee
                if (!type.isMemberExpression(first_member) && first_member.property.value !== 'call') {
                    path.stop()
                }
                let second_member = first_member.object
                if (!type.isMemberExpression(second_member) && second_member.property.value !== 'hasOwnProperty') {
                    path.stop()
                }
                let third_member = first_member.object
                if (!type.isMemberExpression(third_member) && third_member.property.value !== 'prototype') {
                    path.stop()
                }
                path.replaceWith(type.valueToNode(false))
            }
        })
    }

    // 针对for循环:for (_0x73e89b in _0x185f56) false && (_0x679414[_0x73e89b]  = _0x185f56[_0x73e89b]);
    this.for_false_and = function () {
        traverse(this.ast_code, {
            'ForInStatement|ForStatement'(path) {
                let left_name = path.node.body.expression.left.name
                if (!eval(left_name)) {
                    path.remove()
                }
            }
        })
    }

    /* 二进制和十六进制干扰,'\x48\x32\x41\x47'*/
    this.binary_hexadecimal = function () {
        traverse(this.ast_code, {
            'StringLiteral|NumericLiteral'(path) {
                delete path.node.extra  // 主要是由于row这个节点造成的
            }
        })
    }

    /* 运算符混淆,示例:'a'+'b'或者1+3 */
    this.binary_confuse = function () {
        traverse(this.ast_code, {
            'BinaryExpression'(path) {
                let has_identifier_in_binary = check_identifier_in_binary(path.node)
                if (!has_identifier_in_binary) {
                    let binary_result = eval(generator(path.node).code)
                    path.replaceWith(type.valueToNode(binary_result))
                }
            },
        })
        // 检查运算符内是否有参数
        function check_identifier_in_binary (node) {
            if (type.isBinaryExpression(node)) {
                let left = check_identifier_in_binary(node.left)
                let right = check_identifier_in_binary(node.right)
                return left || right
            } else if (type.isStringLiteral(node) || type.isNumericLiteral(node) || type.isUnaryExpression(node)) {
                return false
            }
            return true
        }
    }

    /* 针对function形参定义后函数体内赋值混淆,function(a, b, c, d){d=1,console.log(d)} */
    this.params_define_confuse = function () {
        traverse(this.ast_code, {
            AssignmentExpression(path) {
                let name = path.node.left.name
                let binding = path.scope.getOwnBinding(name)
                if (binding && binding.constantViolations.length === 1 && type.isLiteral(path.node.right)) {
                    for (let i = 0; i < binding.referencePaths.length; i++) {
                        binding.referencePaths[i].replaceWith(path.node.right)
                    }
                    path.remove()
                }
            }
        })
    }

    /* 利用解密函数进行加密字符串解密 */
    this.decrypt_string_confuse = function (decrypt_function_list) {
        traverse(this.ast_code, {
            CallExpression(path) {
                if (decrypt_function_list.indexOf(path.node.callee.name) !== -1) {
                    let result = eval(generator(path.node).code)
                    path.replaceWith(type.valueToNode(result))
                }
            }
        })
    }

    /* 成员属性混淆,a['b']='fuck' */
    this.member_attr_confuse = function () {
        let all_member_obj = {}

        // 放入成员对象合集中并去掉复制
        traverse(this.ast_code, {
            AssignmentExpression(path) {
                // 針對a = b這樣直接賦值
                if (type.isIdentifier(path.node.left) && type.isIdentifier(path.node.right) && all_member_obj[path.node.right.name]) {
                    all_member_obj[path.node.left.name] = all_member_obj[path.node.right.name]
                    return
                }

                let member_value = set_and_get_member_attr(path.node)
                if (member_value) {
                    path.remove()
                }
            }
        })
        // 判斷是否對象屬性混淆並保存對象屬性到全局
        function set_and_get_member_attr(node){
            if (!type.isMemberExpression(node.left)) {
                return
            }

            if (!all_member_obj[node.left.object.name]) {
                all_member_obj[node.left.object.name] = {}
            }

            if (type.isLiteral(node.right)) {
                all_member_obj[node.left.object.name][node.left.property.value] = node.right
                return true
            }
            if (type.isMemberExpression(node.right)) {
                let obj_name = node.right.object.name
                let property_value = node.right.property.value
                if (all_member_obj[obj_name] && all_member_obj[obj_name][property_value]) {
                    all_member_obj[node.left.object.name][node.left.property.value] = all_member_obj[obj_name][property_value]
                    return true
                }
            }
        }

        // 进行替换
        traverse(this.ast_code, {
            MemberExpression(path) {
                let obj_name = path.node.object.name
                let property_value = path.node.property.value
                if (all_member_obj[obj_name] && property_value && all_member_obj[obj_name].hasOwnProperty(property_value)) {
                    try {
                        path.replaceWith(all_member_obj[obj_name][property_value])
                    } catch (e) {
                        console.log(generator(path.node).code)
                        path.stop()
                    }
                }
            }
        })
    }

    /* 成员属性方法混淆,_0x434ddb["GXMkb"] = function(_0x2741e5, _0x22b6d0) {return _0x2741e5 + _0x22b6d0;} */
    this.remove_member_attr_function_confuse = function (is_test=false) {
        let member_attr_obj_function = {}
        let js_code = generator(this.ast_code).code
        this.ast_code = parse(js_code)
        /* 收集全部成员属性方法 */
        traverse(this.ast_code, {
            AssignmentExpression(path) {
                let left = path.node.left
                let right = path.node.right
                // 針對a = b這樣直接賦值
                if (type.isIdentifier(left) && type.isIdentifier(right) && member_attr_obj_function[right.name]) {
                    member_attr_obj_function[left.name] = member_attr_obj_function[right.name]
                    return
                }

                if (!type.isMemberExpression(left)) {
                    return
                }

                if (!member_attr_obj_function[left.object.name]) {
                    member_attr_obj_function[left.object.name] = {}
                }

                // 针对:_0x13a684["rYJFX"] = _0x13a684["rsYJFX"]
                if (type.isMemberExpression(right) &&
                    member_attr_obj_function[right.object.name] &&
                    member_attr_obj_function[right.object.name][right.property.value])
                {
                    member_attr_obj_function[left.object.name][left.property.value] = member_attr_obj_function[right.object.name][right.property.value]
                    return ;
                }

                // 针对:_0x13a684["rYJFX"]=function(){return xxxx}
                if (type.isFunctionExpression(right) && type.isReturnStatement(right.body.body[0]))
                {
                    let return_statement = right.body.body[0]

                    // 二项式直接使用,针对:_0x434ddb["vCXqC"]=function(_0x202936,_0x21f1f2){return _0x202936<<_0x21f1f2;}
                    if (type.isBinaryExpression(return_statement.argument)) {
                        member_attr_obj_function[left.object.name][left.property.value] = right
                        if (!is_test){path.remove()}
                        return;
                    }

                    // 函数调用
                    if (type.isCallExpression(return_statement.argument)) {
                        let callee = return_statement.argument.callee
                        // 直接参数嵌套调用,_0x434ddb["RjlFz"] = function(_0x2840c0){return _0x2840c0();}
                        if (type.isIdentifier(callee)) {
                            member_attr_obj_function[left.object.name][left.property.value] = right
                            if (!is_test){path.remove()}
                            return;
                        }
                        // 成员属性函数嵌套调用,_0x13a684["rYJFX"]=function(_0x2f8c0d,_0xb26c0){return _0x5500bb["aGBTS"](_0x2f8c0d, _0xb26c0);}
                        if (type.isMemberExpression(return_statement.argument.callee) &&
                            member_attr_obj_function[callee.object.name] &&
                            member_attr_obj_function[callee.object.name][callee.property.value])
                        {
                            let function_node = member_attr_obj_function[callee.object.name][callee.property.value]
                            let new_return_node = construct_new_return_node(return_statement.argument.arguments, function_node)
                            right.body.body[0] = new_return_node
                            member_attr_obj_function[left.object.name][left.property.value] = right
                            if (!is_test){path.remove()}
                            return;
                        }
                    }
                }
            }
        })
        /* 将原函数重构成依据底层函数改造的新函数 */
        function construct_new_return_node(arguments, function_node) {
            let formal_parameter_dict = {}  // 原调用的实参与方法形参名的对应表
            let params = function_node.params  // 方法参数
            let return_statement = function_node.body.body[0]
            for (let i = 0; i < params.length; i++) {
                if (params[i]) {
                    formal_parameter_dict[params[i].name] = arguments[i] ? arguments[i] : type.valueToNode(null)
                }
            }

            let new_argument = return_statement['argument']
            // 底层是二项式混淆
            if (type.isBinaryExpression(new_argument)) {
                new_argument = get_binary_new_node(new_argument, formal_parameter_dict)
            }

            // 底层是函数调用混淆
            if (type.isCallExpression(return_statement['argument'])) {
                let new_callee = formal_parameter_dict[return_statement['argument'].callee.name]
                let return_arguments = return_statement['argument'].arguments
                let new_arguments = []
                for (let i = 0; i < return_arguments.length; i++) {
                    new_arguments[i] = formal_parameter_dict[return_arguments[i].name]
                }

                try {
                    new_argument = type.callExpression(new_callee, new_arguments)
                } catch (e) {
                    console.log(arguments)
                }
            }

            // 产生新的函数
            return type.returnStatement(new_argument)
        }
        /* 获取二项式新节点 */
        function get_binary_new_node(node, formal_parameter_dict) {
            let left = node.left
            let rignt = node.right
            if (formal_parameter_dict[left.name]) {
                left = formal_parameter_dict[left.name]
            }

            if (type.isBinaryExpression(rignt)) {
                rignt = get_binary_new_node(right, formal_parameter_dict)
            } else if (type.isIdentifier(rignt) && formal_parameter_dict[rignt.name]) {
                rignt = formal_parameter_dict[rignt.name]
            }

            return type.binaryExpression(node.operator, left, rignt)
        }

        /* 成员属性方法替换 */
        traverse(this.ast_code, {
            'CallExpression': {
                exit(path){
                    if (!type.isMemberExpression(path.node.callee)) {
                        return;
                    }
                    let object = path.node.callee.object
                    let property = path.node.callee.property
                    if (member_attr_obj_function[object.name] &&
                        member_attr_obj_function[object.name].hasOwnProperty(property.value))
                    {
                        let function_node = member_attr_obj_function[object.name][property.value]
                        if (!type.isReturnStatement(function_node.body.body[0])) {
                            return;
                        }
                        let formal_parameter_dict = {}
                        for (let i = 0; i < function_node.params.length; i++) {
                            if (path.node.arguments[i]) {
                                formal_parameter_dict[function_node.params[i].name] = path.node.arguments[i]
                            } else {
                                formal_parameter_dict[function_node.params[i].name] = type.valueToNode(undefined)
                            }
                        }
                        let argument = function_node.body.body[0].argument
                        // 嵌套函数调用混淆,function(_0x4fd34e, _0x54cdbe){return _0x4fd34e(_0x54cdbe);}
                        if (type.isCallExpression(argument)) {
                            let new_callee = formal_parameter_dict[argument.callee.name]
                            let return_arguments = argument.arguments
                            let new_arguments = []
                            for (let i = 0; i < return_arguments.length; i++) {
                                new_arguments[i] = formal_parameter_dict[return_arguments[i].name]
                            }
                            path.replaceWith(type.callExpression(new_callee, new_arguments))
                            path.skip()
                        }
                        // 二项式嵌套混淆,function(_0x4fd34e, _0x54cdbe){return _0x485945 * _0x4a409e;}
                        if (type.isBinaryExpression(argument)) {
                            let new_node = get_binary_new_node(argument, formal_parameter_dict)
                            path.replaceWith(new_node)
                            path.skip()
                        }
                    }
                }
            },

            // CallExpression(path) {
            //     if (!type.isMemberExpression(path.node.callee)) {
            //         return;
            //     }
            //     let object = path.node.callee.object
            //     let property = path.node.callee.property
            //     if (object.name === '_0x426597' && property.value === 'eejBg') {
            //         console.log(231)
            //     }
            //     if (member_attr_obj_function[object.name] &&
            //         member_attr_obj_function[object.name].hasOwnProperty(property.value))
            //     {
            //         let function_node = member_attr_obj_function[object.name][property.value]
            //         if (!type.isReturnStatement(function_node.body.body[0])) {
            //             return;
            //         }
            //         let formal_parameter_dict = {}
            //         for (let i = 0; i < function_node.params.length; i++) {
            //             if (path.node.arguments[i]) {
            //                 formal_parameter_dict[function_node.params[i].name] = path.node.arguments[i]
            //             } else {
            //                 formal_parameter_dict[function_node.params[i].name] = type.valueToNode(undefined)
            //             }
            //         }
            //         let argument = function_node.body.body[0].argument
            //         // 嵌套函数调用混淆,function(_0x4fd34e, _0x54cdbe){return _0x4fd34e(_0x54cdbe);}
            //         if (type.isCallExpression(argument)) {
            //             let new_callee = formal_parameter_dict[argument.callee.name]
            //             let return_arguments = argument.arguments
            //             let new_arguments = []
            //             for (let i = 0; i < return_arguments.length; i++) {
            //                 new_arguments[i] = formal_parameter_dict[return_arguments[i].name]
            //             }
            //             path.replaceWith(type.callExpression(new_callee, new_arguments))
            //             path.skip()
            //         }
            //         // 二项式嵌套混淆,function(_0x4fd34e, _0x54cdbe){return _0x485945 * _0x4a409e;}
            //         if (type.isBinaryExpression(argument)) {
            //             let new_node = get_binary_new_node(argument, formal_parameter_dict)
            //             path.replaceWith(new_node)
            //             path.skip()
            //         }
            //     }
            // }
        })
    }

    // 移除IF语句混淆
    this.remove_if_confuse = function () {
        traverse(this.ast_code, {
            IfStatement(path) {
                // 排除无法正常判断的条件
                let if_test_js_code = generator(path.node.test).code
                // 存在變量則會報錯
                try {
                    let judge_result = eval(if_test_js_code)
                    if (judge_result) {
                        let consequent = path.node.consequent
                        // 正常的if语句
                        if (type.isBlockStatement(consequent)) {
                            consequent.body.length > 0 ? path.replaceInline(consequent.body) : null
                        }

                        // 省略了{}的if语句
                        if (type.isExpressionStatement(consequent)) {
                            consequent.expression ? path.replaceInline(consequent.expression) : null
                        }

                        if (type.isEmptyStatement(consequent)) {
                            path.remove()
                        }
                    } else {
                        let alternate = path.node.alternate
                        // 正常的if语句
                        if (type.isBlockStatement(alternate)) {
                            alternate.body.length > 0 ? path.replaceInline(alternate.body) : path.remove()
                        }

                        // 省略了{}的if语句
                        if (type.isExpressionStatement(alternate)) {
                            alternate.expression ? path.replaceInline(alternate.expression) : path.remove()
                        }

                        if (type.isEmptyStatement(alternate)) {
                            path.remove()
                        }
                    }
                } catch (e) {
                    console.log('轉換失敗,JS判斷測試代碼是:' + if_test_js_code)
                }
            }
        })
    }

    // 函数参数内进行变量定义混淆,针对类型:function(a, b) {a=12, b=13, c=a+b}转换成function() {var a=12, var b=13, c=a+b}配合参数先定义后赋值混淆使用
    this.function_params_define_confuse = function () {
        // 收集函数对应的真正使用的参数长度
        let real_function_params_length = {}
        // 进行收集
        traverse(this.ast_code, {
            CallExpression(path) {
                let callee = path.node.callee
                let arguments = path.node.arguments
                // 自执行函数:
                if (type.isFunctionExpression(callee)) {
                    // 针对非匿名自执行函数:(function test(){})()
                    if (type.isIdentifier(callee.id)) {
                        real_function_params_length[callee.id.name] = arguments.length
                    } else if (!callee.id){
                        // 针对匿名函数自执行形式:(function (){})()
                        solve_function_params_confuse(callee, arguments)
                    }
                }
                // 函数调用,针对形式:$dbsm_0x37d29a(_0x2608da, OooIi1);
                if (type.isIdentifier(callee)) {
                    // 如果没有记录该函数或者记录的传参长度小于本地传参,则直接记录下来
                    if (!real_function_params_length[callee.name] || real_function_params_length[callee.name] < arguments.length){
                        real_function_params_length[callee.name] = arguments.length
                    }
                }
            }
        })

        // 进行替换
        traverse(this.ast_code, {
            // 针对类型:function test(){}
            FunctionExpression(path) {
                if (type.isIdentifier(path.node.id) && real_function_params_length.hasOwnProperty(path.node.id.name)) {
                    solve_function_params_confuse(path.node, real_function_params_length[path.node.id.name])
                }
            },
            // 针对赋值类型:var test = function (_0x2608da, OooIi1, qQOQo0, OOQQ1I, qoo1ql) {}
            VariableDeclarator(path) {
                if (!type.isFunctionExpression(path.node.init) || !type.isIdentifier(path.node.id)) {
                    return;
                }
                solve_function_params_confuse(path.node.init, real_function_params_length[path.node.id.name])
            }
        })

        // 将函数参数里进行定义的变量,改成函数内进行定义
        function solve_function_params_confuse(functionExpression_node, arguments_length) {
            let params = functionExpression_node.params
            let body = functionExpression_node.body.body
            let new_params = []
            for (let i = 0; i < params.length; i++) {
                if (i < arguments_length) {
                    new_params.push(params[i])
                } else {
                    // 向body里插入定义
                    body.unshift(type.variableDeclaration('var', [type.variableDeclarator(params[i], null)]))
                }
            }
            functionExpression_node.params = new_params
        }
    }

    // 针对参数先定义后赋值混淆,var a;a = 2
    this.assignment_after_define_confuse = function () {
        let assignment_after_define_obj = {}
        // 收集全部定义参数
        traverse(this.ast_code, {
            VariableDeclarator(path) {
                if (!type.isIdentifier(path.node.id) || path.node.init) {
                    return;
                }

                let binding = path.scope.getOwnBinding(path.node.id.name)
                let constantViolations = binding.constantViolations
                // 只进行一次赋值将引用全部修改
                if (constantViolations.length === 1 && constantViolations[0].isAssignmentExpression()) {
                    let right = constantViolations[0].node.right
                    if (type.isLiteral(right)) {
                        assignment_after_define_obj[path.node.id.name] = right
                        constantViolations[0].remove()
                    } else if (type.isIdentifier(right) && assignment_after_define_obj.hasOwnProperty(right.name)) {
                        assignment_after_define_obj[path.node.id.name] = assignment_after_define_obj[right.name]
                        constantViolations[0].remove()
                    } else {
                        return;
                    }
                }
            },
            // 替换值
            Identifier(path) {
                // 排除掉定义,赋值和没保存在对象中的变量
                if (path.parentPath.isVariableDeclarator() ||
                    path.parentPath.isAssignmentExpression() ||
                    !assignment_after_define_obj.hasOwnProperty(path.node.name)) {
                    return;
                }

                path.replaceWith(assignment_after_define_obj[path.node.name])
            }
        })
    }

    // 去除不被引用的定义变量
    this.remove_unuseful_variable = function () {
        let js_code = generator(this.ast_code).code
        this.ast_code = parse(js_code)
        traverse(this.ast_code, {
            VariableDeclarator(path) {
                let binding = path.scope.getBinding(path.node.id.name)
                if (binding && !binding.referenced) {
                    path.remove()
                }
            }
        })
    }

    // 去除(0, b[$_BHHGs(175)])()这样的混淆
    this.remove_zero_call_function = function () {
        traverse(this.ast_code, {
            CallExpression(path) {
                let callee = path.node.callee
                if (!type.isSequenceExpression(callee)) {
                    return
                }
                let expressions = callee.expressions
                if (expressions.length === 2 && type.isLiteral(expressions[0]) && expressions[0].value === 0) {
                    path.replaceWith(type.callExpression(expressions[1], path.node.arguments))
                }
            }
        })
    }

    // 特殊函数赋值替换,初始化行数+{被赋值后的变量名:原方法名}
    this.special_function_assign_replace = function (init_line_row, assign_name_source_name) {
        let init_ast_code = parse('')
        for (let i = 0; i < init_line_row; i++) {
            init_ast_code.program.body.push(this.ast_code.program.body[i])
        }
        let init_code = generator(init_ast_code, {'compact': true}).code
        init_code = "const {JSDOM} = require('jsdom');" +
            "const dom = new JSDOM('<!DOCTYPE html><p>Hello world</p>');" +
            "var {window} = dom;" +
            "var {document} = window;" +
            "var {navigator} = window;" +
            init_code
        eval(init_code)

        traverse(this.ast_code, {
            CallExpression(path) {
                let callee = path.node.callee
                if (assign_name_source_name[callee.name]) {
                    // 赋值到变量
                    eval('var ' + callee.name + '=' + assign_name_source_name[callee.name])
                    // 生成值
                    var result = eval(generator(path.node).code)
                    path.replaceWith(type.valueToNode(result))
                }
            }
        })
    }
}

基础使用:

const fs = require('fs');
input_file_path = "./encoding.js"
output_file_path = "./decoding.js"
let sourceCode = fs.readFileSync(input_file_path, {encoding: "utf-8"});
let ast = parse(sourceCode);
parse_tool = new flower_instruction_code(ast)
// 这里初始化解析函数
init_code = parse_tool.get_init_js_code([0, 1, 2])
eval(init_code)
parse_tool.binary_hexadecimal()
parse_tool.replace_confuse_name()
parse_tool.decrypt_string_confuse(['解密函数名'])
let {code} = generator(ast, opts = {jsescOption:{"minimal":true}});
fs.writeFile(output_file_path, code, (err) => {});
console.log('完成')
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值