ob-server
Frida-safe Android 观测服务:低延迟画面、实时输入、多设备跟随、日志和文件能力。

01 / PROJECT OVERVIEW
项目研究解读
Frida-safe Android 观测服务:低延迟画面、实时输入、多设备跟随、日志和文件能力。 本仓库以 Python 为主要技术栈,当前快照索引 35 个文件。报告依据README 与目录结构整理,重点呈现项目用途、工程结构和复用方式,不把宣传描述等同于验证结论。
02 / CORE CAPABILITIES
值得关注的能力
- 01
围绕“Frida-safe Android 观测服务:低延迟画面、实时输入、多设备跟随、日志和文件能力”提供公开实现或研究资料
- 02
以 Python 为主,保留 35 个可检查仓库文件
- 03
提供原始 GitHub 链接、目录导览和本地研究快照,便于复核与二次开发
03 / ENGINEERING
工程与仓库结构
仓库以 Python 为主要实现语言,研究快照包含 35 个文件、16 个主要顶层入口。已提供 README 作为使用与能力说明。 项目最近更新时间为 2026-09-09,许可标记为 MIT License。
项目文件与实现资料
项目文件与实现资料
项目文件与实现资料
项目文件与实现资料
项目文件与实现资料
项目文件与实现资料
04 / USE CASES
适合用在哪里
- 学习项目设计与实现
- 评估后用于二次开发
- 作为相关领域的研究参考
05 / QUICK START
从仓库开始
以下命令摘自项目 README 或根据仓库地址生成。请先阅读源仓库的安装要求、许可和脚本,再在自己的环境中运行。
`launch.py` 会把窗口从当前终端 Job 里拆出去,关掉终端不会把 GUI 一起带走。`start.cmd` 优先用 `pythonw`,不挂控制台。
## 操作
手机窗口是无边框等比镜像(真实分辨率比例),类似 macOS 的 iPhone 镜像。
窗口分组:设备列表是独立一组;每台手机的画面窗 + 控制条是一组。新窗口会避开已有组,拖动松开后磁吸对齐。位置写入 `observer.layout.json`,下次启动还原。
### 画面上
| 动作 | 效果 |
| --- | --- |
| 单击 | 原子 tap:按下不立刻发 DOWN,松开时一次注入 DOWN+UP 12ms(避开 MIUI ~400ms 长按阈值) |
| 拖动 | 越过 14 画布像素才发 DOWN + MOVE…UP;MOVE 跟手、不等回执 |
| 右键 | 返回 |
| 中键 / 底栏横条 | 主页 |
| 滚轮 | 在指针位置上下滑动 |
| 右下角拖 | 拉伸窗体 |
| 顶部「拖动」高亮 / 黑边 | 移动整组 |
### 快捷键
| 键 | 效果 |
| --- | --- |
| Esc / BackSpace | 返回 |
| Home | 主页 |
| F5 | 立即刷新 |
| F8 / Ctrl+Shift+C | 截图进剪贴板(不写文件) |
| PgUp / PgDn | 音量 |
### 工具条
鼠标移到画面上,深色工具条会磁吸停在下方(空间不够则靠左 / 右)。「钉住」默认开着;取消后工具条在鼠标离开后收起。
- 常用键:返回 / 主页 / 最近 / 电源 / 音量 / 菜单 / 回车 / 唤醒 / 上滑解锁
- 立即刷新 / 截图 / 暂停画面(暂停只停 UI,编码仍在跑)
- 文字框 + 发送
- **跟随**、置顶、H.264 ⇄ PNG
## 多设备集控
上限就是本机能列出的设备(`adb devices` + usbmux)。Android 每台独立 LiveEnc / LiveInput / logcat;iOS 每台独立截图 / HID / syslog。互不共用连接。
设备列表:
- `▶` 主控(点过画面或点过该窗的那台)
- `✓` 已跟随
- 空格或控制条「跟随」切换
主控上的点击 / 滑动 / 按键按分辨率归一化后并行打到跟随组。注入器对 DOWN / UP / 点击 / 按键回 `OK` / `ERR`,状态栏例如 `同步 tap 3/3 成功`。失败会留下可重放动作,「重试失败」按原坐标再打到失败的那几台。已经是主控时再点画面不会刷设备列表。
### 排列
扣掉列表窗后的工作区:
| 模式 | 布局 |
| --- | --- |
| 同屏 | 网格铺满 |
| 环绕 | 主控大,其余围在一侧 |
| 焦点 | 主控几乎全屏,其余窄条 |
| 层叠 | 错开叠放 |
卫星窗自动降到约 1/3 分辨率、2 Mbps、12 fps 上屏,UI 泵 80ms 一轮;主控仍约 16ms。`adb run` 按 serial 分锁,批量 ls / push 不会把所有设备排成一队。
### 批量
有跟随时只打跟随组,否则全部已开窗口:主页 / 返回 / 唤醒 / 截图。06 / REPOSITORY MAP
目录证据导览
这里列出快照中的前 35 个索引文件中的代表路径,帮助你快速定位源码、文档、测试与资源。
.gitignoreLICENSEREADME.mdfiles_spec.pyfiles_view.pyfleet.pyframe_submit.pyinput_spec.pyios/__init__.pyios/_jb_worker.pyios/client.pyios/files_view.pyios/jb_app.jsios/jb_hid.jsios/jb_input.pyios/jb_touch.jsios/log.pyios/log_view.pyios/spec.pyios/stream.pyios/wake.pyios/window.pylaunch.pyliveenc/LiveEnc.javaliveenc/LiveInput.javaliveenc/liveenc.dexlogcat_view.pyobserver.pystart.cmdstream_spec.pytests/__init__.pytests/test_fleet.pytests/test_ios.pytests/test_observer.pywm_layout.py
07 / SOURCE NOTES
README 原文摘录
保留原始说明便于复核。中文研究结论以当前快照为依据,后续变化请以 GitHub 仓库为准。
ob-server
Frida 共存的 ADB 观察器:给已经连上的安卓设备开独立镜像窗,看屏幕、点按、跟日志、传文件。
不装 scrcpy、不改 adb forward / reverse,只复用本机已有 adb server(127.0.0.1:5037)。Frida 占用的 28917 / 28918 / 29999 不会被碰。
Android 这条链路是稳定版。iOS 集控在独立包 ios/ 里,不改 LiveEnc / LiveInput / ADB 禁令。
[[图片] License: MIT](LICENSE) [[图片] Python 3.9+](https://www.python.org/) [[图片] Platform](#启动)
能做什么
| 画面 | 默认 LiveEnc 低延迟 H.264(MediaCodec 短 GOP / --low-latency,adb exec-out stdout)。失败回退系统 screenrecord,再失败才 PNG 截图(约 1 fps) |
| 远控 | 常驻 LiveInput(InputManager.injectInputEvent)。单击是原子 tap,拖拽跟手 MOVE。失败才退回 adb shell input |
| 多机 | 不限台数。主控操作按分辨率归一化后并行打到跟随组;卫星窗自动降码率 |
| 日志 | Android Studio 式 logcat:环形缓冲、批量刷屏。可只看 Frida / gum 关键字 |
| 文件 | 浏览 /storage/emulated/0,上传 / 下载 / 复制 / 重命名 / 建目录。跟随组可批量 |
刻意不做的事:
adb kill-server/start-serveradb forward/reverse(含增删已有隧道)adb root/reboot/tcpip/install/uninstall- 往手机 push scrcpy / minicap(可以放项目自有
liveenc.dex到/data/local/tmp/.lenc.dex)
画面怎么来
设备 MediaCodec (LiveEnc.dex)
│ Annex-B H.264
▼
adb exec-out stdout
│
▼
本机 PyAV 解码 + 缩放到窗口 ← 工作线程
│
▼
Tk canvas 只替换已有图 ← UI 线程不 delete("all")、不做整帧 BILINEAR不用 scrcpy:scrcpy 快是因为专用低延迟编码 + 自己的 socket(通常还要 adb reverse / forward)。这里故意不推 scrcpy-server、不改隧道,以免打断正在跑的 Frida。
卡顿优先查编码 GOP / 本机绘制 / 日志抢 Tk 主线程,不要先换 adb tcpip 或怪 USB 带宽。H.264 只有数 Mbps,USB 2.0 够用。
环境
- Windows(剪贴板截图、无边框窗体、从终端 Job 拆出 GUI 目前按 Windows 做)
- Python 3.9+,tkinter
adb在 PATH 里,设备已经连上- 依赖:
pip install pillow av
pip install pymobiledevice3没有 av(PyAV)时 Android 自动走 PNG 截图,画面会很慢。运行期间不要执行 adb kill-server。
iOS 需要本机 usbmux(Windows 上随 iTunes / Apple Device 支持安装)以及 pymobiledevice3(可选 tidevice)。没装时设备列表里不会出现 iPhone,Android 不受影响。pymobiledevice3 是 GPL-3.0,按可选依赖引入,不随本仓库再分发。
越狱机(如 checkra1n iOS 13)触控要单独装一份 Frida 16,不要动全局 17.x:
python -m venv .tools/frida16
.tools/frida16/Scripts/python -m pip install frida==16.7.19手机上的 frida-server 必须和这份 16.x 大版本一致。
启动
双击 start.cmd,或:
python observer.py
python launch.pylaunch.py 会把窗口从当前终端 Job 里拆出去,关掉终端不会把 GUI 一起带走。start.cmd 优先用 pythonw,不挂控制台。
操作
手机窗口是无边框等比镜像(真实分辨率比例),类似 macOS 的 iPhone 镜像。
窗口分组:设备列表是独立一组;每台手机的画面窗 + 控制条是一组。新窗口会避开已有组,拖动松开后磁吸对齐。位置写入 observer.layout.json,下次启动还原。
画面上
| 动作 | 效果 |
|---|---|
| 单击 | 原子 tap:按下不立刻发 DOWN,松开时一次注入 DOWN+UP 12ms(避开 MIUI ~400ms 长按阈值) |
| 拖动 | 越过 14 画布像素才发 DOWN + MOVE…UP;MOVE 跟手、不等回执 |
| 右键 | 返回 |
| 中键 / 底栏横条 | 主页 |
| 滚轮 | 在指针位置上下滑动 |
| 右下角拖 | 拉伸窗体 |
| 顶部「拖动」高亮 / 黑边 | 移动整组 |
快捷键
| 键 | 效果 |
|---|---|
| Esc / BackSpace | 返回 |
| Home | 主页 |
| F5 | 立即刷新 |
| F8 / Ctrl+Shift+C | 截图进剪贴板(不写文件) |
| PgUp / PgDn | 音量 |
工具条
鼠标移到画面上,深色工具条会磁吸停在下方(空间不够则靠左 / 右)。「钉住」默认开着;取消后工具条在鼠标离开后收起。
- 常用键:返回 / 主页 / 最近 / 电源 / 音量 / 菜单 / 回车 / 唤醒 / 上滑解锁
- 立即刷新 / 截图 / 暂停画面(暂停只停 UI,编码仍在跑)
- 文字框 + 发送
- 跟随、置顶、H.264 ⇄ PNG
多设备集控
上限就是本机能列出的设备(adb devices + usbmux)。Android 每台独立 LiveEnc / LiveInput / logcat;iOS 每台独立截图 / HID / syslog。互不共用连接。
设备列表:
▶主控(点过画面或点过该窗的那台)✓已跟随- 空格或控制条「跟随」切换
主控上的点击 / 滑动 / 按键按分辨率归一化后并行打到跟随组。注入器对 DOWN / UP / 点击 / 按键回 OK / ERR,状态栏例如 同步 tap 3/3 成功。失败会留下可重放动作,「重试失败」按原坐标再打到失败的那几台。已经是主控时再点画面不会刷设备列表。
排列
扣掉列表窗后的工作区:
| 模式 | 布局 |
|---|---|
| 同屏 | 网格铺满 |
| 环绕 | 主控大,其余围在一侧 |
| 焦点 | 主控几乎全屏,其余窄条 |
| 层叠 | 错开叠放 |
卫星窗自动降到约 1/3 分辨率、2 Mbps、12 fps 上屏,UI 泵 80ms 一轮;主控仍约 16ms。adb run 按 serial 分锁,批量 ls / push 不会把所有设备排成一队。
批量
有跟随时只打跟随组,否则全部已开窗口:主页 / 返回 / 唤醒 / 截图。
批量截图 PNG 写到 files-inbox/ / .png。
文件
选中设备 →「文件」。浏览默认 /storage/emulated/0(MIUI 的 /sdcard 是符号链接,不带 -L 的 ls 只会列出链接本身——已内置跟随)。
- 列表:名称 / 大小 / 修改时间
- 多选后:上传、下载、删除、复制(自动生成不冲突的副本名)、重命名(
mv -T)、建目录 - 快捷跳转:SD、tmp;「收件箱」打开本地
files-inbox - 传输进度:
N/M
删除 / 建目录 / 重命名 / 复制只允许在 /sdcard/、/storage/emulated/、/data/local/tmp/ 之下,拒绝 /、/system、整卷 /sdcard。仍然拒绝 install / forward / tcpip。
日志
设备窗「日志」打开 Android Studio 式 logcat(环形缓冲、批量刷屏)。勾选 Frida 只看 frida / kxmwp / gum 等关键字。只清视图,不清设备 log 缓冲。
关掉日志窗口会 kill 设备上的 logcat 进程,那条 ADB 流停止;画面上的「暂停」只停 UI。
卡顿排查
- 确认本机装了 PyAV(
import av),否则会落到 PNG ~1 fps - 看状态栏是 LiveEnc、screenrecord 还是 PNG
- 关掉日志窗再比一帧间隔(logcat 会抢 Tk 主线程)
- 卫星窗本来就是 12 fps;主控才是交互档
- 不要用
adb tcpip「优化」——H.264 只有数 Mbps,USB 2.0 够用
测试
python -m unittest discover -s tests -v覆盖推流规格、ADB 禁令、原子 tap / 拖拽阈值、跟随 fan-out、窗口排列、文件路径约束,以及 iOS 规格(坐标 / 手势 / AFC 路径 / 客户端分发)。
目录
observer.py 主程序(设备列表 + 镜像窗)
launch.py 从终端 Job 拆出 GUI
start.cmd 双击启动
stream_spec.py LiveEnc / screenrecord 规格与 ADB 禁令
input_spec.py LiveInput 协议(D/M/U/T/K)
frame_submit.py 工作线程出图,UI 只换 canvas item
fleet.py 跟随组、坐标映射、fan-out
wm_layout.py 同屏 / 环绕 / 焦点 / 层叠
logcat_view.py logcat 窗
files_spec.py 远程路径与 ls/push/pull
files_view.py 文件窗
liveenc/ MediaCodec 编码器 + InputManager 注入器(.java / .dex)
ios/ iOS 独立实现(发现 / 截图 / 输入 / AFC / syslog)
tests/ unittestiOS 集控(独立实现)
代码在 ios/,不进 observer.py 的 Android 类。设备列表会把 usbmux 上的 iPhone 追加在 Android 后面;开窗、日志、文件、跟随 fan-out 按 kind=ios 分发。
| Android(稳定) | iOS(ios/) | |
|---|---|---|
| 发现 | adb devices | usbmux / lockdown |
| 画面 | LiveEnc H.264 → screenrecord → PNG | screenshotr(iOS 13 已在真机跑通,约 2 秒/帧);DVT 仅作后备 |
| 远控 | LiveInput | 越狱机:Frida 16 注入 SpringBoard IOHID(.tools/frida16,与手机 frida-server 16.7.19 对齐)。非越狱走 DVT/HID |
| 文件 | adb ls/push/pull | AFC 媒体分区;越狱有 AFC2 时走整机 /var/mobile/Media |
| 日志 | logcat | syslog / os_trace |
跟随组可以安卓机和 iPhone 混编,坐标仍按分辨率归一化。主页 / 返回在 iOS 上映射成底栏上滑 / 左缘滑动。
未在手机上点「信任」、未开开发者模式、或 iOS 17+ 没有 RSD 隧道时:列表能看到设备,画面和触控会在状态栏写明缺什么。不改 adb forward,也不占用 Frida 隧道。
下一步
iOS 画面还没接 QuickTime 低延迟流;HID 随 pymobiledevice3 版本会走不同类名,缺 API 时会明确报错而不是 silently no-op。
License
MIT © flynn


