在安全研究与协议逆向领域,微信小程序的封闭性一直是一个核心议题。与传统的 Web 端不同,小程序默认不提供开发者调试面板。但在长期的分析实践中,社区已经探索出了开启调试权限的方法。无论是通过微信开发者工具的特定启动参数,还是利用类似 WMPFDebugger 的工具对 PC 端微信底层标志位进行 Patch,都可以成功在本地暴露出关键的 WebSocket 调试端口(通常为 127.0.0.1:62000)。然而,获取 CDP(Chrome DevTools Protocol)调试端口仅仅是分析流程的开始。后续的手工调试工作流依然存在显著的效率瓶颈。在逆向分析新小程序的接口签名(如常见的 sig 或 x-sign)时,传统的流程通常如下:随着前端打包压缩(Minification)以及控制流平坦化等 JavaScript 混淆技术在小程序端的普及,这种纯手工的静态分析与动态调试不仅耗时较长,且容易在复杂的调用栈中遗漏关键信息。此前,为了优化 Web 端的逆向流程,我开发并开源了 js-reverse-mcp —— 一个结合大模型(LLM)与自动化框架的辅助工具。考虑到小程序的底层调试机制依然基于标准的 CDP 协议,我提出了一个初步的假设:能否将小程序调试端口接入现有的 js-reverse-mcp,利用大模型辅助完成断点设置和栈回溯工作?这成为我重新审视小程序自动化调试方案的起点。我的初步测试较为直接。js-reverse-mcp 的核心采集器基于 Playwright 的分支(Patchright)构建。我修改了底层配置,利用 playwright.chromium.connectOverCDP() 方法,将 browserUrl 指向了小程序的 WebSocket 调试端点。按照 Web 端的逻辑,Playwright 连接 CDP 后会自动生成对应的 BrowserContext,进而可以通过 page.route() 拦截请求或注入脚本。但在实际测试中,我遇到了预期之外的问题。连接无法保持稳定,系统日志中频繁出现 Timeout 异常。数据采集器无法正常捕获完整的 HTTP 请求序列,在 Web 端稳定的断点逻辑也失去了作用。程序通常在连接目标 Target 后不久,便因内部状态异常而中断运行。为了定位 Playwright 在这一环节失败的具体原因,我暂时移除了高层框架,在本地建立了基础测试工程,尝试仅使用 Node.js 的原生 chrome-remote-interface 库连接小程序的 CDP 端口。通过对比 WebSocket 传输的底层协议帧,我确认了高层自动化框架在此场景下存在兼容性冲突的根源。第一,Playwright 的架构设计强依赖于 DOM 生命周期。Playwright 的核心逻辑建立在 BrowserContext 和 Page 的抽象之上。在状态采集器(如 PageCollector)切分请求历史或判断页面加载状态时,其底层逻辑依赖浏览器内核派发的 framenavigated 或 DOMContentLoaded 等标准生命周期事件。Playwright 默认目标 Target 必须触发这些事件,才能被视为可交互的页面状态。第二,小程序逻辑层(AppService)脱离了 DOM 环境。微信小程序采用了双线程架构。负责界面渲染的是 WebView 层(或 Skyline),而负责网络请求发起、业务逻辑执行及核心加密算法运行的,是相对独立的逻辑层(AppService)。在安卓系统上,逻辑层运行于纯粹的 V8 Isolate 中;在 iOS 上,则运行于 JavaScriptCore 线程中。该环境类似于 Web Worker,内部不包含 window 或 document 对象,也不涉及 DOM 树的解析过程。因此,AppService 线程在其运行周期内,不会向 CDP 派发类似 DOMContentLoaded 的页面导航事件。当 Playwright 尝试将获取到的 AppService Target 封装为标准 Page 对象时,其内部状态机会持续阻塞等待这些缺失的 DOM 事件。这直接导致了断点失效、上下文收集器超时以及连接中断。结论评估:将小程序的隔离上下文直接适配基于单一浏览器窗口状态机的 Playwright 框架存在明显的架构不匹配。为了实现小程序的自动化与 AI 辅助分析,有必要剥离 DOM 层面的抽象,直接基于原生 CDP 协议构建调试模块。在此基础上,我开始了新一轮的架构重构。在确定需要剥离 DOM 依赖后,下一步是寻找合适的底层 CDP 客户端。在 Node.js 生态中虽然存在 chrome-remote-interface,但在纯异步环境下从头实现多路复用、断线重连和事件分发机制需要较高的工程成本。在调研过程中,我关注到了 AI 智能体开源项目 browser-use 团队开发的 Python 基础库 —— cdp-use。分析 cdp-use 源码后,我发现其设计符合当前的架构需求。它基于 Python 的异步机制(asyncio),提供强类型的 CDP 接口。最关键的是,该库未对“页面”或“DOM”进行预设假定,专注于处理基础的 WebSocket 通信:接收 Endpoint,建立 Session,监听 Event 并执行 Command。采用 cdp-use 意味着新工具的技术栈需从 Node.js 迁移至 Python。这一决策综合考虑了后续的开发需求。在当前的开发生态中,Python 在 AI 智能体应用和数据处理领域具备相对优势。考虑到后续需要处理复杂的 Prompt 组装,并对底层返回的 JSON 结果进行结构化清洗,Python 在字符串处理和模型框架对接上提供了更高的便利性。因此,基于 Python 和 cdp-use 的新项目 miniapp-cdp-mcp 正式开源。该项目利用 Target.attachToTarget 和独立 sessionId,在事件层面对小程序的网络通信进行拦截。在底层通信建立后,随之而来的是目标识别(Target Identification)的挑战。在标准的 Web 环境中,建立连接通常意味着获取当前的活跃页面 Target。但在微信小程序环境下,发送 Target.getTargets 指令会返回大量的并发进程。受小程序的运行机制影响,返回列表中包含大量用于预加载的 preload- 线程,以及底层基础组件相关的隐藏 Target。如果探针未进行筛选直接挂载,大概率会连接到无实际业务逻辑的空闲线程,导致无法捕获网络请求或触发断点。为了实现自动化的目标定位,工具需要具备筛选合适调试目标的能力。针对微信小程序的进程特征,我在运行环境(cdp_runtime.py)中实现了一套启发式过滤逻辑。该逻辑的处理流程为:通过这套过滤规则,工具可以在小程序启动后,自动从进程列表中定位并挂载真实的 AppService 逻辑层上下文。解决了框架兼容性和目标识别问题后,底层的 CDP 调试基建已基本稳定。接下来的核心任务是如何优化数据流,使大模型能够高效处理底层协议报文。在建立稳定的
...(已截断)
---
来源: 看雪论坛
原文链接: https://bbs.kanxue.com/thread-290933.htm