ob-server

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

ob-server 项目封面或真实界面
Python主要技术栈
0GitHub Stars
1Forks
35索引文件
MIT License许可标记
2026-09-09最近更新

01 / PROJECT OVERVIEW

项目研究解读

Frida-safe Android 观测服务:低延迟画面、实时输入、多设备跟随、日志和文件能力。 本仓库以 Python 为主要技术栈,当前快照索引 35 个文件。报告依据README 与目录结构整理,重点呈现项目用途、工程结构和复用方式,不把宣传描述等同于验证结论。

adbandroidandroid-debug-bridgedebuggingfridah264logcatmulti-devicepythonremote-controlreverse-engineeringscreen-mirroringtkinterwindows

02 / CORE CAPABILITIES

值得关注的能力

  1. 01

    围绕“Frida-safe Android 观测服务:低延迟画面、实时输入、多设备跟随、日志和文件能力”提供公开实现或研究资料

  2. 02

    以 Python 为主,保留 35 个可检查仓库文件

  3. 03

    提供原始 GitHub 链接、目录导览和本地研究快照,便于复核与二次开发

03 / ENGINEERING

工程与仓库结构

仓库以 Python 为主要实现语言,研究快照包含 35 个文件、16 个主要顶层入口。已提供 README 作为使用与能力说明。 项目最近更新时间为 2026-09-09,许可标记为 MIT License。

01LICENSE

项目文件与实现资料

02README.md

项目文件与实现资料

03files_spec.py

项目文件与实现资料

04files_view.py

项目文件与实现资料

05fleet.py

项目文件与实现资料

06frame_submit.py

项目文件与实现资料

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 个索引文件中的代表路径,帮助你快速定位源码、文档、测试与资源。

  • .gitignore
  • LICENSE
  • README.md
  • files_spec.py
  • files_view.py
  • fleet.py
  • frame_submit.py
  • input_spec.py
  • ios/__init__.py
  • ios/_jb_worker.py
  • ios/client.py
  • ios/files_view.py
  • ios/jb_app.js
  • ios/jb_hid.js
  • ios/jb_input.py
  • ios/jb_touch.js
  • ios/log.py
  • ios/log_view.py
  • ios/spec.py
  • ios/stream.py
  • ios/wake.py
  • ios/window.py
  • launch.py
  • liveenc/LiveEnc.java
  • liveenc/LiveInput.java
  • liveenc/liveenc.dex
  • logcat_view.py
  • observer.py
  • start.cmd
  • stream_spec.py
  • tests/__init__.py
  • tests/test_fleet.py
  • tests/test_ios.py
  • tests/test_observer.py
  • wm_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-server
  • adb 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.py

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 不会把所有设备排成一队。

批量

有跟随时只打跟随组,否则全部已开窗口:主页 / 返回 / 唤醒 / 截图。

批量截图 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。

卡顿排查

  1. 确认本机装了 PyAV(import av),否则会落到 PNG ~1 fps
  2. 看状态栏是 LiveEnc、screenrecord 还是 PNG
  3. 关掉日志窗再比一帧间隔(logcat 会抢 Tk 主线程)
  4. 卫星窗本来就是 12 fps;主控才是交互档
  5. 不要用 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/               unittest

iOS 集控(独立实现)

代码在 ios/,不进 observer.py 的 Android 类。设备列表会把 usbmux 上的 iPhone 追加在 Android 后面;开窗、日志、文件、跟随 fan-out 按 kind=ios 分发。

Android(稳定)iOS(ios/)
发现adb devicesusbmux / lockdown
画面LiveEnc H.264 → screenrecord → PNGscreenshotr(iOS 13 已在真机跑通,约 2 秒/帧);DVT 仅作后备
远控LiveInput越狱机:Frida 16 注入 SpringBoard IOHID(.tools/frida16,与手机 frida-server 16.7.19 对齐)。非越狱走 DVT/HID
文件adb ls/push/pullAFC 媒体分区;越狱有 AFC2 时走整机 /var/mobile/Media
日志logcatsyslog / os_trace

跟随组可以安卓机和 iPhone 混编,坐标仍按分辨率归一化。主页 / 返回在 iOS 上映射成底栏上滑 / 左缘滑动。

未在手机上点「信任」、未开开发者模式、或 iOS 17+ 没有 RSD 隧道时:列表能看到设备,画面和触控会在状态栏写明缺什么。不改 adb forward,也不占用 Frida 隧道。

下一步

iOS 画面还没接 QuickTime 低延迟流;HID 随 pymobiledevice3 版本会走不同类名,缺 API 时会明确报错而不是 silently no-op。

License

MIT © flynn