feat: skill v3.2.0 — 硬约束Checklist五项压缩到三项,移除MCP session依赖,cases/成为唯一经验库

- SKILL.md 瘦身重写(核心层+按需加载references/)
- Checklist: CHECK-3/4(session)删除,五项→三项
- 新增6个references子文档(path-a/path-b/phase-details/experience-rules-full/mcp-tool-reference/common-pitfalls)
- 删除 references/domain-session-guide.md
- 工具引用对齐实际MCP(32工具),verify_signer_offline替代verify_against_session
- cases/_template.md 新增可验证事实清单段
- 经验法则session相关条目改写
- 红线四条、第一原则0-5、三分法、四板斧、六步法完整保留
This commit is contained in:
白夜
2026-04-18 13:36:14 +08:00
parent a5228600f4
commit 38b982fb1e
13 changed files with 2905 additions and 2067 deletions
+58 -59
View File
@@ -17,42 +17,42 @@
| **截图** | `take_screenshot` / `take_snapshot` | 截图 / 无障碍树 |
| **页面信息** | `get_page_info` / `get_page_html` | 页面状态和 HTML |
| **源码搜索** | `search_code` | 在所有 JS 中搜索(结构化结果,默认 max_results=50) |
| **精确搜索** | `search_code_in_script` | 在指定脚本中搜索(前后 3 行上下文,适合大文件) |
| **源码获取** | `get_script_source` | 获取指定脚本的代码 |
| **源码保存** | `save_script` | 将脚本保存到本地文件 |
| **脚本列表** | `list_scripts` | 列出页面加载的所有脚本 |
| **精确搜索** | `search_code(..., script_url=...)` | 在指定脚本中搜索(前后 3 行上下文,适合大文件) | <!-- v3.1.0: migrated from search_code_in_script -->
| **源码获取** | `scripts(action='get', ...)` | 获取指定脚本的代码 | <!-- v3.1.0: migrated from get_script_source -->
| **源码保存** | `scripts(action='save', ...)` | 将脚本保存到本地文件 | <!-- v3.1.0: migrated from save_script -->
| **脚本列表** | `scripts(action='list')` | 列出页面加载的所有脚本 | <!-- v3.1.0: migrated from list_scripts -->
| **执行 JS** | `evaluate_js` / `evaluate_js_handle` | 在页面执行任意 JS |
| **加载前注入** | `add_init_script` | 页面加载前注入脚本(支持 `persistent` 跨导航重注入) |
| **伪断点** | `set_breakpoint_via_hook` | 通过 Hook 设置伪断点(支持 `persistent` 持久化) |
| **断点数据** | `get_breakpoint_data` | 获取伪断点捕获的数据 |
| **函数追踪** | `trace_function` / `get_trace_data` | 追踪函数调用(支持 `persistent` 跨导航持久化) |
| **函数追踪** | `hook_function(..., mode='trace', ...)` / `get_trace_data` | 追踪函数调用(支持 `persistent` 跨导航持久化) | <!-- v3.1.0: migrated from trace_function -->
| **自定义 Hook** | `hook_function` | 注入自定义 Hook(before/after/replace,支持 `non_overridable` 防覆盖) |
| **预设 Hook** | `inject_hook_preset` | 一键 Hook(xhr/fetch/crypto/websocket/debugger_bypass,默认持久化) |
| **移除 Hook** | `remove_hooks` | 移除所有 Hook(支持 `keep_persistent` 保留持久化 Hook) |
| **冻结原型** | `freeze_prototype` | 冻结任意原型方法,防止页面 JS 覆盖 Hook |
| **属性追踪** | `trace_property_access` / `get_property_access_log` | Proxy 级别属性访问追踪 |
| **冻结原型** | `hook_function(..., mode='intercept', ...)` | 冻结任意原型方法,防止页面 JS 覆盖 Hook | <!-- v3.1.0: migrated from freeze_prototype -->
| **属性追踪** | `hook_jsvmp_interpreter(mode='proxy', trackProps=True)` / `get_property_access_log` | Proxy 级别属性访问追踪 | <!-- v3.1.0: migrated from trace_property_access -->
| **JSVMP 插桩** | `hook_jsvmp_interpreter` | 一键插桩 JSVMP(Function.prototype.apply + 30+ 敏感属性) |
| **JSVMP 日志** | `get_jsvmp_log` | 获取 JSVMP 日志(API 调用统计 + 属性读取摘要) |
| **JSVMP 字符串** | `dump_jsvmp_strings` | 提取字符串数组,识别 API 名称,检测混淆模式 |
| **环境采集** | `compare_env` | 全面收集浏览器环境(navigator/screen/canvas/WebGL/Audio/timing) |
| **网络捕获** | `start_network_capture` / `stop_network_capture` | 启停网络捕获(支持 `capture_body` 捕获响应体) |
| **网络捕获** | `network_capture(action='start', ...)` / `network_capture(action='stop')` | 启停网络捕获(支持 `capture_body` 捕获响应体) | <!-- v3.1.0: migrated from start_network_capture / stop_network_capture -->
| **网络请求** | `list_network_requests` | 列出捕获的请求 |
| **请求详情** | `get_network_request` | 获取请求完整信息(含响应体) |
| **请求来源** | `get_request_initiator` | 获取请求的 JS 调用栈(改进 URL 匹配 + 诊断信息) |
| **请求拦截** | `intercept_request` / `stop_intercept` | 拦截/修改/Mock 请求 |
| **Cookie** | `get_cookies` / `set_cookies` / `delete_cookies` | Cookie 管理 |
| **Cookie** | `cookies(action='get', ...)` / `cookies(action='set', ...)` / `delete_cookies` | Cookie 管理 | <!-- v3.1.0: migrated from get_cookies / set_cookies -->
| **Storage** | `get_storage` / `set_storage` | localStorage / sessionStorage |
| **状态管理** | `export_state` / `import_state` | 保存/恢复浏览器状态 |
| **控制台** | `get_console_logs` | 读取控制台输出 |
| **指纹** | `get_fingerprint_info` | 检查浏览器指纹 |
| **反检测** | `check_detection` | 测试是否被反爬识别 |
| **反调试** | `bypass_debugger_trap` | 绕过 debugger 陷阱 |
| **分发循环扫描** | `find_dispatch_loops` | **[v0.4.0]** 定位字节码分发函数(while+switch,case 数过滤) |
| **源码级插桩** | `instrument_jsvmp_source` | **[v0.4.0]** HTTP 层改写 VMP,每个 obj[key]/fn(args) 插入 tap(通用 VMP 利器) |
| **插桩日志** | `get_instrumentation_log` | **[v0.4.0]** 拉取源码插桩日志,带 hot_keys/hot_methods/hot_functions 摘要 |
| **插桩状态** | `get_instrumentation_status` / `stop_instrumentation` | **[v0.4.0]** 查看/停止源码插桩 |
| **分发循环扫描** | `search_code(keyword='switch', script_url=..., context_chars=500)` | **[v0.4.0]** 定位字节码分发函数(while+switch,case 数过滤) | <!-- v3.1.0: migrated from find_dispatch_loops -->
| **源码级插桩** | `instrumentation(action='install', ...)` | **[v0.4.0]** HTTP 层改写 VMP,每个 obj[key]/fn(args) 插入 tap(通用 VMP 利器) | <!-- v3.1.0: migrated from instrument_jsvmp_source -->
| **插桩日志** | `instrumentation(action='log', ...)` | **[v0.4.0]** 拉取源码插桩日志,带 hot_keys/hot_methods/hot_functions 摘要 | <!-- v3.1.0: migrated from get_instrumentation_log -->
| **插桩状态** | `check_environment()` / `instrumentation(action='stop', ...)` | **[v0.4.0]** 查看/停止源码插桩 | <!-- v3.1.0: migrated from get_instrumentation_status / stop_instrumentation -->
| **Cookie 归因** | `analyze_cookie_sources` | **[v0.4.0]** 融合 HTTP Set-Cookie + JS document.cookie + cookie jar |
| **hook 重载** | `reload_with_hooks` | **[v0.4.0]** 重载使 persistent hook 先于页面 JS 执行(+ 清日志) |
| **hook 重载** | `instrumentation(action='reload')` | **[v0.4.0]** 重载使 persistent hook 先于页面 JS 执行(+ 清日志) | <!-- v3.1.0: migrated from reload_with_hooks -->
| **运行时探针日志** | `get_runtime_probe_log` | **[v0.4.0]** 获取 runtime_probe 预设的广谱事件日志 |
| **预设 Hook(扩展)** | `inject_hook_preset("cookie")` / `inject_hook_preset("runtime_probe")` | **[v0.4.0]** 新增两个预设 |
| **首屏注入** | `navigate(pre_inject_hooks=[...])` | **[v0.4.0]** 经 about:blank 装 hook 再 goto,解决首屏挑战页 |
@@ -74,7 +74,7 @@
[camoufox-reverse] take_screenshot() → 确认页面正常
步骤 4:开始网络捕获
[camoufox-reverse] start_network_capture()
[camoufox-reverse] network_capture(action='start') <!-- v3.1.0: migrated from start_network_capture -->
步骤 5:触发数据请求(如翻页)
[camoufox-reverse] click(selector=".next-page")
@@ -97,7 +97,7 @@
[camoufox-reverse] search_code(keyword="参数名")
步骤 10:读取相关源码
[camoufox-reverse] get_script_source(script_url="包含加密逻辑的脚本URL")
[camoufox-reverse] scripts(action='get', script_url="包含加密逻辑的脚本URL") <!-- v3.1.0: migrated from get_script_source -->
步骤 11:设置伪断点验证
[camoufox-reverse] set_breakpoint_via_hook(target_function="加密函数路径")
@@ -129,13 +129,13 @@
步骤 4:根据调用栈定位生成函数
[camoufox-reverse] search_code(keyword="目标函数名")
[camoufox-reverse] get_script_source(script_url="...")
[camoufox-reverse] scripts(action='get', script_url="...") <!-- v3.1.0: migrated from get_script_source -->
步骤 5:分析生成逻辑
[camoufox-reverse] set_breakpoint_via_hook(target_function="cookie生成函数")
刷新页面 →
[camoufox-reverse] get_breakpoint_data → 查看入参和返回值
[camoufox-reverse] trace_function(function_path="加密函数", log_args=true, log_return=true, log_stack=true)
[camoufox-reverse] hook_function(function_path="加密函数", mode='trace', log_args=true, log_return=true, log_stack=true) <!-- v3.1.0: migrated from trace_function -->
[camoufox-reverse] get_trace_data → 查看中间值
```
@@ -145,11 +145,11 @@
```
步骤 1:列出所有脚本
[camoufox-reverse] list_scripts
[camoufox-reverse] scripts(action='list') <!-- v3.1.0: migrated from list_scripts -->
→ 找到可疑的混淆脚本(通常文件名无意义或体积很大)
步骤 2:保存混淆脚本到本地
[camoufox-reverse] save_script(script_url="混淆脚本URL", save_path="./project/obfuscated.js")
[camoufox-reverse] scripts(action='save', script_url="混淆脚本URL", save_path="./project/obfuscated.js") <!-- v3.1.0: migrated from save_script -->
步骤 3:搜索关键特征
[camoufox-reverse] search_code(keyword="_0x")
@@ -165,7 +165,7 @@
步骤 5:定位关键函数
[camoufox-reverse] search_code(keyword="encrypt|sign|md5|aes")
→ 找到加密相关代码的大致位置
[camoufox-reverse] get_script_source → 获取上下文
[camoufox-reverse] scripts(action='get') → 获取上下文 <!-- v3.1.0: migrated from get_script_source -->
```
### 场景 4:WASM 逆向
@@ -220,7 +220,7 @@
```
步骤 1:启动浏览器 + 开启响应体捕获
[camoufox-reverse] launch_browser(headless=False)
[camoufox-reverse] start_network_capture(capture_body=True)
[camoufox-reverse] network_capture(action='start', capture_body=True) <!-- v3.1.0: migrated from start_network_capture -->
步骤 2:第一次导航定位 VMP 脚本
[camoufox-reverse] navigate(url="https://target.com/")
@@ -228,14 +228,13 @@
→ 找最大的 JS(100KB+,通常是 sdenv-*.js / FuckCookie_*.js / webmssdk.es5.js)
步骤 3:确认是 VMP
[camoufox-reverse] find_dispatch_loops(
script_url="https://target.com/xxx/sdenv-xxx.js",
[camoufox-reverse] search_code(keyword='switch', script_url="https://target.com/xxx/sdenv-xxx.js", context_chars=500) <!-- v3.1.0: migrated from find_dispatch_loops -->
min_case_count=20
)
→ case_count > 50 基本确认是 VMP
步骤 4:装源码级插桩(核心)
[camoufox-reverse] instrument_jsvmp_source(
[camoufox-reverse] instrumentation(action='install', <!-- v3.1.0: migrated from instrument_jsvmp_source -->
url_pattern="**/sdenv-*.js",
mode="ast", # 能联网用 ast(99% 覆盖);离线用 regex(80%)
tag="vmp1"
@@ -248,26 +247,26 @@
[camoufox-reverse] bypass_debugger_trap()
步骤 6:重载让插桩先于 VMP 生效
[camoufox-reverse] reload_with_hooks()
[camoufox-reverse] instrumentation(action='reload') <!-- v3.1.0: migrated from reload_with_hooks -->
步骤 7:触发业务操作(翻页 / 登录 / 搜索)
步骤 8:读 hot_keys / hot_methods / hot_functions(30 秒读完 VMP 指纹)
[camoufox-reverse] get_instrumentation_log(
[camoufox-reverse] instrumentation(action='log', <!-- v3.1.0: migrated from get_instrumentation_log -->
tag_filter="vmp1",
type_filter="tap_get", # 所有 obj[key] 读取
limit=200
)
→ summary.hot_keys: VMP 读了哪些属性(top 30,按频次)
[camoufox-reverse] get_instrumentation_log(
[camoufox-reverse] instrumentation(action='log', <!-- v3.1.0: migrated from get_instrumentation_log -->
tag_filter="vmp1",
type_filter="tap_method", # 所有 obj.method(args) 调用
limit=200
)
→ summary.hot_methods: VMP 调了哪些方法(Array.prototype.join / CryptoJS.MD5 ...)
[camoufox-reverse] get_instrumentation_log(
[camoufox-reverse] instrumentation(action='log', <!-- v3.1.0: migrated from get_instrumentation_log -->
tag_filter="vmp1",
type_filter="tap_call", # 所有 fn(args) 直接调用
limit=200
@@ -280,7 +279,7 @@
+ http_responses[].url + js_writes[].stack
步骤 10:完工清理
[camoufox-reverse] stop_instrumentation(url_pattern="**/sdenv-*.js")
[camoufox-reverse] instrumentation(action='stop', url_pattern="**/sdenv-*.js") <!-- v3.1.0: migrated from stop_instrumentation -->
[camoufox-reverse] remove_hooks()
```
@@ -301,7 +300,7 @@
```
步骤 1:启动环境 + 开启响应体捕获 + cookie hook
[camoufox-reverse] launch_browser(headless=False)
[camoufox-reverse] start_network_capture(capture_body=True)
[camoufox-reverse] network_capture(action='start', capture_body=True) <!-- v3.1.0: migrated from start_network_capture -->
[camoufox-reverse] inject_hook_preset(preset="cookie", persistent=True) # 原型链级
步骤 2:导航到目标(首屏有挑战用 pre_inject_hooks)
@@ -348,11 +347,12 @@
## 高级技巧
### 使用 trace_function 自动记录函数调用
### 使用 hook_function(mode='trace') 自动记录函数调用 <!-- v3.1.0: migrated from trace_function -->
```
[camoufox-reverse] trace_function(
[camoufox-reverse] hook_function( <!-- v3.1.0: migrated from trace_function -->
function_path="window.encrypt",
mode='trace',
log_args=true,
log_return=true,
log_stack=true,
@@ -387,10 +387,10 @@
```
→ 在 XHR.open 调用前输出请求方法和 URL,即使页面 JS 尝试覆盖也不会丢失
### 使用 freeze_prototype 防止 Hook 被覆盖
### 使用 hook_function(mode='intercept') 防止 Hook 被覆盖 <!-- v3.1.0: migrated from freeze_prototype -->
```
[camoufox-reverse] freeze_prototype(className="XMLHttpRequest", methodName="send")
[camoufox-reverse] hook_function(className="XMLHttpRequest", methodName="send", mode='intercept') <!-- v3.1.0: migrated from freeze_prototype -->
```
→ 冻结原型方法(configurable:false + writable:false),防止 JSVMP 等覆盖你的 Hook
@@ -431,16 +431,16 @@ await navigate(url, pre_inject_hooks=["jsvmp_probe_transparent"])
### 使用属性访问追踪
```
[camoufox-reverse] trace_property_access(target_expression="navigator")
[camoufox-reverse] hook_jsvmp_interpreter(mode='proxy', trackProps=True, target_expression="navigator") <!-- v3.1.0: migrated from trace_property_access -->
触发操作...
[camoufox-reverse] get_property_access_log → 查看 navigator 的哪些属性被读取
```
→ 精确发现 JSVMP 或签名逻辑读取了哪些环境属性
### 使用 search_code_in_script 精确搜索大文件
### 使用 search_code(..., script_url=...) 精确搜索大文件 <!-- v3.1.0: migrated from search_code_in_script -->
```
[camoufox-reverse] search_code_in_script(script_id=3, keyword="sign|token|encrypt")
[camoufox-reverse] search_code(keyword="sign|token|encrypt", script_url=3) <!-- v3.1.0: migrated from search_code_in_script -->
```
→ 在指定脚本中搜索,返回前后 3 行上下文,适合 200KB+ 的 JSVMP 文件
@@ -484,10 +484,10 @@ await navigate(url, pre_inject_hooks=["jsvmp_probe_transparent"])
```
# 1. 先确认是不是 VMP(case_count > 50 基本是)
[camoufox-reverse] find_dispatch_loops(script_url="https://target.com/sdenv-xxx.js", min_case_count=20)
[camoufox-reverse] search_code(keyword='switch', script_url="https://target.com/sdenv-xxx.js", context_chars=500) <!-- v3.1.0: migrated from find_dispatch_loops -->
# 2. 装插桩(AST 模式优先,需 CDN;regex 模式兜底)
[camoufox-reverse] instrument_jsvmp_source(
[camoufox-reverse] instrumentation(action='install', <!-- v3.1.0: migrated from instrument_jsvmp_source -->
url_pattern="**/sdenv-*.js", # glob 模式匹配多 hash 版本
mode="ast", # 或 "regex"
tag="vmp1", # 区分多 VMP 的标签
@@ -498,21 +498,21 @@ await navigate(url, pre_inject_hooks=["jsvmp_probe_transparent"])
)
# 3. 装完后必须重载让插桩生效
[camoufox-reverse] reload_with_hooks()
[camoufox-reverse] instrumentation(action='reload') <!-- v3.1.0: migrated from reload_with_hooks -->
# 4. 触发操作后读日志
[camoufox-reverse] get_instrumentation_log(tag_filter="vmp1", type_filter="tap_get", limit=200)
[camoufox-reverse] instrumentation(action='log', tag_filter="vmp1", type_filter="tap_get", limit=200) <!-- v3.1.0: migrated from get_instrumentation_log -->
→ summary.hot_keys 是 VMP 读取的环境属性 top 30(指纹学习金矿)
[camoufox-reverse] get_instrumentation_log(tag_filter="vmp1", type_filter="tap_method", limit=200)
[camoufox-reverse] instrumentation(action='log', tag_filter="vmp1", type_filter="tap_method", limit=200) <!-- v3.1.0: migrated from get_instrumentation_log -->
→ summary.hot_methods 是 VMP 调用的方法 top 30(ObjectType.methodName 格式)
# 5. 查看插桩状态
[camoufox-reverse] get_instrumentation_status()
[camoufox-reverse] check_environment() <!-- v3.1.0: migrated from get_instrumentation_status -->
# 6. 完工移除
[camoufox-reverse] stop_instrumentation(url_pattern="**/sdenv-*.js")
[camoufox-reverse] stop_instrumentation() # 不传参数 = 全部停止
[camoufox-reverse] instrumentation(action='stop', url_pattern="**/sdenv-*.js") <!-- v3.1.0: migrated from stop_instrumentation -->
[camoufox-reverse] instrumentation(action='stop') # 不传参数 = 全部停止 <!-- v3.1.0: migrated from stop_instrumentation -->
```
**与 hook_jsvmp_interpreter 的分工**:
@@ -520,7 +520,7 @@ await navigate(url, pre_inject_hooks=["jsvmp_probe_transparent"])
| 工具 | 能看到 | 看不到 |
|------|--------|--------|
| `hook_jsvmp_interpreter` | VMP 通过 `Function.prototype.apply/call/bind` 或 `Reflect.*` 调子函数,读全局对象属性(Proxy) | VMP 在 switch/case 内部直接 `obj[key]` / `fn(args)` 的调用 |
| `instrument_jsvmp_source` | 每一次 member access + 每一次函数调用,无论是否通过可 hook API | 不跨脚本(只改写指定 url_pattern 的那个文件) |
| `instrumentation(action='install', ...)` | 每一次 member access + 每一次函数调用,无论是否通过可 hook API | 不跨脚本(只改写指定 url_pattern 的那个文件) | <!-- v3.1.0: migrated from instrument_jsvmp_source -->
| **建议**:两者同时开,互相校验 | | |
#### mode="ast" 的 v0.5.0 变化(v2.6.0 吸收)
@@ -528,15 +528,14 @@ await navigate(url, pre_inject_hooks=["jsvmp_probe_transparent"])
```python
# v2.5.0 / MCP v0.4.x: mode="ast" 会在页面里注入 acorn CDN script tag
# v2.6.0 / MCP v0.5.0: mode="ast" 在 MCP 进程里用 esprima-python 解析,零页面依赖
await instrument_jsvmp_source(
"**/sdenv-*.js",
await instrumentation(action='install', url_pattern="**/sdenv-*.js", <!-- v3.1.0: migrated from instrument_jsvmp_source -->
mode="ast", # 默认,走 MCP 侧 esprima
tag="sdenv",
fallback_on_error=True, # 新参数:esprima 挂就回落 regex
)
# 查看实际走了哪条路径
status = await get_instrumentation_status()
status = await check_environment() <!-- v3.1.0: migrated from get_instrumentation_status -->
# status["active_patterns"][0]["last_mode_used"] == "ast" (正常)
# or "regex (fallback)" (esprima 对该 VMP 的语法支持不全)
# or "ast_page" (你显式用了 deprecated 模式)
@@ -546,14 +545,14 @@ status = await get_instrumentation_status()
```python
# 仅用于 A/B 对比 v0.4.x 的旧页面内 Acorn 实现,deprecated
# 生产不要用,挑战页会因 CDN 被拦静默失败
await instrument_jsvmp_source("**/vmp.js", mode="ast_page")
await instrumentation(action='install', url_pattern="**/vmp.js", mode="ast_page") <!-- v3.1.0: migrated from instrument_jsvmp_source -->
```
### 使用 Cookie 归因分析(v2.5.0 新增)
```
# 1. 前置条件:网络抓包 + cookie hook 同时开
[camoufox-reverse] start_network_capture(capture_body=True)
[camoufox-reverse] network_capture(action='start', capture_body=True) <!-- v3.1.0: migrated from start_network_capture -->
[camoufox-reverse] inject_hook_preset(preset="cookie", persistent=True)
# 2. 触发场景
@@ -616,15 +615,15 @@ await instrument_jsvmp_source("**/vmp.js", mode="ast_page")
| 页面导航 | `navigate` `reload` `go_back` | 导航控制 |
| 页面交互 | `click` `type_text` `wait_for` | UI 自动化 |
| 页面状态 | `get_page_info` `take_screenshot` `take_snapshot` `get_page_html` | 页面信息 |
| 源码分析 | `list_scripts` `get_script_source` `search_code` `search_code_in_script` `save_script` | JS 逆向核心 |
| 源码分析 | `scripts(action='list')` `scripts(action='get', ...)` `search_code` `search_code(..., script_url=...)` `scripts(action='save', ...)` | JS 逆向核心 | <!-- v3.1.0: migrated from list_scripts, get_script_source, search_code_in_script, save_script -->
| JS 执行 | `evaluate_js` `evaluate_js_handle` `add_init_script` | 代码执行(支持持久化) |
| 调试 | `set_breakpoint_via_hook` `get_breakpoint_data` `get_console_logs` | 伪断点调试(支持持久化) |
| Hook | `trace_function` `get_trace_data` `hook_function` `inject_hook_preset` `remove_hooks` `freeze_prototype` | 函数 Hook(支持持久化 + 防覆盖) |
| 属性追踪 | `trace_property_access` `get_property_access_log` | Proxy 级别属性访问监控 |
| Hook | `hook_function(..., mode='trace', ...)` `get_trace_data` `hook_function` `inject_hook_preset` `remove_hooks` `hook_function(..., mode='intercept', ...)` | 函数 Hook(支持持久化 + 防覆盖) | <!-- v3.1.0: migrated from trace_function, freeze_prototype -->
| 属性追踪 | `hook_jsvmp_interpreter(mode='proxy', trackProps=True)` `get_property_access_log` | Proxy 级别属性访问监控 | <!-- v3.1.0: migrated from trace_property_access -->
| JSVMP 专项 | `hook_jsvmp_interpreter` `get_jsvmp_log` `dump_jsvmp_strings` `compare_env` | JSVMP 虚拟机保护分析 |
| 网络 | `start_network_capture` `stop_network_capture` `list_network_requests` `get_network_request` `get_request_initiator` `intercept_request` `stop_intercept` | 网络分析(支持响应体捕获) |
| 存储 | `get_cookies` `set_cookies` `delete_cookies` `get_storage` `set_storage` `export_state` `import_state` | 状态管理 |
| 网络 | `network_capture(action='start', ...)` `network_capture(action='stop')` `list_network_requests` `get_network_request` `get_request_initiator` `intercept_request` `stop_intercept` | 网络分析(支持响应体捕获) | <!-- v3.1.0: migrated from start_network_capture, stop_network_capture -->
| 存储 | `cookies(action='get', ...)` `cookies(action='set', ...)` `delete_cookies` `get_storage` `set_storage` `export_state` `import_state` | 状态管理 | <!-- v3.1.0: migrated from get_cookies, set_cookies -->
| 反检测 | `get_fingerprint_info` `check_detection` `bypass_debugger_trap` | 指纹与反检测 |
| 源码级插桩 | `instrument_jsvmp_source` `get_instrumentation_log` `get_instrumentation_status` `stop_instrumentation` `find_dispatch_loops` | **[v0.4.0]** 通用 JSVMP 逆向利器 |
| 源码级插桩 | `instrumentation(action='install', ...)` `instrumentation(action='log', ...)` `check_environment()` `instrumentation(action='stop', ...)` `search_code(keyword='switch', script_url=..., context_chars=500)` | **[v0.4.0]** 通用 JSVMP 逆向利器 | <!-- v3.1.0: migrated from instrument_jsvmp_source, get_instrumentation_log, get_instrumentation_status, stop_instrumentation, find_dispatch_loops -->
| Cookie 归因 | `analyze_cookie_sources` | **[v0.4.0]** HTTP Set-Cookie + JS 写入融合分析 |
| 导航增强 | `navigate(pre_inject_hooks)` `reload_with_hooks` `get_runtime_probe_log` | **[v0.4.0]** 首屏挑战/hook 重注入/运行时探针 |
| 导航增强 | `navigate(pre_inject_hooks)` `instrumentation(action='reload')` `get_runtime_probe_log` | **[v0.4.0]** 首屏挑战/hook 重注入/运行时探针 | <!-- v3.1.0: migrated from reload_with_hooks -->