美文网首页
尝试还原jsvmp-1

尝试还原jsvmp-1

作者: 周周周__ | 来源:发表于2023-04-06 00:06 被阅读0次

    慢更费脑!!! 有一起讨论的首页小企鹅

    参考文章系列
    1、某乎x96参数与jsvmp初体验
    2、给"某音"的js虚拟机写一个编译器
    3、如何用AST还原某音的JSVMP
    4、VM防护介绍及企鹅滑块分析

    本系列重在尝试,思路不一定对

    主要的参考还是上述参考文章2
    以大佬的开源项目的进行测试还原。

    1、测试效果

    总结:每一个代码块 即js中函数的{}或者AST的BlockStatement 会进入到一个jsvmp的循环中,这也是为什么我们能看到那么多次进入到循环

    简单加翻译日志(20230425)

    待加密代码

    "function add(a, b){return a+b}; add(1, 3);add(2, 3)"
    

    加密后密文,运行逻辑在最后边代码块

    var codestr = `y'l l!b+ s1l1z.!.#["c~2l1z.".#["c~3`
    

    输出日志信息

    修改作用域,将参数前置到当前vm_var
    将var 0 = {} 放入vm_var
    y'l l!b+ s1l1z.!.#["c~2l1z.".#["c~3
    初始化函数
    声明变量var_ 17 = [Function: anonymous_function] {
      body_str: 'l l!b+ ',
      entry: [Function: vmRun]
    }
    创建函数: var_17
    取出var_ 17   放入vm_stack: [
      [Function: anonymous_function] {
        body_str: 'l l!b+ ',
        entry: [Function: vmRun]
      }
    ]
    将值 1 入栈
    将值 3 入栈
    由此进入函数内部开始执行。。。。。
    修改作用域,将参数前置到当前vm_var
    将var 0 = 1 放入vm_var
    将var 1 = 3 放入vm_var
    l l!b+
    取出var_ 0   放入vm_stack: [ 1 ]
    取出var_ 1   放入vm_stack: [ 1, 3 ]
    计算结果并放进堆栈: [ 4, 3 ]
    结束当前循环, 并将结果返回 4
    取出var_ 17   放入vm_stack: [
      4,
      [Function: anonymous_function] {
        body_str: 'l l!b+ ',
        entry: [Function: vmRun]
      },
      [ 1, 3 ],
      3
    ]
    将值 2 入栈
    将值 3 入栈
    由此进入函数内部开始执行。。。。。
    修改作用域,将参数前置到当前vm_var
    将var 0 = 2 放入vm_var
    将var 1 = 3 放入vm_var
    l l!b+
    取出var_ 0   放入vm_stack: [ 2 ]
    取出var_ 1   放入vm_stack: [ 2, 3 ]
    计算结果并放进堆栈: [ 5, 3 ]
    结束当前循环, 并将结果返回 5
    []
    [89,83,76,90,14,14,59,67,94,76,90,14,14,59,67,94,null]
    

    待运行代码块

    var codestr = `上边密文`
    let deepClone = function (obj) {
        let _tmp = JSON.stringify(obj);//将对象转换为json字符串形式
        let result = JSON.parse(_tmp);//将转换而来的字符串转换为原生js对象
        return result;
    };
    
    function vmExpression_single_calc(symbol, opNum1) {
        switch (symbol) {
            case "!":
                return !opNum1
            case "+":
                return +opNum1
            case "-":
                return -opNum1
            case "~":
                return ~opNum1
            default:
                return undefined
        }
    }
    
    function vmExpression_calc(symbol, opNum2, opNum1) {
        switch (symbol) {
            case "!":
                return !opNum1
            case "*":
                return opNum1 * opNum2
            case "/":
                return opNum1 / opNum2
            case "%":
                return opNum1 % opNum2
            case "+":
                return opNum1 + opNum2
            case "-":
                return opNum1 - opNum2
            case "<<":
                return opNum1 << opNum2
            case ">>":
                return opNum1 >> opNum2
            case ">>>":
                return opNum1 >>> opNum2
            case ">":
                return opNum1 > opNum2
            case "<":
                return opNum1 < opNum2
            case ">=":
                return opNum1 >= opNum2
            case "<=":
                return opNum1 <= opNum2
            case "==":
                return opNum1 == opNum2
            case "===":
                return opNum1 === opNum2
            case "!==":
                return opNum1 !== opNum2
            case "!=":
                return opNum1 != opNum2
            case "&":
                return opNum1 & opNum2
            case "~":
                return ~opNum
            case "^":
                return opNum1 ^ opNum2
            case "|":
                return opNum1 | opNum2
            case "&&":
                return opNum1 && opNum2
            case "||":
                return opNum1 || opNum2
            case "=":
                return opNum1 = opNum2
            case "*=":
                return opNum1 *= opNum2
            case "/=":
                return opNum1 /= opNum2
            case "%=":
                return opNum1 %= opNum2
            case "&=":
                return opNum1 &= opNum2
            case "+=":
                return opNum1 += opNum2
            case "-=":
                return opNum1 -= opNum2
            case "<<=":
                return opNum1 <<= opNum2
            case ">>=":
                return opNum1 >>= opNum2
            case "^=":
                return opNum1 ^= opNum2
            case "|=":
                return opNum1 ^= opNum2
            default:
                return undefined
        }
    }
    
    function init_vm() {
    
        var e = {}
    
        var instance_run = (function anonymous() {
            function vmExpression(symbol, opNum2, opNum1) {
                //var raw = pthis_Functions("x,y", "return x " + symbol + " y")(opNum1, opNum2)
                var now = vmExpression_calc(symbol, opNum2, opNum1)
                return now
            }
    
            function vmExpression_single(symbol, opNum) {
                //var raw = pthis_Functions("x", "return " + symbol + "x")(opNum)
                var now = vmExpression_single_calc(symbol, opNum)
                return now
            }
    
            function vmNewObject(vm_stack, obj_point, argNum) {
                //return (k[argNum] || (k[argNum] = pthis_Functions("x,y", "return new x[y](" + Array(argNum + 1).join(",x[++y]").substr(1) + ")")))(vm_stack, obj_point)
            }
    
            function vmEnter(codes, argumentss, vars) {
                var n,
                    t,
                    i,
                    s = {}
                b = s.d = vars ? vars.d + 1 : 0;
                for (s["$" + b] = s, t = 0; t < b; t++) {
                    s[n = "$" + t] = vars[n];
    
                    //������һ�����ȡ, Ϊ�˼��ݱ��뷽ʽ
                    for (i in vars) {
                        if (parseInt(i) >= 15 && i.indexOf('$') < 0)
                            s[i] = vars[i]
                    }
    
                }
                console.log("修改作用域,将参数前置到当前vm_var")
                for (t = 0, b = s.length = argumentss.length; t < b; t++) {
                    console.log("将var", t, "=", argumentss[t], "放入vm_var")
                    s[t] = argumentss[t];
                }
                return vmRun(codes, 0, s)
            }
    
            function vmRun(codes, index, vm_vars) {
                function vm_push(e) {
                    vm_stack[vm_esp++] = e
                }
    
                function vm_substring() {
                    g = codes.charCodeAt(index++) - 32
                    var str = codes.substring(index, index += g)
                    return str
                }
    
                function call() {
                    try {
                        y = vmRun(codes, index, vm_vars)
                    } catch (e) {
                        h = e,
                            y = call //�쳣��
                    }
                }
    
                var num_znb = [];
                var ast_body = []; // 代码块
                var my_stack = []; // 记录堆栈的值
                var my_esp = 0; // 记录堆栈中数据操作的索引
                var my_var_vm = []; // 记录变量的堆栈
                console.log(codes)
                for (var h, y, d, g, vm_stack = [], vm_esp = 0; ;) {
                    g = codes.charCodeAt(index++) - 32
                    num_znb.push(g)
    
                    // console.log(g, vm_stack, vm_esp)
                    // console.log("vm_vars:",vm_vars)
    
                    if (Number.isNaN(g)) {
                        console.log(ast_body)
                        console.log(JSON.stringify(num_znb))
                        break
                    }
                    switch (g) {
                        case 1:
                            vm_push(!vm_stack[--vm_esp]);
                            break;
                        case 4:
                            vm_stack[vm_esp++] = vm_substring();
    
                            break;
                        case 5:
                            vm_push(function (e) {
                                var a = 0,
                                    r = e.length; //ȡ����
                                return function () {
                                    var c = a < r; //�жϳ����Ƿ����0
                                    return c && vm_push(e[a++]), //�����߼���һ��û�з���ֵ�ĺ���, ���һ����undefined
                                        c
                                }
                            }
                            (vm_stack[--vm_esp]));
    
                            break;
                        case 6:
                            y = vm_stack[--vm_esp]
                            var func = vm_stack[--vm_esp]
                            var result = func(y)
                            vm_push(result);
    
                            break;
                        case 8: //���ú�������һ�ַ�ʽ
                            if (g = codes.charCodeAt(index++) - 32, //ȡ������VM�ֽ���
                                call(), //���ú���
                                index += g, //����ִ�����, eip+VM�ֽ���
                                g = codes.charCodeAt(index++) - 32,
                            y === vmRun) //y�Ƿ���ֵ
                                index += g;
                            else if (y !== call) {
    
                                return y; //����y
                            }
    
                            break; //�޷���ֵ
                        case 9:
                            vm_stack[vm_esp++] = vmRun;
    
                            break;
                        case 10:
                            vm_push(s(vm_stack[--vm_esp])); //����ִ�в�����, û��s����
                            break;
                        case 11:
                            y = vm_stack[--vm_esp],
                                x = vm_stack[--vm_esp],
                                vm_push(x + y);
    
                            break;
                        case 12:
                            for (y = vm_substring(), d = [], g = 0; g < y.length; g++)
                                d[g] = y.charCodeAt(g) ^ g + y.length;
                            str = String.fromCharCode.apply(null, d)
                            vm_push(str);
    
                            break;
                        case 13:
                            y = vm_stack[--vm_esp],
                                obj = vm_stack[--vm_esp][y]
    
                            //h = delete obj;
                            break;
                        case 14: // 将后一个值入栈
                            g = codes.charCodeAt(index++) - 32;
                            console.log("将值", g, "入栈")
                            vm_stack[vm_esp++] = g
                            ///////////////////////////////////////////
                            my_stack[my_esp++] = g
                            ///////////////////////////////////////////
                            break;
                        case 59: // 截取函数的参数放进数组,并放入堆栈
                            g = codes.charCodeAt(index++) - 32
                            var end = vm_esp
                            var begin = vm_esp -= g
                            ary = g ? vm_stack.slice(begin, end) : []
                            vm_push(ary);
    
                            break;
                        case 61:
                            var temp = vm_stack[--vm_esp][codes.charCodeAt(index++) - 32]
                            vm_push(temp)
                            //var index = vm_esp - 1;
    
                            break;
                        case 62:
                            g = vm_stack[--vm_esp]
                            vm_vars[0] = 65599 * vm_vars[0] + vm_vars[1].charCodeAt(g) >>> 0;
    
                            break;
                        case 65:
                            h = vm_stack[--vm_esp],
                                y = vm_stack[--vm_esp],
                                vm_stack[--vm_esp][y] = h;
    
                            break;
                        case 66: // 进行计算的位置
                            vm_push(vmExpression(codes[index++], vm_stack[--vm_esp], vm_stack[--vm_esp]));
                            console.log('计算结果并放进堆栈:', vm_stack)
                            ////////////////////////////////////////////////////
                            my_esp = vm_esp
                            var var_1 = my_stack[my_esp]
                            var var_2 = my_stack[--my_esp]
                            // 当不是变量赋值,是直接的数字时,需要判断
                            var test = var_2 + codes[index - 1] + var_1
                            my_stack[my_esp] = test
                            ////////////////////////////////////////////////////
                            break;
                        case 67: // 分别将函数和参数取出,并执行后将结果推进堆栈
                            y = vm_stack[--vm_esp]
                            d = vm_stack[--vm_esp]
                            g = vm_stack[--vm_esp]
                            console.log("由此进入函数内部开始执行。。。。。")
                            if (g.x === vmRun)
                                vm_push(vmEnter(g.y, y, vm_vars))
                            else
                                vm_push(g.apply(d, y))
                            break;
                        case 68:
                            var symbol;
                            g = codes[index++]
                            if (g < "<") {
                                index--
                                symbol = vm_substring()
                            } else
                                symbol = g + g
                            vm_push(vmExpression(symbol, vm_stack[--vm_esp], vm_stack[--vm_esp]));
    
                            break;
                        case 70:
                            vm_push(!1);
    
                            break;
                        case 71:
                            vm_stack[vm_esp++] = pthis;
    
                            break;
                        case 72:
                            vm_stack[vm_esp++] = +vm_substring();
    
                            break;
                        case 73:
                            vm_push(parseInt(vm_substring(), 36));
    
                            break;
                        case 75:
                            ////////////////////////////////////////////////////
                            if (vm_stack[vm_esp]) {
                                ast_body.push('if (' + my_stack[my_esp] + ')')
                            }
    
    
                            ////////////////////////////////////////////////////
                            if (vm_stack[--vm_esp]) {
                                index++;
                                break
                            }
    
    
                        case 74: //������������, ������ѭ�������
                            g = codes.charCodeAt(index++) - 32
                            g = g << 16 >> 16
    
                            index += g;
                            break;
                        case 76: // 将后一个code对应的变量追加vm_stack
                            var vars_idx = codes.charCodeAt(index) - 32;
                            vm_push(vm_vars[codes.charCodeAt(index++) - 32]);
                            console.log('取出var_',codes.charCodeAt(index - 1) - 32, "  放入vm_stack:", vm_stack)
                            //////////////////////////////////////////////////////
                            var znb_index = index - 1
                            my_esp = vm_esp - 1
                            my_stack[my_esp] = ("var_" + [codes.charCodeAt(znb_index) - 32])
                            //////////////////////////////////////////////////////
    
                            break;
                        case 77:
                            y = vm_stack[--vm_esp],
                                vm_push(vm_stack[--vm_esp][y]);
    
                            break;
                        case 78:
                            g = codes.charCodeAt(index++) - 32
                            vm_push(vmNewObject(vm_stack, vm_esp -= g + 1, g));
    
                            break;
                        case 79:
                            g = codes.charCodeAt(index++) - 32;
                            vm_push(vm_vars["$" + g]);
    
                            break;
                        case 81:
                            h = vm_stack[--vm_esp]
                            str = vm_substring()
                            vm_stack[--vm_esp][str] = h;
    
                            break;
                        case 82:
                            var str = vm_substring();
                            vm_push(vm_stack[--vm_esp][str]);
    
                            break;
                        case 83: // 将刚刚初始的值放进vm_vars
                            h = vm_stack[--vm_esp];
                            var vars_idx = codes.charCodeAt(index) - 32;
                            vm_vars[codes.charCodeAt(index++) - 32] = h;
                            console.log("声明变量var_",codes.charCodeAt(index-1) - 32, "=", h, )
                            /////////////////////////////////////////////
                            my_esp = vm_esp
                            if (codes.charCodeAt(index - 4) - 32 === 66) { // 上一步是计算
                                ast_body.push(
                                    "var var_" + [codes.charCodeAt(index - 1) - 32] + "=" + my_stack[my_esp] + ';'
                                )
                            }
                            if (codes.charCodeAt(index - 4) - 32 === 14 || codes.charCodeAt(index - 4) - 32 === 76) { // 上一步是赋值,或者是其他
                                ast_body.push(
                                    "var var_" + [codes.charCodeAt(index - 1) - 32] + "=" + h + ';'
                                )
                            }
                            if (num_znb.slice(-2)[0] === 89) { // 上一步是函数声明
                                console.log("创建函数:", "var_" + [codes.charCodeAt(index - 1) - 32])
                            }
                            /////////////////////////////////////////////
                            break;
                        case 84:
                            vm_stack[vm_esp++] = !0;
    
                            break;
                        case 85:
                            vm_stack[vm_esp++] = void 0;
    
                            break;
                        case 86:
                            vm_push(vm_stack[vm_esp - 1]);
    
                            break;
                        case 88:
                            h = vm_stack[--vm_esp],
                                y = vm_stack[--vm_esp],
                                vm_stack[vm_esp++] = h,
                                vm_stack[vm_esp++] = y;
    
                            break;
                        case 89:
                            console.log('初始化函数')
                            vm_push(function () {
                                function anonymous_function() {
                                    return vmEnter(anonymous_function.body_str, arguments, vm_vars)
                                }
    
                                return anonymous_function.body_str = vm_substring(),
                                    anonymous_function.entry = vmRun,
                                    anonymous_function
                            }
                            ());
    
                            break;
                        case 90: //
                            vm_stack[vm_esp++] = null;
    
                            break;
                        case 91:
                            vm_stack[vm_esp++] = h;
    
                            break;
                        case 93:
                            h = vm_stack[--vm_esp];
    
                            break;
                        case 94: // 未知 还没走到条件内
                            if (vm_esp >= 1 && vm_stack[vm_esp - 1] != undefined) {
                                h = vm_stack[vm_esp - 1];
                                var vars_idx = codes.charCodeAt(index) - 32;
                                vm_vars[codes.charCodeAt(index++) - 32] = h;
    
                            } else
                                index++
                            break
                        case 95:
                            vm_push(parseFloat(vm_substring()));
    
                            break;
                        case 96: //
                            var a_idx = vm_stack[--vm_esp]
                            var ary = vm_stack[--vm_esp]
                            vm_push(ary[a_idx]);
    
                            break;
                        case 97:
                            var a_idx = vm_stack[--vm_esp]
                            var ary = vm_stack[--vm_esp]
                            var vlaue = vm_stack[--vm_esp]
                            ary[a_idx] = vlaue
    
                            break;
                        case 98:
                            vm_push(vmExpression_single(codes[index++], vm_stack[--vm_esp]));
    
                            break;
                        case 99:
                            var str = vm_stack[--vm_esp]
                            vm_push(global[str])
    
                        case 0: // 结束当前堆栈
                            console.log("结束当前循环, 并将结果返回", vm_stack[vm_esp-1])
                            return vm_stack[--vm_esp]; //����һ�����ʽ
                        default:
    
                            vm_push((g << 16 >> 16) - 16)
                    }
                }
            }
    
            var pthis = global
            //pthis_Functions = pthis.Function
            var s = Object.keys || function (e) {
                var a = {},
                    r = 0;
                for (var c in e)
                    a[r++] = c;
                return a.length = r,
                    a
            }
            var b = {};
            var k = {};
            return vmEnter
        })
    
        function init() {
            global.console = console;
            global.Date = Date;
            global.String = String;
            global.encodeURIComponent = encodeURIComponent;
            global.decodeURIComponent = decodeURIComponent;
            global.Array = Array;
            global.parseInt = parseInt;
            global.Math = Math;
            global.JSON = JSON;
            instance_run = instance_run()
            instance_run = instance_run(codestr, [e])
        }
    
        init()
    
    }
    
    
    init_vm()
    
    
    var codestr = `y'l l!b+ s1y'l l!b- s4y@.!s5."s6l1zl5l6["c~7l4zl7l6["c~8s9l9z[ c~:`
    

    相关文章

      网友评论

          本文标题:尝试还原jsvmp-1

          本文链接:https://www.haomeiwen.com/subject/imbyddtx.html