execjs有哪些常用的api,如何逆向分析网站的加签机制

execjs 是 Python 中一个用于执行 JavaScript 代码的库,它能调用系统中安装的 JavaScript 运行时(如 Node.js、V8 等)来执行 JS 代码。以下是其常用的 API 及用法说明:

1. execjs.compile(source)

  • 功能 :编译 JavaScript 代码字符串,返回一个 Context 对象,用于后续执行该代码中的函数或表达式。

  • 参数source 为 JavaScript 代码字符串。

  • 示例

    python 复制代码
    import execjs
    
    # 编译JS代码
    js_code = """
    function add(a, b) {
        return a + b;
    }
    """
    ctx = execjs.compile(js_code)

2. Context.call(name, *args)

  • 功能:调用编译后的 JavaScript 代码中的指定函数。

  • 参数

    • name:要调用的 JS 函数名(字符串)。
    • *args:传递给 JS 函数的参数(支持 Python 基本类型,会自动转换为 JS 类型)。
  • 示例

    python 复制代码
    # 调用上面编译的add函数
    result = ctx.call("add", 2, 3)  # 调用add(2,3)
    print(result)  # 输出:5

3. Context.eval(expression)

  • 功能:执行编译后的 JavaScript 代码中的表达式,并返回结果。

  • 参数expression 为 JS 表达式字符串(如变量、运算式等)。

  • 示例

    python 复制代码
    # 编译包含变量的JS代码
    js_code = """
    var x = 10;
    var y = 20;
    """
    ctx = execjs.compile(js_code)
    
    # 执行表达式获取结果
    result = ctx.eval("x + y")  # 计算x+y
    print(result)  # 输出:30

4. execjs.eval(source)

  • 功能 :直接执行简单的 JavaScript 代码(无需先编译),相当于 compile(source).eval(source) 的简写。

  • 适用场景:执行单行或简单的 JS 表达式(不包含复杂函数定义时更方便)。

  • 示例

    python 复制代码
    result = execjs.eval("1 + 2 * 3")  # 直接执行JS表达式
    print(result)  # 输出:7

5. execjs.get_runtime(name=None)

  • 功能 :获取指定的 JavaScript 运行时(如 Node.js、V8 等)。若不指定 name,则返回默认运行时。

  • 参数name 为运行时名称(如 "Node"、"V8" 等,取决于系统中安装的运行时)。

  • 示例

    python 复制代码
    # 获取Node.js运行时
    node_runtime = execjs.get_runtime("Node")
    print(node_runtime.name)  # 输出:Node.js

6. execjs.runtimes

  • 功能:返回一个列表,包含当前系统中所有可用的 JavaScript 运行时。

  • 示例

    python 复制代码
    # 查看所有可用的JS运行时
    for runtime in execjs.runtimes:
        print(runtime.name)  # 可能输出:Node.js、JScript、V8等

注意事项

  • execjs 依赖系统中已安装的 JavaScript 运行时(如 Node.js 最常用),若未安装会报错。
  • Python 与 JS 之间的类型转换是自动的(如 Python 的 int→JS 的 Numberdict→JS 的 Object 等)。
  • 复杂场景建议先通过 compile() 编译代码,再用 call() 调用函数,效率更高。

通过这些 API,可以方便地在 Python 中集成 JavaScript 代码,适用于处理需要 JS 解析的场景(如加密逻辑、前端代码模拟等)。

使用 Chrome DevTools 逆向分析 JS 加签函数并通过 execjs 模拟执行

一、准备工作

  1. 安装必要工具

    • Chrome 浏览器(自带 DevTools)
    • Python 环境
    • 安装 execjs 库:pip install PyExecJS
    • 确保系统中安装了 Node.js(execjs 会优先使用 Node.js 作为运行时)
  2. 基础知识

    • 了解基本的 JavaScript 语法
    • 了解 HTTP 请求的基本概念
    • 熟悉 Python 基础语法

二、使用 Chrome DevTools 定位加签函数

1. 打开开发者工具

  • 在 Chrome 中访问目标网站
  • 按 F12 或 Ctrl+Shift+I (Windows/Linux) 或 Cmd+Opt+I (Mac) 打开 DevTools
  • 切换到 "Network"(网络)面板

2. 找到包含加签参数的请求

  • 进行触发加签逻辑的操作(如登录、提交表单等)
  • 在网络面板中找到对应的请求(通常是 XHR/fetch 类型)
  • 查看请求的参数,识别出疑似加签的字段(如 sign、signature、token 等)

3. 定位加签函数

有几种常用方法:

方法一:搜索关键词
  • 切换到 "Sources"(源代码)面板
  • 按 Ctrl+Shift+F (Windows/Linux) 或 Cmd+Opt+F (Mac) 打开全局搜索
  • 搜索加签参数名(如 "sign"),查看相关代码
方法二:XHR 断点
  • 在 Network 面板中,右键点击目标请求,选择 "Copy" → "Copy as cURL"
  • 切换到 Sources 面板,在 XHR/fetch 断点处点击 "+",输入包含加签参数的 URL 部分
  • 触发请求,程序会在发送请求前暂停,通过调用栈找到加签逻辑
方法三:观察调用栈
  • 在 Sources 面板中,找到可能包含加签逻辑的 JS 文件
  • 在可疑代码处设置断点(点击行号)
  • 触发请求,程序暂停后,通过右侧 "Call Stack"(调用栈)回溯找到加签函数

三、分析并提取加签函数

  1. 理解加签逻辑

    • 观察加签函数的输入参数
    • 分析函数内部的加密算法(如 MD5、SHA、HMAC 等)
    • 注意是否有时间戳、随机数等动态参数参与计算
  2. 提取关键代码

    • 复制加签函数的完整代码
    • 检查该函数是否依赖其他函数或变量,一并提取
    • 注意处理可能的代码混淆(如变量名压缩、控制流平坦化等)
  3. 测试提取的代码

    • 在 DevTools 的 "Console"(控制台)中粘贴代码
    • 手动调用函数,验证是否能生成正确的签名

四、使用 execjs 执行提取的代码

1. 基本示例

假设我们提取的加签函数如下:

javascript 复制代码
function generateSign(params, secret) {
    // 对参数进行排序
    let sortedKeys = Object.keys(params).sort();
    let str = '';
    for (let key of sortedKeys) {
        str += key + '=' + params[key] + '&';
    }
    str += 'secret=' + secret;
    
    // 使用 MD5 加密
    return md5(str);
}

// MD5 函数(假设已提取)
function md5(s) {
    // 具体实现...
}

2. Python 代码实现

python 复制代码
import execjs
import json

# 读取提取的JS代码
with open('sign_code.js', 'r', encoding='utf-8') as f:
    js_code = f.read()

# 编译JS代码
ctx = execjs.compile(js_code)

def generate_sign(params, secret):
    """调用JS加签函数生成签名"""
    try:
        # 调用JS中的generateSign函数
        sign = ctx.call('generateSign', params, secret)
        return sign
    except Exception as e:
        print(f"生成签名出错: {e}")
        return None

if __name__ == "__main__":
    # 测试参数
    test_params = {
        'username': 'test',
        'password': '123456',
        'timestamp': 1620000000,
        'nonce': 'abc123'
    }
    test_secret = 'my_secret_key'
    
    # 生成签名
    sign = generate_sign(test_params, test_secret)
    print(f"生成的签名: {sign}")
    
    # 可以将签名添加到请求参数中发送请求
    # request_params = {**test_params, 'sign': sign}
    # 发送请求...

3. 处理复杂依赖

如果加签函数依赖较多其他函数或库,可以:

1.** 完整提取依赖 :将所有相关函数和变量都提取到 JS 文件中 2. 使用虚拟环境 **:对于浏览器特定的 API(如 window、document),可以在 JS 代码中添加模拟实现

javascript 复制代码
// 模拟浏览器环境
var window = {};
var document = {
    cookie: ''
};

3.** 分模块处理 **:如果代码量很大,可以拆分成多个 JS 文件,在 Python 中依次加载

五、常见问题及解决方案

1.** 运行时错误 **- 确保 Node.js 已正确安装并配置到环境变量

  • 检查 JS 代码是否有语法错误
  • 确认所有依赖函数都已被正确提取

2.** 签名不匹配 **- 检查参数排序方式是否与原网站一致

  • 确认编码方式(如 UTF-8)是否正确
  • 检查是否有隐藏参数参与签名计算

3.** 代码混淆处理 **- 使用在线工具(如 jsbeautifier)格式化代码

  • 逐步调试,替换混淆的变量名,提高可读性
  • 对于复杂混淆,可考虑使用 AST 工具辅助分析

六、注意事项

1.** 法律与伦理 :确保你的逆向分析行为符合相关法律法规,仅用于合法目的 2. 网站政策 :尊重网站的 robots.txt 和使用条款 3. 动态变化 :网站的加签逻辑可能会定期更新,需要定期维护你的代码 4. 性能考虑 **:对于高频调用,可考虑将 JS 代码转换为 Python 实现以提高性能

通过以上步骤,你可以成功逆向分析网站的加签逻辑并使用 Python 进行模拟执行。实际操作中可能会遇到各种复杂情况,需要结合具体场景灵活运用调试技巧。

相关推荐
over697几秒前
从代码到歌词:我用AI为汪峰创作了一首情歌
前端
老前端的功夫1 分钟前
JavaScript的`this`指向:送你一张永远不会错的地图
前端
前端没钱1 分钟前
Tauri2+vue3+NaiveUI仿写windows微信,安装包仅为2.5M,95%的API用JavaScript写,太香了
前端·vue.js·rust
用户279428286132 分钟前
HTML5 敲击乐:从零搭建交互式前端音乐项目
前端
KongHen2 分钟前
UTS编写字符串编解码/加密插件(安卓及鸿蒙端)
前端·harmonyos
知其然亦知其所以然7 分钟前
我被问懵了:Tomcat 到底有几种部署方式?
后端·面试·tomcat
Cache技术分享9 分钟前
219. Java 函数式编程风格 - 从命令式风格到函数式风格:迭代与数据转换
前端·后端
豆苗学前端12 分钟前
JavaScript原型对象、构造函数、继承与类详解
前端·javascript·后端
飞翔的佩奇15 分钟前
【完整源码+数据集+部署教程】【运动的&足球】足球比赛分析系统源码&数据集全套:改进yolo11-RFAConv
前端·python·yolo·计算机视觉·数据集·yolo11·足球比赛分析系统
支付宝体验科技18 分钟前
SEE Conf 2025:开启体验科技的新十年
前端