某q-深入浅出 JSVMP

查看 102|回复 10
作者:utf8   
深入浅出 JSVMP
本文仅供学习交流,因使用本文内容而产生的任何风险及后果,作者不承担任何责任,一起学习吧
写在前面
我其实用这种方法很少,如果有错误,还请大佬们指正,谢谢!!!
都是个人理解,可能不准确,这个方法也是当时和别人聊天聊出来的。
建议先观看前一篇文章:https://www.52pojie.cn/thread-2022463-1-1.html
上一章插桩代码+补环境,我放到最后面,搞忘记了,抱歉!
啥是JSVMP?
JSVMP(JavaScript Virtual Machine Protection)是一种基于虚拟化技术的JavaScript代码保护方案,主要用于防止代码被逆向分析或篡改。其核心思想是将原始JavaScript代码转换为自定义的字节码指令集,并通过模拟的虚拟机环境来解释执行这些指令,从而增加逆向工程的难度。
是不是很抽象,那就对了,为了后面方便我们理解他的工作原理。首先了解一下JS的运作原理:
[JS 源码]
   ↓
[Parser: 词法 + 语法分析]  --> 抽象语法树 (AST)
   ↓
[生成字节码 / 中间表示 (IR)]
   ↓
[解释执行]   (启动快,但比较慢)
   → (检测到热点代码,调用优化编译器)
      ↓
   [JIT 编译器: 生成机器码, 优化运行]
   → [执行机器码]  (运行速度更快)
   → [可能在某些情况下反优化、回退到解释执行]
并行地,还有一个垃圾回收线程/算法在做内存管理,确保不使用的对象被回收。
举一个例子:
console.log("Hello World"):当JS接收到这段代码时他会怎么做呢?
[ol]
  • 词法/语法分析:将 console.log("Hello World") 拆分为标识符 console、点号 .、标识符 log、括号 ()、字符串 Hello World 等 Token,最终组装成一个调用表达式(CallExpression)的 AST。
  • 解释或编译:JS 引擎会将这个调用表达式变成可执行的字节码/机器码,准备执行。

  • 执行

  • 查找 console 对象(在浏览器或 Node.js 环境里由宿主环境提供)

  • 找到其上的 log 方法

  • 调用时把 "Hello World" 作为参数传入,交由宿主环境去处理输出(浏览器控制台或 Node.js 控制台输出)。

  • 期间还会有各种内置检查,比如类型检查、作用域检查等

    [/ol]
    看懂了上面,JSVMP就是这里面动了手脚。如下:
    [原始 JS 源码]
       ↓
    [Parser: 词法分析 + 语法分析]  
       → 抽象语法树(AST)
       → 【JSVMP】分析 AST 并生成自定义指令集(VMP IR)
       ↓
    [加载进 JS 层虚拟机(VMP 解释器)]
       → 初始化运行时(栈、堆、上下文、指令表等)
       ↓
    [在 JS 层解释执行指令集](VMP 模拟执行流程)
       → 每一条自定义指令被翻译为 JS 操作(变量、运算、跳转等)
       → 多层嵌套虚拟机 + 花指令 + 加密解码逻辑
       ↓
    [JS 引擎自身的 IR / 字节码阶段](开始对“VMP脚本”做优化)
       ↓
    [解释器执行字节码]
       → 大量解释器循环、VM调度、字节码解密过程
       → HotPath 检测
       ↓
    [JIT 编译器优化 VMP 框架代码]
       → 优化执行“VMP解释器本身”的性能
       → 并不会还原出原始业务逻辑
       ↓
    [机器码执行](仍在跑 JS 层的 VMP 虚拟机)
       → 若触发异常/特征变化 → 回退解释执行
    为了更进一步的了解他的混淆,我们再举一个例子:
    原始js代码:
    function add(a, b) {
      return a + b;
    }
    console.log(add(2, 3)); // 输出 5
    首先定义自己的“指令集”:
    // 指令格式: [OPCODE, 操作数1, 操作数2, ...]
    [
      ["PUSH", 2],
      ["PUSH", 3],
      ["CALL", "add"],
      ["CALL_BUILTIN", "console.log"]
    ]
    [table]
    [tr]
    [td]思路如下:[/td]
    [td]指令名[/td]
    [td]含义[/td]
    [/tr]
    [tr]
    [td]PUSH

    机器码, 代码

  • Xie9527   

    大佬大佬
    utf8
    OP
      


    ShriyGo 发表于 2025-4-14 16:08
    主要是插装点还是很有疑问,我自己插装在call apply和各种加减乘除位移异或什么的,效果太乱了,提取不到 ...

    所以我才会对那一部分整体改写,我最后有贴代码,你可以看看。这个地方对js执行顺序和作用域考察很深哦。
    K23   

    没看懂,但是好像很厉害,支持一下
    kyomic   

    很是强大,顶一下
    goodyou   

    虽然我看不懂 但是 顶一下
    Adby0711   

    感谢楼主分享,【抱拳】
    laoa2025   

    虽然我看不懂 但是 顶一下+1
    BrutusScipio   

    这不是IL那套嘛,不过为了混淆重新实现一次对性能会有多大影响?是把所有指令都hook一次还是再加混淆,印象里指令集可以做到很小就能完整调度
    外酥内嫩   

    讲的太好了,之前对vmp还有点疑惑,一看楼主的那个抽出来的指令就明白了
    您需要登录后才可以回帖 登录 | 立即注册

    返回顶部