如何调用逆向出来的JS代码

B站影视 韩国电影 2025-09-29 13:14 1

摘要:在 JavaScript 逆向中,我们往往是将浏览器的 JavaScript 代码在本地还原,执行后获取逆向结果。然尔 JavaScript 逆向基本都是为 Python 爬虫服务的,所以我们经常需要在 Python 代码中调用 JavaScript 代码。本

在 JavaScript 逆向中,我们往往是将浏览器的 JavaScript 代码在本地还原,执行后获取逆向结果。然尔 JavaScript 逆向基本都是为 Python 爬虫服务的,所以我们经常需要在 Python 代码中调用 JavaScript 代码。本文详细介绍了几种常用的方法。

pip install PyExecJS #技术分享安装一个 JavaScript 运行时 PyExecJS 只是一个“调度员”,它需要一个真正的“工人”(JS 运行时)来执行代码。强烈推荐安装 Node.js,因为它最稳定且兼容性最好。访问 Node.js 官网 下载并安装。安装完成后,在你的终端(命令行)输入 node -v,如果能看到版本号,就说明安装成功了。

这是最基础的用法,可以直接执行一行 JS 代码并获取返回值。我们使用 execjs.eval 函数。

import execjs# 使用 .eval 执行一个简单的JS字符串操作js_Expression = "'Hello PyExecJS'.split('').reverse.join('')" result = execjs.eval(js_expression)print(f"JS 表达式的结果: {result}")# 输出: JS 表达式的结果: SJcexEyp olleH

当你有一段包含多个函数定义的 JS 代码时,你需要先“编译”这段代码,然后再通过函数名来调用指定的函数。这需要用到 execjs.compile 和 .call 假设你有一个 math.js 文件,里面有一个 add 函数。

function add(x, y) { return x +}function subtract(x, y) { return x -}

则可以在 Python 脚本中这样调用:

import execjswith open('math.js', 'r', encoding='utf-8') as f: js_code = f.readctx = execjs.compile(js_code)result = ctx.call("add", 10, 5)print(f"调用 JS add(10, 5) 函数的结果是: {result}")非常简单:上手快,调用 JS 函数就一两行代码。安装方便: pip install PyExecJS 就行,库本身很小。比较灵活:能自动寻找你电脑上安装的 JavaScript 环境(比如 Node.js)。必须依赖外部程序:你的电脑上必须安装 Node.js 才能运行,否则会报错,增加了部署的麻烦。性能很差:每次调用 JS 都像重新打开一个程序,速度慢,不适合频繁调用。不支持现代 JS:无法运行 Promise 或 async/await 等异步代码,很多新网站的 JS 都跑不了。已经“过时”了:这个项目自 2018 年以来就没更新过,对于新项目来说,使用它存在风险。

将以下所有代码保存在一个名为 server.js 的文件中。这个文件包含了:

核心的 JS 业务逻辑 ( getSign 函数)。使用 Express 创建的 HTTP 服务器。处理 /get-signature 路由的逻辑。const express = require('express');async function getSign(params) { console.log(`[JS Logic] 接收到参数:`, params); await new Promise(resolve => setTimeout(resolve, 50)); const sortedValues = Object.values(params).sort; const baseString = sortedValues.join('-'); const signature = `express_signed_${baseString}_${Date.now}`; console.log(`[JS Logic] 生成签名为: ${signature}`); return signature; }const app = express; const PORT = 3000;app.use(express.json);app.post('/get-signature', async (req, res) => { console.log('[Server] /get-signature 路由被调用'); try { const params = req.body;if (!params || Object.keys(params).length === 0) { return res.status(400).json({ success: false, error: '请求体不能为空' }); }const signature = await getSign(params);res.json({ success: true, signature: signature });} catch (error) { console.error('[Server] 处理请求时发生错误:', error); res.status(500).JSON({ success: false, error: '服务器内部错误' }); } });app.listen(PORT, => { console.log(`Express 服务已启动,正在监听 http://127.0.0.1:${PORT}`); });

在终端中运行:node server.js 就可以启动服务。

优缺点优点 (Pros) 专业级性能与稳定性:Node.js 服务是一个常驻进程,利用 V8 引擎以最高效率执行 JS。它避免了其他方法“每次调用都新建进程”的巨大开销,因此响应极快、吞吐量高,完全能胜任高并发的生产环境。彻底解决环境与依赖问题:你拥有一个完整的、真实的 Node.js 环境。可以随意使用 npm 安装任何第三方 JS 库(如 crypto-js)。强大的扩展性:这是一个真正的微服务。未来你可以轻松地增加更多 API 接口(路由),并且可以独立地对这个 JS 服务进行扩容(例如部署到多个服务器或容器),而无需改动 Python 主应用。增加了架构复杂度:的项目从一个“单体脚本”变成了“微服务架构”。你需要管理两个独立的服务(Python 应用和 Node.js 服务),并确保它们之间的网络通信是可靠的。

这是一种非常强大和灵活的“中量级”方案,它比 PyExecJS 更可靠,又比搭建完整的微服务更简单。Python 程序像一个“指挥官”,通过 subprocess 在操作系统中开启一个独立的 Node 进程(“士兵”),然后通过标准输入/输出( stdin/stdout )给它下达指令并接收报告。

这个 JS 脚本需要被设计成一个命令行工具,它必须:

标准输入(stdin)读取数据。执行核心逻辑(可以是异步的)。将最终结果打印到 标准输出(stdout) 。如果出错,将错误信息打印到 标准错误(stderr) 。async function getSign(params) { await new Promise(resolve => setTimeout(resolve, 50)); const baseString = Object.values(params).sort.join('_'); const signature = `processed_${baseString}`; return signature;}function readStdin { return new Promise((resolve, reject) => { let data = ''; process.stdin.on('data', chunk => data += chunk); process.stdin.on('end', => resolve(data)); process.stdin.on('error', err => reject(err)); }); }async function main { try { const inputStr = await readStdin; const params = json.parse(inputStr);const result = await getSign(params);console.log(JSON.stringify({ success: true, data: result }));} catch (error) { console.error(JSON.stringify({ success: false, error: error.message })); process.exit(1); } }main;import subprocessimport jsondef run_js_with_subprocess(params: dict) -> str | None: """ 通过 subprocess 调用 worker.js 并传递参数。""" command = ['node', 'worker.js'] input_data = json.dumps(params) print(f"[Python] 准备运行命令: {' '.join(command)}") print(f"[Python] 将通过 stdin 发送数据: {input_data}")try: result = subprocess.run( command, input=input_data, capture_output=True, text=True, check=True )output_data = json.loads(result.stdout) if output_data.get('success'): return output_data.get('data') else: print(f"[Python] JS 脚本报告了一个逻辑错误: {output_data.get('error')}") return Noneexcept FileNotFoundError: print("[Python] 错误: 'node' 命令未找到。请确保 Node.js 已经安装并加入到系统 PATH。") return None except subprocess.CalledProcessError as e: print("[Python] 错误: JS 脚本执行失败!") print(f" - 返回码: {e.returncode}") print(f" - 错误输出 (stderr): {e.stderr.strip}") return Noneif __name__ == "__main__": order_data = { "orderId": "TYO-20250919-001", "amount": 15000, "currency": "JPY" } signature = run_js_with_subprocess(order_data) if signature: print(f"\n[Python] 成功从 JS 获取结果: {signature}")无Python第三方依赖: subprocess 是内置库。完整的Node.js环境:可以随意使用 npm 包和所有 Node.js 功能,包括 async/await 。模式通用:这种通过 stdin/stdout 通信的模式可以用于调用任何命令行程序。

来源:墨码行者

相关推荐