|
|
1 semana atrás | |
|---|---|---|
| .. | ||
| README.md | 1 semana atrás | |
| YamlLoader.py | 4 meses atrás | |
| application.yml | 4 meses atrás | |
| jhs_raw_codec_client.py | 1 semana atrás | |
| jhs_raw_codec_rpc.js | 4 meses atrás | |
| jhs_rpc_spider.py | 1 semana atrás | |
| mysql_pool.py | 4 meses atrás | |
| requirements.txt | 1 semana atrás | |
| start_auto_dismiss.ps1 | 1 semana atrás | |
| 去除升级弹窗.txt | 1 semana atrás | |
基于 Frida RPC 的 raw_data 编解码调用封装,核心依赖 App 运行时中的 Java 层逻辑(gc.b.b / gc.a.intercept)。
jhs_raw_codec_rpc.js:Frida 侧 RPC 脚本(实现 enc/dec)jhs_raw_codec_client.py:Python 客户端封装(设备连接、attach、RPC 调用、CLI 兜底)jhs_rpc_spider.py:主爬虫脚本(定时采集 + 入库)demo.py:单页请求封装示例(可直接改为多页循环)auto_dismiss_update.js:常驻 Frida 脚本(自动 dismiss App 启动时的"立即更新"弹窗)start_auto_dismiss.ps1 / stop_auto_dismiss.ps1:弹窗清除脚本的后台启动 / 停止start_jhs_zygiskfrida_bg.ps1 / stop_jhs_zygiskfrida_bg.ps1:旧版后台 hook 启停脚本(当前未使用,保留备查)application.yml:配置文件(数据库等)requirements.txt:Python 依赖清单adb version 正常)frida --version 正常)frida、frida-tools、requests本项目使用 ZygiskFrida(Zygisk 模块)而非传统 frida-server。 ZygiskFrida 会在 App 启动时自动将 frida-gadget 注入目标进程,无需手动推送或运行 frida-server。
com.jihuanshecom.jihuanshe在 scripts/raw_codec_rpc 目录下执行:
python -m venv .venv
.venv\Scripts\activate
pip install -r requirements.txt
确认命令可用:
python -c "import frida, requests; print('ok')"
frida --version
adb version
本项目不使用传统的
frida-server,而是通过 ZygiskFrida 模块在 App 启动时自动注入 frida-gadget。
在 /data/local/tmp/re.zyg.fri/target_packages.txt 中添加目标包名:
com.jihuanshe
重启设备使模块生效
验证:启动目标 App 后,在 PC 端执行:
frida -U -N com.jihuanshe
如果能正常 attach 说明 gadget 注入成功。
老版本 App 启动会弹"立即更新"提示,挡住登录等人工操作。提供常驻 Frida 脚本自动 dismiss:
启动(重启 App → 等待 gadget 注入 → 挂载 dismiss 脚本):
.\start_auto_dismiss.ps1 # 后台运行
.\start_auto_dismiss.ps1 -Foreground # 前台跑,看实时日志(推荐调试时用)
.\start_auto_dismiss.ps1 -NoRestart # App 已经在跑,跳过重启直接 attach
可选参数:
| 参数 | 默认值 | 说明 |
|---|---|---|
-Package |
com.jihuanshe |
目标包名 |
-DelayMs |
12000 |
等待 ZygiskFrida 注入毫秒数 |
-Adb |
D:\platform-tools\adb.exe |
adb 路径 |
-Frida |
C:\Python\Python312\Scripts\frida.exe |
frida CLI 路径 |
-Hook |
auto_dismiss_update.js |
hook 脚本路径 |
-NoRestart |
关 | 加上则跳过 App 重启,直接 attach |
-Foreground |
关 | 前台运行(Ctrl+C 停止);不加则后台运行写日志文件 |
停止:
.\stop_auto_dismiss.ps1
说明:弹窗只挡人工操作,不影响爬虫 RPC(爬虫不碰 UI),所以该脚本只在「需要登录刷 token」时跑一次即可,日常爬取不需要。
只要 App 在手机上正常运行(ZygiskFrida 会在 App 启动时自动注入 gadget),直接:
python .\jhs_rpc_spider.py
爬虫的 JhsRawCodecClient 会自己 attach 到 App 调 RPC,不需要任何其他守护进程。弹窗在不在都无所谓。
jhs_token 表里的 token 是 JWT,过期后接口会返回 401 MARKET_UNAUTHORIZED,爬虫报 KeyError: 'raw_data'。流程:
# 1. 启动弹窗清除(推荐 -Foreground 看日志)
# App 还没开 → 用这条(会自动重启 App 并等待注入)
.\start_auto_dismiss.ps1 -Foreground
# App 已经在跑 → 用这条(跳过重启,直接 attach,更快)
.\start_auto_dismiss.ps1 -NoRestart -Foreground
# 看到 [dismiss] all hooks installed 即可,弹窗一出来就会被自动关掉
# 2. 在手机里登录账号;用抓包工具拿新 token
# (token 在登录接口返回里,或后续请求的 token 参数)
# 3. 手动 UPDATE 数据库
# UPDATE jhs_token SET token = '<新token>' WHERE id = 1;
# (写库操作必须人工执行)
# 4. Ctrl+C 停掉 dismiss 脚本(或者 .\stop_auto_dismiss.ps1)
# 5. 跑爬虫
python .\jhs_rpc_spider.py
JhsRawCodecClient(...) 支持:
device_id:指定设备 ID(多模拟器必须传)cli_target_sec:CLI 兜底模式的 frida -t 秒数(建议 2 或 3)可选环境变量(不强制):
FRIDA_DEVICE_IDFRIDA_CLI_TARGET_SECJHS_CODEC_DEBUG(1/true/on 开启日志)核心原则:client 和 Session 放在循环外,只创建一次。
from jhs_raw_codec_client import JhsRawCodecClient
import requests
page = 1
with JhsRawCodecClient(device_id="25051FDD4S018P", cli_target_sec=2) as client:
with requests.Session() as sess:
while page < 100:
result = fetch_market_page(
page=page,
token=TOKEN,
client=client,
session=sess,
headers=HEADERS,
)
print(page, result["decoded"])
page += 1
JhsRawCodecClientrequests.Sessioncli_target_sec 建议先设 2,不稳定再回退 3JHS_CODEC_DEBUGunable to attach ...device_id 传对target_packages.txt 包含目标包名start_jhs_zygiskfrida_bg.ps1 重新走完流程)Java is not definedcli_target_secdevice_idadb devices / frida-ls-devices 核对 ID老版本 App 启动会弹"有新版本 / 立即更新",挡住登录操作。
先用算法助手(LSPosed 模块)的「拦截关键词弹窗」开关,多数 App 这样就够了。
若算法助手失效(集换社这个弹窗就是):它不是标准 Dialog,而是 App 自己用 WindowManager.addView() 手撸的自定义弹窗,算法助手只盯标准 Dialog,盯不到这层。解决:
# App 已经在跑、弹窗正显示时,直接 attach 我们的脚本即可
.\start_auto_dismiss.ps1 -NoRestart -Foreground
auto_dismiss_update.js 在最底层的 WindowManager.addView() 也下了 hook,能兜住任意形态的弹窗。原理详见 docs/优化记录_jhs_rpc_spider_20260609.md 的 §5、§6。
排查口诀:
WindowManager.addView 实现start_auto_dismiss.ps1 兜底TOKEN 建议不要硬编码在仓库,改为环境变量或外部配置