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 进行模拟执行。实际操作中可能会遇到各种复杂情况,需要结合具体场景灵活运用调试技巧。

相关推荐
ObjectX前端实验室2 小时前
【图形编辑器架构】:无限画布标尺与网格系统实现解析
前端·canvas·图形学
你的电影很有趣3 小时前
lesson71:Node.js与npm基础全攻略:2025年最新特性与实战指南
前端·npm·node.js
闲蛋小超人笑嘻嘻3 小时前
find数组方法详解||Vue3 + uni-app + Wot Design(wd-picker)使用自定义插槽内容写一个下拉选择器
前端·javascript·uni-app
小牛itbull3 小时前
初始化electron项目运行后报错 electron uninstall 解决方法
前端·javascript·electron
聪明的笨猪猪4 小时前
Java 集合 “Map(1)”面试清单(含超通俗生活案例与深度理解)
java·经验分享·笔记·面试
闲蛋小超人笑嘻嘻4 小时前
前端面试十四之webpack和vite有什么区别
前端·webpack·node.js
rggrgerj4 小时前
Vue3 组件完全指南代码
前端·javascript·vue.js
独行soc6 小时前
2025年渗透测试面试题总结-98(题目+回答)
网络·安全·web安全·adb·面试·渗透测试·安全狮
golang学习记6 小时前
从0死磕全栈之Next.js App Router动态路由详解:从入门到实战
前端