JSVMP逆向实战:原理分析与破解思路详解
引言
在当今Web安全领域,JavaScript虚拟机保护(JSVMP)技术被广泛应用于前端代码的保护和反爬机制中。作为前端逆向工程师,掌握JSVMP逆向技术已成为必备技能。本文将深入剖析JSVMP的工作原理,并分享实用的逆向破解思路。
什么是JSVMP?
JSVMP(JavaScript Virtual Machine Protection)是一种通过自定义虚拟机执行JavaScript代码的保护技术。它将原始JavaScript代码编译为自定义的字节码,然后通过解释器执行,从而:
-
隐藏原始业务逻辑
-
增加逆向分析难度
-
防止直接调试和Hook
JSVMP的核心组成
1. 字节码编译器
将原始JS代码转换为自定义字节码序列:
// 原始JS
function add(a, b) {return a + b;
}// 编译后字节码可能类似
[0x01, 0x02, 0x03, 0x04, ...]
2. 虚拟机解释器
解释执行自定义字节码的虚拟机核心:
function VM(bytecode) {this.pc = 0; // 程序计数器this.stack = []; // 操作数栈this.registers = {}; // 寄存器this.run = function() {while(this.pc < bytecode.length) {const opcode = bytecode[this.pc++];this.execute(opcode);}}this.execute = function(opcode) {switch(opcode) {case 0x01: // PUSHthis.stack.push(bytecode[this.pc++]);break;case 0x02: // ADDconst a = this.stack.pop();const b = this.stack.pop();this.stack.push(a + b);break;// ...其他操作码}}
}
3. 运行时环境
提供与原生JavaScript环境的交互接口:
const runtime = {getCookie: function(name) {// 获取cookie的实现},sendRequest: function(url, data) {// 发送请求的实现}// ...其他运行时方法
};
JSVMP逆向分析步骤
1. 识别JSVMP结构
通过特征识别目标是否使用JSVMP:
-
存在大量
switch-case结构 -
有明显的字节码序列
-
代码包含解释执行循环
-
使用
eval或Function动态执行
2. 定位关键入口
寻找字节码加载和解释器初始化的位置:
// 常见初始化模式
const bytecode = [0x01, 0x02, ...];
const vm = new VM(bytecode);
vm.run();
3. 分析字节码结构
确定字节码的编码方式和指令集:
| 操作码 | 指令 | 描述 |
|---|---|---|
| 0x01 | PUSH | 压栈 |
| 0x02 | ADD | 加法 |
| 0x03 | CALL | 调用函数 |
| ... | ... | ... |
4. 动态调试技巧
使用Chrome DevTools进行动态分析:
// 在关键位置插入调试语句
console.log("PC:", vm.pc, "Opcode:", opcode, "Stack:", vm.stack);// 或使用debugger语句
if(vm.pc === targetPC) debugger;
实战破解案例
案例1:某网站加密参数分析
目标:破解_signature参数生成算法
步骤:
-
通过XHR断点定位加密位置
-
回溯调用栈找到VM入口
-
分析字节码中的加密逻辑
-
提取关键操作模拟执行
// 还原后的加密逻辑
function generateSign(params) {const vm = new VM(encryptBytecode);vm.registers.input = JSON.stringify(params);vm.run();return vm.stack.pop();
}
案例2:某JSVMP反爬破解
挑战:
-
动态变化的操作码映射表
-
自修改字节码
-
反调试检测
解决方案:
-
使用
Object.definePropertyHook关键函数 -
记录操作码执行轨迹
-
构建操作码到原始JS的映射关系
// Hook示例
const originalRun = VM.prototype.run;
VM.prototype.run = function() {console.log("VM started with bytecode:", this.bytecode);return originalRun.apply(this, arguments);
};
高级逆向技术
1. 符号执行分析
通过符号执行还原原始逻辑:
# 使用PyExZ3等符号执行工具
from pyexz3 import *def analyze_bytecode(bytecode):vm = VM(bytecode)vm.run()return vm.stack
2. 字节码反编译
将字节码转换回高级JavaScript代码:
function decompile(bytecode) {let jsCode = "";for(let i = 0; i < bytecode.length; ) {const opcode = bytecode[i++];switch(opcode) {case 0x01: jsCode += `stack.push(${bytecode[i++]});\n`;break;// 其他操作码转换...}}return jsCode;
}
3. 内存快照分析
通过内存dump获取运行时信息:
// 获取VM内存状态
function dumpVM(vm) {return {pc: vm.pc,stack: [...vm.stack],registers: {...vm.registers}};
}
反反爬对策
应对JSVMP的反逆向措施:
| 反爬技术 | 破解方法 |
|---|---|
| 代码混淆 | AST分析 |
| 环境检测 | 纯净环境 |
| 动态加载 | 请求拦截 |
| 定时检测 | 断点绕过 |
工具推荐
-
静态分析工具:
-
AST Explorer
-
Babel Parser
-
WebStorm
-
-
动态调试工具:
-
Chrome DevTools
-
Fiddler
-
Charles
-
-
专用逆向工具:
-
WasmDec
-
JEB JavaScript
-
Node.js VM
-
学习资源
-
《JavaScript高级程序设计》- VM实现章节
-
Chrome V8引擎源码
-
WebAssembly虚拟机规范
-
Babel插件开发手册
结语
JSVMP逆向是一个需要耐心和技术积累的过程。通过本文介绍的方法论和实战案例,相信读者已经对JSVMP逆向有了系统性的认识。记住,逆向工程的本质是与开发者的智力博弈,保持学习和技术更新才是制胜关键。
重要声明:本文所有技术仅限学习交流,请勿用于非法用途。实际逆向操作前请确保已获得相关授权。
相关文章:
JSVMP逆向实战:原理分析与破解思路详解
引言 在当今Web安全领域,JavaScript虚拟机保护(JSVMP)技术被广泛应用于前端代码的保护和反爬机制中。作为前端逆向工程师,掌握JSVMP逆向技术已成为必备技能。本文将深入剖析JSVMP的工作原理,并分享实用的逆向破解思路…...
【SPP】蓝牙链路控制(LC)在SPP中互操作性深度解析
在蓝牙协议栈的精密分层体系中,其链路控制(Link Control, LC)层作为基带层的核心组件,承载着物理信道管理、连接建立与维护等关键任务。其互操作性要求直接决定了不同厂商设备能否实现无缝通信。本文将以蓝牙技术规范中的LC互操作…...
单片机学习之定时器
定时器是用来定时的机器,是存在于STM32单片机中的一个外设。STM32一般总共有8个定时器,分别是2个高级定时器(TIM1、TIM8),4个通用定时器(TIM2、TIM3、TIM4、TIM5)和2个基本定时器(TI…...
供应链管理:计算题 / 倒扣法
一、理解倒扣法 在供应链管理中,倒扣法是一种常用的成本计算方法,主要用于确定商品的成本和销售价格,以确保特定的毛利率。倒扣法的基本原理是在已知售价和期望毛利率的情况下,逆推计算出供货价或成本价。 二、倒扣法的计算公式…...
算法每日一练 (25)
💢欢迎来到张翊尘的技术站 💥技术如江河,汇聚众志成。代码似星辰,照亮行征程。开源精神长,传承永不忘。携手共前行,未来更辉煌💥 文章目录 算法每日一练 (25)四数之和题目描述解题思路解题代码c…...
【大模型基础_毛玉仁】6.4 生成增强
目录 6.4 生成增强6.4.1 何时增强1)外部观测法2)内部观测法 6.4.2 何处增强6.4.3 多次增强6.4.4 降本增效1)去除冗余文本2)复用计算结果 6.4 生成增强 检索器得到相关信息后,将其传递给大语言模型以期增强模型的生成能…...
Zephyr实时操作系统初步介绍
一、概述 Zephyr是由Linux基金会托管的开源实时操作系统(RTOS),专为资源受限的物联网设备设计。其核心特性包括模块化架构、跨平台兼容性、安全性优先以及丰富的连接协议支持。基于Apache 2.0协议,Zephyr允许商业和非商业用途的自…...
【GCC警告报错4】warning: format not a string literal and no format arguments
文章主本文根据笔者个人工作/学习经验整理而成,如有错误请留言。 文章为付费内容,已加入原创保护,禁止私自转载。 文章发布于:《C语言编译报错&警告合集》 如图所示: 原因: snprintf的函数原型&#x…...
【落羽的落羽 C++】模板简介
文章目录 一、模板的引入二、函数模板1. 函数模板的使用2. 函数模板的原理3. 函数模板的实例化4. 函数模板的匹配 三、类模板 一、模板的引入 假如我们想写一个Swap函数,针对每一种类型,都要函数重载写一次,但它们的实现原理是几乎一样的。在…...
USB(通用串行总线)数据传输机制和包结构简介
目录 1. USB的物理连接电缆结构时钟恢复技术 2. USB的数据传输方式包(Packet) 3. 包的传输规则帧和微帧 4. 包的结构1. 同步字段(Sync)2. 包标识符字段(PID)3. 数据字段4. 循环冗余校验字段(CRC…...
【目标检测】【深度学习】【Pytorch版本】YOLOV3模型算法详解
【目标检测】【深度学习】【Pytorch版本】YOLOV3模型算法详解 文章目录 【目标检测】【深度学习】【Pytorch版本】YOLOV3模型算法详解前言YOLOV3的模型结构YOLOV3模型的基本执行流程YOLOV3模型的网络参数 YOLOV3的核心思想前向传播阶段反向传播阶段 总结 前言 YOLOV3是由华盛顿…...
【前端扫盲】postman介绍及使用
Postman 是一款专为 API 开发与测试设计的 全流程协作工具,程序员可通过它高效完成接口调试、自动化测试、文档管理等工作。以下是针对程序员的核心功能介绍和应用场景说明: 一、核心功能亮点 接口请求构建与调试 支持所有 HTTP 方法(GET/POS…...
每日c/c++题 备战蓝桥杯(全排列问题)
题目描述 按照字典序输出自然数 1 到 n 所有不重复的排列,即 n 的全排列,要求所产生的任一数字序列中不允许出现重复的数字。 输入格式 一个整数 n。 输出格式 由 1∼n 组成的所有不重复的数字序列,每行一个序列。 每个数字保留 5 个场…...
IdeaVim-AceJump
AceJump 是一款专为IntelliJ IDEA平台打造的开源插件,旨在通过简单的快捷键操作帮助用户快速跳转到编辑器中的任何符号位置,如变量名、方法调用或特定的字符串。无论是大型项目还是日常编程,AceJump 都能显著提升你的代码导航速度和效率。…...
BMS电池关键参数及其含义
BMS概述 BMS的定义与功能 BMS,即电池管理系统,是电池系统的核心控制设备,充当着电池的“状态观测器”。它通过传感器采集电池的单体电压、温度、电流等关键参数,并利用电子控制单元(ECU)进行数据处理和分…...
DataFrame行索引操作以及重置索引
一.DataFrame行索引操作 1.1 获取数据 1.1.1 loc 选取数据 df.loc[ ] 只能使用标签索引,不能使用整数索引。 当通过标签索引的切片方式来筛选数据时,它的取值前闭后闭。 传参: 1.如果选择单行或单列,返回的数据类型为 Series…...
DayDreamer: World Models forPhysical Robot Learning
DayDreamer:用于物理机器人学习的世界模型 Philipp Wu* Alejandro Escontrela* Danijar Hafner* Ken Goldberg Pieter Abbeel 加州大学伯克利分校 *贡献相同 摘要:为了在复杂环境中完成任务,机器人需要从经验中学习。深度强化学习是机器人学…...
线性欧拉筛
线性筛:高效求解素数 在数论中,素数的筛选是一个经典的问题。最常见的素数筛选方法是埃拉托斯特尼筛法,其时间复杂度为 O ( n log log n ) O(n\log \log n) O(nloglogn),非常适合求解小范围内的素数。随着问题规模的增大&…...
Flutter vs React Native:跨平台移动开发框架对比
文章目录 前言1. 框架概述什么是 Flutter?什么是 React Native? 2. 性能对比Flutter 的性能表现React Native 的性能表现总结: 3. 开发体验对比3.1 开发效率3.2 UI 组件库 4. 生态系统对比5. 适用场景分析6. 结论:如何选择&#x…...
用matlab搭建一个简单的图像分类网络
文章目录 1、数据集准备2、网络搭建3、训练网络4、测试神经网络5、进行预测6、完整代码 1、数据集准备 首先准备一个包含十个数字文件夹的DigitsData,每个数字文件夹里包含1000张对应这个数字的图片,图片的尺寸都是 28281 像素的,如下图所示…...
AI辅助开发插件
适合Java程序员的AI辅助开发插件,按功能和适用场景分类: 1. 飞算JavaAI • 特点:从需求分析到代码生成的全流程智能引导,支持Maven、Gradle等主流工具,一键生成完整工程代码,包括配置文件、源代码和测试资…...
【AI4CODE】5 Trae 锤一个基于百度Amis的Crud应用
【AI4CODE】目录 【AI4CODE】1 Trae CN 锥安装配置与迁移 【AI4CODE】2 Trae 锤一个 To-Do-List 【AI4CODE】3 Trae 锤一个贪吃蛇的小游戏 【AI4CODE】4 Trae 锤一个数据搬运工的小应用 1 百度 Amis 简介 百度 Amis 是一个低代码前端框架,由百度开源。它通过 J…...
npm webpack打包缓存 导致css引用地址未更新
问题如下: 测试环境配置: publicPath: /chat/,生产环境配置: publicPath: /,css中引用背景图片 background-image: url(/assets/images/calendar/arrow-left.png);先打包测试环境,观察打包后的css文件引用的背景图片地址 可以全…...
ollama导入huggingface下载的大模型并量化
1. 导入GGUF 类型的模型 1.1 先在huggingface 下载需要ollama部署的大模型 1.2 编写modelfile 在ollama 里面输入 ollama show --modelfile <你有的模型名称> eg: ollama show --modelfile qwen2.5:latest修改其中的from 路径为自己的模型下载路径 FROM /Users/lzx/A…...
Java 集合 Map Stream流
目录 集合遍历for each map案例 编辑 这种数组的遍历是【index】编辑map排序【对象里重写compareTo编辑map排序【匿名内部类lambda编辑 stream流编辑 编辑获取: map的键是set集合,获取方法map.keySet() map的值是collection 集合&…...
记录一下零零散散的的东西-ImageNet
ImageNet 是一个非常著名的大型图像识别数据集, 数据集基本信息 内容说明📸 图像数量超过 1400万张图片(包含各类子集)🏷️ 类别数量常用的是 ImageNet-1K(1000类)🧑Ἶ…...
【网络安全实验】PKI(证书服务)配置实验
目录 一、PKI相关概念 1.1 定义与核心功能 1.2 PKI 系统的组成 1.证书颁发机构(CA, Certificate Authority) 2.注册机构(RA, Registration Authority) 3.数字证书 1.3 PKI 的功能 1.4 PKI认证体系: 工作流程 …...
【数据集】多视图文本数据集
多视图文本数据集指的是包含多个不同类型或来源的信息的文本数据集。不同视图可以来源于不同的数据模式(如原始文本、元数据、网络结构等),或者不同的文本表示方法(如 TF-IDF、词嵌入、主题分布等)。这些数据集常用于多…...
学透Spring Boot — 007. 七种配置方式及优先级
Spring Boot 提供很多种方式来加载配置,本文我们会用Tomcat的端口号作为例子,演示Spring Boot 常见的配置方式。 几种配置方式 使用默认配置 新建一个项目什么都不配置,Spring Boot会自动配置Tomcat端口号。 启动日志 TomcatWebServer :…...
元素定位-xpath
xpath其实就是一个path(路径),一个描述页面元素位置信息的路径,相当于元素的坐标xpath基于XML文档树状结构,是XML路径语言,用来查询xml文档中的节点。 绝对定位 从根开始找--/(根目录)/html/body/div[2]/div/form/div[5]/button缺…...
