never-jscore:为逆向而生的 Python 高性能 JS 引擎(Hook 拦截 + 零配置补环境)
本文最后更新于:2026年8月14日 下午
本文为工具使用整理,基于官方仓库、README 与类型存根编写
- 项目地址:https://github.com/neverl805/never-jscore(★360+)
- PyPI:
pip install never-jscore(v3.2.x)- 底层:Rust + deno_core(V8)
文中代码与 API 签名均来自官方 README 和
never_jscore.pyi类型存根,可直接验证。⚠️ License 提示:仓库 GitHub API 未标注 License,而 README 徽章写的是 MIT——两者不一致,商用前请向作者确认授权。
一、它是什么,解决什么问题
never-jscore 是一个用 Python 高性能执行 JavaScript 的引擎,专为 JS 逆向工程设计,定位是 execjs(PyExecJS)的上位替代。
在 Python 里跑 JS,常见几条路线:
| 方案 | 底层 | 特点 |
|---|---|---|
| 外部 Node 等 runtime | 每次起子进程,慢、已过时 | |
| mini-racer | 嵌入式 V8 | 通用、轻量,跑纯算法最省心 |
| bestV8 | 纯净 V8 动态库 | 补环境(白纸全手补) |
| never-jscore | Rust + deno_core(V8) | 自带 Deno 全套 API + 逆向专用 Hook |
never-jscore 的独特之处在于:它底层用的是 deno_core,因此自带 Deno 那一整套 Web / Node.js API(fetch、localStorage、crypto、require 等),实现”零配置补环境”;同时提供 Hook 拦截和确定性随机数这两个逆向专用能力。
一句话对比:bestV8 给你一张纯净白纸让你手工补环境;never-jscore 直接给你一个装好浏览器/Node API 的环境,还额外送你逆向 Hook。
二、核心特点
- 🚀 极致性能:简单任务 25 万+ ops/s,复杂任务 2 万+ ops/s(Context 复用模式)
- 🎣 双模式 Hook 拦截(
$return+$terminate),专为逆向设计 - 🎲 确定性随机数:固定种子,加密算法调试结果可复现
- 🌐 完整 Web / Node.js API,零配置补环境
- ⚡ v3.0.0 GIL 释放优化,多线程性能提升
- 🎨 附带 Canvas 2D API(纯 Rust 实现)、V8 堆内存分析等
三、安装与快速上手
1 | |
支持 Windows / Linux / macOS,Python 3.8+(官方推荐 3.14 获得最佳性能)。
1 | |
四、两种执行模式:Context vs JSEngine
v3.0.0 起提供双架构,选错模式性能差几十上百倍,这是最需要注意的点。
关键性能真相 ⚠️
| 场景 | Context(复用) | JSEngine(Pool) | 差距 |
|---|---|---|---|
| 简单 JS(btoa) | 255,969 ops/s | 743 ops/s | Context 快 344× |
| 复杂计算(循环) | 23,675 ops/s | 550 ops/s | Context 快 43× |
| 冷启动(每次重建) | 50 ops/s | 607 ops/s | JSEngine 快 12× |
结论:99% 场景用 Context 复用模式。只有”每次都要跑不同 JS、无法复用 Context”或”避免大型 JS 库重复冷启动”时,JSEngine 才有优势。
最容易踩的坑:不要在循环里反复建 Context
1 | |
JSEngine 模式(批量 / 并发)
1 | |
五、逆向专属能力
这三个特性是 never-jscore 比通用 JS 引擎(mini-racer 等)更”懂逆向”的地方。
1. 双模式 Hook 拦截
$return() —— 快速拦截,抠出加密中间值
在 JS 逻辑中间插一句 $return(...),提前返回中间结果,后续代码不再执行:
1 | |
$terminate() —— 强制终止,连 try-catch 都拦不住
适合 Hook 那些被 try-catch 包裹的关键函数(比如 XMLHttpRequest.send),拿到加密后的 payload:
1 | |
$return与$terminate的区别:前者是”正常提前返回”,后者是”强制终止事件循环、无法被 JS 捕获”。逆向时想拿被保护函数的入参/中间值,$terminate更可靠。
2. 确定性随机数(调试可复现)
固定种子后,所有随机 API 每次结果都一样——对依赖随机数的签名/加密算法调试极其有用:
1 | |
影响的 API:Math.random()、crypto.randomUUID()、crypto.getRandomValues()。
3. 零配置补环境(Web / Node.js API)
Web API(默认启用)
fetch、localStorage、URL、TextEncoder/Decoder、atob/btoa、crypto、setTimeout、ReadableStream、structuredClone、Event/EventTarget、AbortController 等开箱即用:
1 | |
Node.js 兼容模式
传 enable_node_compat=True 即可用 require() 和 Node 内置模块,甚至加载 npm 包(需先 npm install):
1 | |
支持 path/fs/crypto/buffer/stream/url/util/events 等内置模块,以及 jsdom、lodash、crypto-js、ws 等 npm 包。
六、Context 关键参数(来自类型存根)
Context.__init__ 的真实签名与含义:
1 | |
小提示:如果你想要一个纯净 V8 环境(不自带 Deno API,类似 bestV8 的白纸),可以传
enable_extensions=False。
常用方法:
compile(code):编译并加载 JS(供后续call复用)evaluate(code, auto_await=None):执行并返回最后一个表达式的值,自动 await Promiseeval(code, return_value=True, auto_await=None):底层求值call(name, args=[], auto_await=None):按函数名调用get_hook_data():取出 Hook($return/$terminate)保存的数据(JSON 字符串)get_heap_statistics()/take_heap_snapshot(path)/gc():V8 堆分析与内存管理get_stats()/reset_stats():调用计数统计
七、性能对比(官方数据,仅供参考)
| 测试项 | never-jscore | PyMiniRacer | PyExecJS |
|---|---|---|---|
| 简单计算 | 0.007ms | 0.005ms | 2.3ms |
| 字符串操作 | 0.004ms | 0.008ms | 2.3ms |
| 复杂算法(1000 次) | 11ms | 38ms | 69473ms |
| Promise / async | ✅ 3ms | ❌ 不支持 | ❌ 不支持 |
数据来自官方 README,随环境变化,仅供参考。可以看出它和 PyMiniRacer 在纯计算上同量级,但多了 Promise/async 支持,且远快于起子进程的 PyExecJS。
八、选型建议
- 跑不依赖浏览器环境的纯算法 JS → mini-racer 最省心(轻量、稳定)。
- 需要补浏览器环境 + 逆向 Hook → never-jscore(自带 Deno API,还有
$return/$terminate)。 - 需要极致纯净 V8、自己精确控制环境特征 → bestV8,或 never-jscore 传
enable_extensions=False。
一个需要留意的权衡:never-jscore 底层是 deno_core,自带 Deno/Node 环境是把双刃剑——补环境省事,但如果目标站点会检测 Deno/Node 特征,反而可能露馅。对抗强检测时要评估这一点,必要时切到纯净模式或 bestV8。
参考
- 项目地址:https://github.com/neverl805/never-jscore
- PyPI:https://pypi.org/project/never-jscore/
- deno_core:https://github.com/denoland/deno_core
本文仅作技术学习记录。请在合法合规、获得授权的前提下使用相关技术。