diff --git a/phoneuse/event_server.py b/phoneuse/event_server.py index ca5c924..ed4dec4 100644 --- a/phoneuse/event_server.py +++ b/phoneuse/event_server.py @@ -213,3 +213,33 @@ def clear_events(): @app.get("/health") def health(): return {"status": "ok", "ts": time.time()} + + +class XhsParams(BaseModel): + method: str + url: str + headers: dict[str, str] = {} + + +@app.post("/xhs_params", status_code=200) +def post_xhs_params(params: XhsParams): + """Receive forwarded XHS request from xhshook (Hook.java). + Stored in events table as type='xhs_request' so Hermes can poll via GET /events?type=xhs_request.""" + with get_db() as conn: + cursor = conn.execute( + "INSERT INTO events (type, app, data, ts, source) VALUES (?, ?, ?, ?, ?)", + ("xhs_request", "com.xingin.xhs", json.dumps({"method": params.method, "url": params.url, "headers": params.headers}), time.time(), "xhshook") + ) + conn.commit() + return {"id": cursor.lastrowid} + + +@app.get("/xhs_params") +def get_xhs_params(limit: int = Query(default=10, le=100)): + """Latest XHS requests captured by xhshook. Convenience wrapper over GET /events?type=xhs_request.""" + with get_db() as conn: + rows = conn.execute( + "SELECT id, data, ts FROM events WHERE type='xhs_request' ORDER BY id DESC LIMIT ?", + (limit,) + ).fetchall() + return [{"id": r["id"], "ts": r["ts"], **json.loads(r["data"])} for r in reversed(rows)] diff --git a/xhs_lsposed_a16_fix/STATUS.md b/xhs_lsposed_a16_fix/STATUS.md index be99d56..fd63b9a 100644 --- a/xhs_lsposed_a16_fix/STATUS.md +++ b/xhs_lsposed_a16_fix/STATUS.md @@ -13,16 +13,18 @@ --- -## 当前设备状态(2026-06-30 00:33 验证通过) +## 当前设备状态(2026-06-30 01:17 验证通过) ``` 设备:Pixel 10 Pro Fold Android:16 (API 36) Magisk:30.7 LSPosed (Vector fork):正常运行,lspd 进程存活 -xhshook:注入 com.xingin.xhs 成功 +xhshook v3:注入 com.xingin.xhs 成功(mid=4,APK=16863 字节,DEX=6328 字节) xy-common-params:已捕获(见下方样本) curl HTTP 200:已用捕获参数成功复现 API 调用 +xhshook HTTP 转发:POST /xhs_params 已实现,event_server.py 已更新 +event_server.py:已推送到设备 ~/.hermes/event_bus/event_server.py ``` ### 模块布局 @@ -47,8 +49,9 @@ curl HTTP 200:已用捕获参数成功复现 API 调用 ``` 已安装:com.hermes.xhshook(streamed install --no-incremental) APK 含:assets/xposed_init → com.hermes.xhshook.Hook -modules_config.db:mid=1, enabled=1, scope=com.xingin.xhs -APK 路径:/data/app/~~1V3kNj_Xru_4IO7Ixo56Wg==/com.hermes.xhshook-5c7zNdRgh3RtSyoqISuL_A==/base.apk +modules_config.db:mid=4, enabled=1, scope=(4, com.xingin.xhs, 0) +APK 路径:/data/app/~~F2OUnKKEvaoaCC4wwrGOsg==/com.hermes.xhshook-NAAljEo_GRPgf6S_5pp7kw==/base.apk +xhshook v3 新增:HTTP POST 转发到 127.0.0.1:8765/xhs_params(后台线程,1s 超时,静默失败) ``` --- @@ -242,10 +245,30 @@ Hook.java 里已经打印了 `Headers.toString()` 的完整内容——重新抓 su -c "logcat -d -b all | grep 'VectorLegacyBridge'" | grep -v '\[XHSHook\]' | head -30 ``` -### C. 修改 xhshook 做实时转发(高级,需要 Mac 改 Hook.java) +### C. 实时转发 → Hermes event_server ✅ 已完成(2026-06-30 01:17) -改 hook 在 `beforeHookedMethod` 里把完整 header 通过 HTTP POST 转到 Hermes 的本地 server -(如 `localhost:8765`),让 Hermes 实时处理每条请求的签名参数。 +xhshook v3(Hook.java)已在 `beforeHookedMethod` 里启动后台线程 HTTP POST 到 `127.0.0.1:8765/xhs_params`。 +event_server.py 已新增两个端点(已推送到设备 `~/.hermes/event_bus/event_server.py`): + +```bash +# Hermes 启动 event_server 后(uvicorn event_server:app --host 127.0.0.1 --port 8765), +# 打开 XHS,hook 自动转发 edith 请求,Hermes 可以查询: + +# 查最近捕获的 XHS 请求(含完整 headers) +curl http://127.0.0.1:8765/xhs_params + +# 或通过通用 events 接口 +curl "http://127.0.0.1:8765/events/latest?type=xhs_request&app=com.xingin.xhs" +``` + +转发的 JSON 格式:`{"method":"GET","url":"https://edith.xiaohongshu.com/...","headers":{"xy-common-params":"...","x-mini-sig":"...",...}}` + +**启动 event_server 步骤(Termux 里):** +```bash +cd ~/.hermes/event_bus +uvicorn event_server:app --host 127.0.0.1 --port 8765 +# 然后打开 XHS,xhshook 会自动 POST 每条 edith 请求过来 +``` ---