adbproxy 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- adbproxy-0.1.0/LICENSE +21 -0
- adbproxy-0.1.0/PKG-INFO +254 -0
- adbproxy-0.1.0/README.md +233 -0
- adbproxy-0.1.0/pyproject.toml +37 -0
- adbproxy-0.1.0/setup.cfg +4 -0
- adbproxy-0.1.0/src/adbproxy/__init__.py +2 -0
- adbproxy-0.1.0/src/adbproxy/__main__.py +5 -0
- adbproxy-0.1.0/src/adbproxy/cli/__init__.py +1 -0
- adbproxy-0.1.0/src/adbproxy/cli/device.py +13 -0
- adbproxy-0.1.0/src/adbproxy/cli/main.py +60 -0
- adbproxy-0.1.0/src/adbproxy/cli/server.py +13 -0
- adbproxy-0.1.0/src/adbproxy/config.py +39 -0
- adbproxy-0.1.0/src/adbproxy/device/__init__.py +1 -0
- adbproxy-0.1.0/src/adbproxy/device/app.py +532 -0
- adbproxy-0.1.0/src/adbproxy/device/backend.py +242 -0
- adbproxy-0.1.0/src/adbproxy/device/banner.py +33 -0
- adbproxy-0.1.0/src/adbproxy/device/connection.py +505 -0
- adbproxy-0.1.0/src/adbproxy/device/session.py +304 -0
- adbproxy-0.1.0/src/adbproxy/device/stream_table.py +125 -0
- adbproxy-0.1.0/src/adbproxy/observers/__init__.py +1 -0
- adbproxy-0.1.0/src/adbproxy/observers/events.py +19 -0
- adbproxy-0.1.0/src/adbproxy/observers/install.py +126 -0
- adbproxy-0.1.0/src/adbproxy/observers/shell.py +371 -0
- adbproxy-0.1.0/src/adbproxy/observers/stream.py +94 -0
- adbproxy-0.1.0/src/adbproxy/observers/sync.py +550 -0
- adbproxy-0.1.0/src/adbproxy/protocols/__init__.py +1 -0
- adbproxy-0.1.0/src/adbproxy/protocols/adb.py +66 -0
- adbproxy-0.1.0/src/adbproxy/protocols/payload/__init__.py +17 -0
- adbproxy-0.1.0/src/adbproxy/protocols/payload/install.py +44 -0
- adbproxy-0.1.0/src/adbproxy/protocols/payload/shell_v2.py +28 -0
- adbproxy-0.1.0/src/adbproxy/protocols/payload/sync.py +180 -0
- adbproxy-0.1.0/src/adbproxy/protocols/smart_socket/__init__.py +33 -0
- adbproxy-0.1.0/src/adbproxy/protocols/smart_socket/classifier.py +78 -0
- adbproxy-0.1.0/src/adbproxy/protocols/smart_socket/conversation.py +335 -0
- adbproxy-0.1.0/src/adbproxy/protocols/smart_socket/handshake.py +75 -0
- adbproxy-0.1.0/src/adbproxy/protocols/smart_socket/wire.py +82 -0
- adbproxy-0.1.0/src/adbproxy/protocols/transport/__init__.py +52 -0
- adbproxy-0.1.0/src/adbproxy/protocols/transport/codec.py +90 -0
- adbproxy-0.1.0/src/adbproxy/protocols/transport/constants.py +21 -0
- adbproxy-0.1.0/src/adbproxy/protocols/transport/errors.py +5 -0
- adbproxy-0.1.0/src/adbproxy/runtime/__init__.py +1 -0
- adbproxy-0.1.0/src/adbproxy/runtime/adb_process.py +195 -0
- adbproxy-0.1.0/src/adbproxy/runtime/capture.py +41 -0
- adbproxy-0.1.0/src/adbproxy/runtime/logging.py +113 -0
- adbproxy-0.1.0/src/adbproxy/runtime/sockets.py +14 -0
- adbproxy-0.1.0/src/adbproxy/server/__init__.py +1 -0
- adbproxy-0.1.0/src/adbproxy/server/app.py +221 -0
- adbproxy-0.1.0/src/adbproxy/server/connection.py +378 -0
- adbproxy-0.1.0/src/adbproxy.egg-info/PKG-INFO +254 -0
- adbproxy-0.1.0/src/adbproxy.egg-info/SOURCES.txt +56 -0
- adbproxy-0.1.0/src/adbproxy.egg-info/dependency_links.txt +1 -0
- adbproxy-0.1.0/src/adbproxy.egg-info/entry_points.txt +4 -0
- adbproxy-0.1.0/src/adbproxy.egg-info/requires.txt +10 -0
- adbproxy-0.1.0/src/adbproxy.egg-info/top_level.txt +1 -0
- adbproxy-0.1.0/tests/test_cli_main.py +86 -0
- adbproxy-0.1.0/tests/test_dynamic_commands.py +582 -0
- adbproxy-0.1.0/tests/test_imports.py +97 -0
- adbproxy-0.1.0/tests/test_protocols.py +1522 -0
adbproxy-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Forgo7ten
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
adbproxy-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: adbproxy
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: ADB smart-socket and device transport proxies
|
|
5
|
+
Author: Forgo7ten
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Forgo7ten/adbproxy
|
|
8
|
+
Project-URL: Repository, https://github.com/Forgo7ten/adbproxy
|
|
9
|
+
Project-URL: Issues, https://github.com/Forgo7ten/adbproxy/issues
|
|
10
|
+
Requires-Python: >=3.10
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Requires-Dist: zstandard>=0.25.0
|
|
14
|
+
Provides-Extra: lz4
|
|
15
|
+
Requires-Dist: lz4>=4.3.0; extra == "lz4"
|
|
16
|
+
Provides-Extra: brotli
|
|
17
|
+
Requires-Dist: brotli>=1.1.0; extra == "brotli"
|
|
18
|
+
Provides-Extra: decompress
|
|
19
|
+
Requires-Dist: adbproxy[brotli,lz4]; extra == "decompress"
|
|
20
|
+
Dynamic: license-file
|
|
21
|
+
|
|
22
|
+
# adbproxy
|
|
23
|
+
|
|
24
|
+
在 ADB client 与 server / 设备之间插入透明代理,解析并记录 ADB 协议流量,同时保持原始字节原样转发。
|
|
25
|
+
|
|
26
|
+
适用于调试 adb 命令、观察 shell / sync / install 等协议交互、抓取 push/pull 文件内容。
|
|
27
|
+
|
|
28
|
+
## 功能
|
|
29
|
+
|
|
30
|
+
- **server-proxy**:MITM 本机 `adb client ↔ adb server` 的 smart-socket 链路(默认监听 `5037`,真实 server 挪到 `5038`)
|
|
31
|
+
- **device-proxy**:模拟网络 adbd,接受 transport 协议连接,再经系统 adb server 转发到真实设备
|
|
32
|
+
- 解析并记录 shell、sync、install、stream 等协议事件
|
|
33
|
+
- 可选落盘 sync / install 文件内容,以及 `--debug` 原始 hex
|
|
34
|
+
- 观察 / 解码 / 抓包失败时 fail-open,不中断透明转发
|
|
35
|
+
|
|
36
|
+
## 架构
|
|
37
|
+
|
|
38
|
+
```mermaid
|
|
39
|
+
flowchart LR
|
|
40
|
+
Client[adb client]
|
|
41
|
+
SP[server-proxy :5037]
|
|
42
|
+
Server[adb server :5038]
|
|
43
|
+
Dev[真实设备]
|
|
44
|
+
|
|
45
|
+
Client -->|smart socket| SP
|
|
46
|
+
SP -->|smart socket| Server
|
|
47
|
+
Server --> Dev
|
|
48
|
+
|
|
49
|
+
Client2[adb client]
|
|
50
|
+
ServerFront[adb server :5037]
|
|
51
|
+
DP[device-proxy :5566]
|
|
52
|
+
ServerBack[adb server :5037]
|
|
53
|
+
Dev2[真实设备]
|
|
54
|
+
|
|
55
|
+
Client2 -->|smart socket| ServerFront
|
|
56
|
+
ServerFront -->|transport| DP
|
|
57
|
+
DP -->|smart socket| ServerBack
|
|
58
|
+
ServerBack --> Dev2
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## 环境要求
|
|
62
|
+
|
|
63
|
+
- Python ≥ 3.10
|
|
64
|
+
- [uv](https://docs.astral.sh/uv/)
|
|
65
|
+
- 系统 `adb`(Android platform-tools)
|
|
66
|
+
|
|
67
|
+
## 安装
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
git clone <repo-url>
|
|
71
|
+
cd adbproxy # 或你的本地目录名
|
|
72
|
+
uv sync
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
也可从 PyPI:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
pip install adbproxy
|
|
79
|
+
# 可选:sync 解压依赖
|
|
80
|
+
pip install "adbproxy[decompress]"
|
|
81
|
+
|
|
82
|
+
# 临时运行
|
|
83
|
+
uvx adbproxy server --help
|
|
84
|
+
uvx adbproxy device --help
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
`uv sync` 会安装依赖,并根据 `pyproject.toml` 的 `[project.scripts]` 注册命令行入口:
|
|
88
|
+
|
|
89
|
+
| 命令 | 对应模块 | 作用 |
|
|
90
|
+
|------|----------|------|
|
|
91
|
+
| `adbproxy` | `adbproxy.cli.main:main` | **推荐**统一入口:`server` / `device` 子命令 |
|
|
92
|
+
| `adb-server-proxy` | `adbproxy.cli.server:main` | 兼容旧入口(等同 `adbproxy server`) |
|
|
93
|
+
| `adb-device-proxy` | `adbproxy.cli.device:main` | 兼容旧入口(等同 `adbproxy device`) |
|
|
94
|
+
|
|
95
|
+
推荐启动方式:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# 统一入口(推荐)
|
|
99
|
+
uv run adbproxy server --help
|
|
100
|
+
uv run adbproxy device --help
|
|
101
|
+
uv run python -m adbproxy server --help
|
|
102
|
+
uv run python -m adbproxy device --help
|
|
103
|
+
|
|
104
|
+
# 兼容旧 console script / 模块路径
|
|
105
|
+
uv run adb-server-proxy --help
|
|
106
|
+
uv run adb-device-proxy --help
|
|
107
|
+
uv run python -m adbproxy.cli.server --help
|
|
108
|
+
uv run python -m adbproxy.cli.device --help
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
下文示例统一使用 `adbproxy server` / `adbproxy device`。
|
|
112
|
+
|
|
113
|
+
## 使用
|
|
114
|
+
|
|
115
|
+
### 1. server-proxy(MITM 本机 5037)
|
|
116
|
+
|
|
117
|
+
启动前确认本机 `5038` 未被占用。代理会接管默认 `5037`,把真实 adb server 挪到 `5038`;退出时按所有权恢复。
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
uv run adbproxy server
|
|
121
|
+
# 等价:
|
|
122
|
+
# uv run python -m adbproxy server
|
|
123
|
+
# uv run adb-server-proxy
|
|
124
|
+
|
|
125
|
+
# 可选参数:
|
|
126
|
+
# --debug 将每段 recv 的原始 hex 落盘
|
|
127
|
+
# --no-capture 不落盘 sync/install 文件,仅打印摘要
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
另开终端正常使用 adb(默认走 5037,即经过代理):
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
adb devices -l
|
|
134
|
+
adb shell echo hello
|
|
135
|
+
adb push local.apk /data/local/tmp/
|
|
136
|
+
adb install local.apk
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### 2. device-proxy(模拟网络 adbd)
|
|
140
|
+
|
|
141
|
+
默认监听 `5566`,后端复用系统 `5037` adb server,把请求转发到指定真实设备。
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
uv run adbproxy device \
|
|
145
|
+
--listen 5566 \
|
|
146
|
+
--target serial:<设备序列号>
|
|
147
|
+
|
|
148
|
+
# 等价:
|
|
149
|
+
# uv run python -m adbproxy device \
|
|
150
|
+
# --listen 5566 \
|
|
151
|
+
# --target serial:<设备序列号>
|
|
152
|
+
# uv run adb-device-proxy \
|
|
153
|
+
# --listen 5566 \
|
|
154
|
+
# --target serial:<设备序列号>
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
`--target` 支持:
|
|
158
|
+
|
|
159
|
+
| 值 | 含义 |
|
|
160
|
+
|----|------|
|
|
161
|
+
| `usb` | 自动选择首个 USB 且状态为 `device` 的设备(默认) |
|
|
162
|
+
| `serial:<s>` | 指定序列号 |
|
|
163
|
+
| `net:<ip>:<port>` | 先 `adb connect` 到该网络设备 |
|
|
164
|
+
|
|
165
|
+
常用参数:
|
|
166
|
+
|
|
167
|
+
```text
|
|
168
|
+
--listen PORT 监听端口,默认 5566
|
|
169
|
+
--adb-server-port PORT 后端 adb server 端口,默认 5037
|
|
170
|
+
--debug 原始 hex 落盘
|
|
171
|
+
--no-capture 禁用 sync/install 文件落盘
|
|
172
|
+
--banner-type TYPE CNXN banner 前缀,默认 device
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
另开终端连接并操作:
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
adb connect 127.0.0.1:5566
|
|
179
|
+
adb -s 127.0.0.1:5566 get-state
|
|
180
|
+
adb -s 127.0.0.1:5566 shell echo hello
|
|
181
|
+
adb -s 127.0.0.1:5566 push local.apk /data/local/tmp/
|
|
182
|
+
adb disconnect 127.0.0.1:5566
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## 输出目录
|
|
186
|
+
|
|
187
|
+
运行时在项目根目录生成(可用 `ADB_PROXY_OUT_DIR` 覆盖):
|
|
188
|
+
|
|
189
|
+
| 路径 | 内容 |
|
|
190
|
+
|------|------|
|
|
191
|
+
| `out/logs/` | 事件日志;加 `--debug` 时另有 debug hex 日志 |
|
|
192
|
+
| `out/files/` | sync push/pull、install 流捕获(未加 `--no-capture` 时) |
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
export ADB_PROXY_OUT_DIR=/tmp/adbproxy-out
|
|
196
|
+
# 写入 /tmp/adbproxy-out/logs 与 /tmp/adbproxy-out/files
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## 测试
|
|
200
|
+
|
|
201
|
+
### 准备
|
|
202
|
+
|
|
203
|
+
真机动态矩阵(push / pull / install)依赖测试 APK。仓库不附带该文件,运行前请自行放置:
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
# 任意可安装的 APK 即可
|
|
207
|
+
cp /path/to/your.apk tests/app.apk
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
`tests/app.apk` 已在 `tests/.gitignore` 中忽略,不会被提交。
|
|
211
|
+
|
|
212
|
+
无设备的单元 / 静态测试不需要该文件。
|
|
213
|
+
|
|
214
|
+
### 环境变量
|
|
215
|
+
|
|
216
|
+
| 变量 | 说明 |
|
|
217
|
+
|------|------|
|
|
218
|
+
| `ADB_PROXY_REAL_DEVICE=1` | 启用真机动态用例;未设置时相关用例自动 skip |
|
|
219
|
+
| `ADB_SERIAL` | 指定真机序列号;省略时取首个 USB 且状态为 `device` 的设备 |
|
|
220
|
+
| `ADB_PROXY_OUT_DIR` | 覆盖运行产物根目录(日志 / 抓包),默认项目根 `out/` |
|
|
221
|
+
|
|
222
|
+
### 全部测试
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
# 无设备:单元 + 静态;动态用例自动 skip
|
|
226
|
+
uv run python -B -m unittest discover -s tests -v
|
|
227
|
+
|
|
228
|
+
# 含真实设备动态矩阵(需先放置 tests/app.apk)
|
|
229
|
+
export ADB_PROXY_REAL_DEVICE=1
|
|
230
|
+
export ADB_SERIAL=<可选,默认取首个 USB device>
|
|
231
|
+
uv run python -B -m unittest discover -s tests -v
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### 按文件运行
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
# 包布局与导入
|
|
238
|
+
uv run python -B -m unittest tests.test_imports -v
|
|
239
|
+
|
|
240
|
+
# 统一 CLI 分发
|
|
241
|
+
uv run python -B -m unittest tests.test_cli_main -v
|
|
242
|
+
|
|
243
|
+
# 协议 / lease / 观察逻辑单元测试
|
|
244
|
+
uv run python -B -m unittest tests.test_protocols -v
|
|
245
|
+
|
|
246
|
+
# 真机动态矩阵(server-proxy + device-proxy;需 tests/app.apk)
|
|
247
|
+
export ADB_PROXY_REAL_DEVICE=1
|
|
248
|
+
export ADB_SERIAL=<可选>
|
|
249
|
+
uv run python -B -m unittest tests.test_dynamic_commands -v
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
## 说明
|
|
253
|
+
|
|
254
|
+
- 代理是透明的:解析失败不会改写或阻断转发字节
|
adbproxy-0.1.0/README.md
ADDED
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
# adbproxy
|
|
2
|
+
|
|
3
|
+
在 ADB client 与 server / 设备之间插入透明代理,解析并记录 ADB 协议流量,同时保持原始字节原样转发。
|
|
4
|
+
|
|
5
|
+
适用于调试 adb 命令、观察 shell / sync / install 等协议交互、抓取 push/pull 文件内容。
|
|
6
|
+
|
|
7
|
+
## 功能
|
|
8
|
+
|
|
9
|
+
- **server-proxy**:MITM 本机 `adb client ↔ adb server` 的 smart-socket 链路(默认监听 `5037`,真实 server 挪到 `5038`)
|
|
10
|
+
- **device-proxy**:模拟网络 adbd,接受 transport 协议连接,再经系统 adb server 转发到真实设备
|
|
11
|
+
- 解析并记录 shell、sync、install、stream 等协议事件
|
|
12
|
+
- 可选落盘 sync / install 文件内容,以及 `--debug` 原始 hex
|
|
13
|
+
- 观察 / 解码 / 抓包失败时 fail-open,不中断透明转发
|
|
14
|
+
|
|
15
|
+
## 架构
|
|
16
|
+
|
|
17
|
+
```mermaid
|
|
18
|
+
flowchart LR
|
|
19
|
+
Client[adb client]
|
|
20
|
+
SP[server-proxy :5037]
|
|
21
|
+
Server[adb server :5038]
|
|
22
|
+
Dev[真实设备]
|
|
23
|
+
|
|
24
|
+
Client -->|smart socket| SP
|
|
25
|
+
SP -->|smart socket| Server
|
|
26
|
+
Server --> Dev
|
|
27
|
+
|
|
28
|
+
Client2[adb client]
|
|
29
|
+
ServerFront[adb server :5037]
|
|
30
|
+
DP[device-proxy :5566]
|
|
31
|
+
ServerBack[adb server :5037]
|
|
32
|
+
Dev2[真实设备]
|
|
33
|
+
|
|
34
|
+
Client2 -->|smart socket| ServerFront
|
|
35
|
+
ServerFront -->|transport| DP
|
|
36
|
+
DP -->|smart socket| ServerBack
|
|
37
|
+
ServerBack --> Dev2
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## 环境要求
|
|
41
|
+
|
|
42
|
+
- Python ≥ 3.10
|
|
43
|
+
- [uv](https://docs.astral.sh/uv/)
|
|
44
|
+
- 系统 `adb`(Android platform-tools)
|
|
45
|
+
|
|
46
|
+
## 安装
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
git clone <repo-url>
|
|
50
|
+
cd adbproxy # 或你的本地目录名
|
|
51
|
+
uv sync
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
也可从 PyPI:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
pip install adbproxy
|
|
58
|
+
# 可选:sync 解压依赖
|
|
59
|
+
pip install "adbproxy[decompress]"
|
|
60
|
+
|
|
61
|
+
# 临时运行
|
|
62
|
+
uvx adbproxy server --help
|
|
63
|
+
uvx adbproxy device --help
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
`uv sync` 会安装依赖,并根据 `pyproject.toml` 的 `[project.scripts]` 注册命令行入口:
|
|
67
|
+
|
|
68
|
+
| 命令 | 对应模块 | 作用 |
|
|
69
|
+
|------|----------|------|
|
|
70
|
+
| `adbproxy` | `adbproxy.cli.main:main` | **推荐**统一入口:`server` / `device` 子命令 |
|
|
71
|
+
| `adb-server-proxy` | `adbproxy.cli.server:main` | 兼容旧入口(等同 `adbproxy server`) |
|
|
72
|
+
| `adb-device-proxy` | `adbproxy.cli.device:main` | 兼容旧入口(等同 `adbproxy device`) |
|
|
73
|
+
|
|
74
|
+
推荐启动方式:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
# 统一入口(推荐)
|
|
78
|
+
uv run adbproxy server --help
|
|
79
|
+
uv run adbproxy device --help
|
|
80
|
+
uv run python -m adbproxy server --help
|
|
81
|
+
uv run python -m adbproxy device --help
|
|
82
|
+
|
|
83
|
+
# 兼容旧 console script / 模块路径
|
|
84
|
+
uv run adb-server-proxy --help
|
|
85
|
+
uv run adb-device-proxy --help
|
|
86
|
+
uv run python -m adbproxy.cli.server --help
|
|
87
|
+
uv run python -m adbproxy.cli.device --help
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
下文示例统一使用 `adbproxy server` / `adbproxy device`。
|
|
91
|
+
|
|
92
|
+
## 使用
|
|
93
|
+
|
|
94
|
+
### 1. server-proxy(MITM 本机 5037)
|
|
95
|
+
|
|
96
|
+
启动前确认本机 `5038` 未被占用。代理会接管默认 `5037`,把真实 adb server 挪到 `5038`;退出时按所有权恢复。
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
uv run adbproxy server
|
|
100
|
+
# 等价:
|
|
101
|
+
# uv run python -m adbproxy server
|
|
102
|
+
# uv run adb-server-proxy
|
|
103
|
+
|
|
104
|
+
# 可选参数:
|
|
105
|
+
# --debug 将每段 recv 的原始 hex 落盘
|
|
106
|
+
# --no-capture 不落盘 sync/install 文件,仅打印摘要
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
另开终端正常使用 adb(默认走 5037,即经过代理):
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
adb devices -l
|
|
113
|
+
adb shell echo hello
|
|
114
|
+
adb push local.apk /data/local/tmp/
|
|
115
|
+
adb install local.apk
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### 2. device-proxy(模拟网络 adbd)
|
|
119
|
+
|
|
120
|
+
默认监听 `5566`,后端复用系统 `5037` adb server,把请求转发到指定真实设备。
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
uv run adbproxy device \
|
|
124
|
+
--listen 5566 \
|
|
125
|
+
--target serial:<设备序列号>
|
|
126
|
+
|
|
127
|
+
# 等价:
|
|
128
|
+
# uv run python -m adbproxy device \
|
|
129
|
+
# --listen 5566 \
|
|
130
|
+
# --target serial:<设备序列号>
|
|
131
|
+
# uv run adb-device-proxy \
|
|
132
|
+
# --listen 5566 \
|
|
133
|
+
# --target serial:<设备序列号>
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
`--target` 支持:
|
|
137
|
+
|
|
138
|
+
| 值 | 含义 |
|
|
139
|
+
|----|------|
|
|
140
|
+
| `usb` | 自动选择首个 USB 且状态为 `device` 的设备(默认) |
|
|
141
|
+
| `serial:<s>` | 指定序列号 |
|
|
142
|
+
| `net:<ip>:<port>` | 先 `adb connect` 到该网络设备 |
|
|
143
|
+
|
|
144
|
+
常用参数:
|
|
145
|
+
|
|
146
|
+
```text
|
|
147
|
+
--listen PORT 监听端口,默认 5566
|
|
148
|
+
--adb-server-port PORT 后端 adb server 端口,默认 5037
|
|
149
|
+
--debug 原始 hex 落盘
|
|
150
|
+
--no-capture 禁用 sync/install 文件落盘
|
|
151
|
+
--banner-type TYPE CNXN banner 前缀,默认 device
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
另开终端连接并操作:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
adb connect 127.0.0.1:5566
|
|
158
|
+
adb -s 127.0.0.1:5566 get-state
|
|
159
|
+
adb -s 127.0.0.1:5566 shell echo hello
|
|
160
|
+
adb -s 127.0.0.1:5566 push local.apk /data/local/tmp/
|
|
161
|
+
adb disconnect 127.0.0.1:5566
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## 输出目录
|
|
165
|
+
|
|
166
|
+
运行时在项目根目录生成(可用 `ADB_PROXY_OUT_DIR` 覆盖):
|
|
167
|
+
|
|
168
|
+
| 路径 | 内容 |
|
|
169
|
+
|------|------|
|
|
170
|
+
| `out/logs/` | 事件日志;加 `--debug` 时另有 debug hex 日志 |
|
|
171
|
+
| `out/files/` | sync push/pull、install 流捕获(未加 `--no-capture` 时) |
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
export ADB_PROXY_OUT_DIR=/tmp/adbproxy-out
|
|
175
|
+
# 写入 /tmp/adbproxy-out/logs 与 /tmp/adbproxy-out/files
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## 测试
|
|
179
|
+
|
|
180
|
+
### 准备
|
|
181
|
+
|
|
182
|
+
真机动态矩阵(push / pull / install)依赖测试 APK。仓库不附带该文件,运行前请自行放置:
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
# 任意可安装的 APK 即可
|
|
186
|
+
cp /path/to/your.apk tests/app.apk
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
`tests/app.apk` 已在 `tests/.gitignore` 中忽略,不会被提交。
|
|
190
|
+
|
|
191
|
+
无设备的单元 / 静态测试不需要该文件。
|
|
192
|
+
|
|
193
|
+
### 环境变量
|
|
194
|
+
|
|
195
|
+
| 变量 | 说明 |
|
|
196
|
+
|------|------|
|
|
197
|
+
| `ADB_PROXY_REAL_DEVICE=1` | 启用真机动态用例;未设置时相关用例自动 skip |
|
|
198
|
+
| `ADB_SERIAL` | 指定真机序列号;省略时取首个 USB 且状态为 `device` 的设备 |
|
|
199
|
+
| `ADB_PROXY_OUT_DIR` | 覆盖运行产物根目录(日志 / 抓包),默认项目根 `out/` |
|
|
200
|
+
|
|
201
|
+
### 全部测试
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
# 无设备:单元 + 静态;动态用例自动 skip
|
|
205
|
+
uv run python -B -m unittest discover -s tests -v
|
|
206
|
+
|
|
207
|
+
# 含真实设备动态矩阵(需先放置 tests/app.apk)
|
|
208
|
+
export ADB_PROXY_REAL_DEVICE=1
|
|
209
|
+
export ADB_SERIAL=<可选,默认取首个 USB device>
|
|
210
|
+
uv run python -B -m unittest discover -s tests -v
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### 按文件运行
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
# 包布局与导入
|
|
217
|
+
uv run python -B -m unittest tests.test_imports -v
|
|
218
|
+
|
|
219
|
+
# 统一 CLI 分发
|
|
220
|
+
uv run python -B -m unittest tests.test_cli_main -v
|
|
221
|
+
|
|
222
|
+
# 协议 / lease / 观察逻辑单元测试
|
|
223
|
+
uv run python -B -m unittest tests.test_protocols -v
|
|
224
|
+
|
|
225
|
+
# 真机动态矩阵(server-proxy + device-proxy;需 tests/app.apk)
|
|
226
|
+
export ADB_PROXY_REAL_DEVICE=1
|
|
227
|
+
export ADB_SERIAL=<可选>
|
|
228
|
+
uv run python -B -m unittest tests.test_dynamic_commands -v
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## 说明
|
|
232
|
+
|
|
233
|
+
- 代理是透明的:解析失败不会改写或阻断转发字节
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "adbproxy"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "ADB smart-socket and device transport proxies"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
authors = [{ name = "Forgo7ten" }]
|
|
13
|
+
dependencies = [
|
|
14
|
+
"zstandard>=0.25.0",
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
[project.urls]
|
|
18
|
+
Homepage = "https://github.com/Forgo7ten/adbproxy"
|
|
19
|
+
Repository = "https://github.com/Forgo7ten/adbproxy"
|
|
20
|
+
Issues = "https://github.com/Forgo7ten/adbproxy/issues"
|
|
21
|
+
|
|
22
|
+
[project.optional-dependencies]
|
|
23
|
+
# sync push 可选解压:缺失时 observers/sync 降级为原始压缩字节捕获
|
|
24
|
+
lz4 = ["lz4>=4.3.0"]
|
|
25
|
+
brotli = ["brotli>=1.1.0"]
|
|
26
|
+
decompress = ["adbproxy[lz4,brotli]"]
|
|
27
|
+
|
|
28
|
+
[project.scripts]
|
|
29
|
+
adbproxy = "adbproxy.cli.main:main"
|
|
30
|
+
adb-server-proxy = "adbproxy.cli.server:main"
|
|
31
|
+
adb-device-proxy = "adbproxy.cli.device:main"
|
|
32
|
+
|
|
33
|
+
[tool.setuptools]
|
|
34
|
+
package-dir = {"" = "src"}
|
|
35
|
+
|
|
36
|
+
[tool.setuptools.packages.find]
|
|
37
|
+
where = ["src"]
|
adbproxy-0.1.0/setup.cfg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""代理程序命令行入口(统一 adbproxy 与兼容旧脚本)。"""
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"""统一 CLI:adbproxy server | device。
|
|
2
|
+
|
|
3
|
+
不修改现有 cli/server.py、cli/device.py;通过临时改写 sys.argv
|
|
4
|
+
再调用旧入口,保证子命令参数与直接运行旧脚本一致。
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import sys
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
_TOP_HELP = """\
|
|
13
|
+
usage: adbproxy {server,device} ...
|
|
14
|
+
|
|
15
|
+
子命令:
|
|
16
|
+
server client↔adb server smart-socket MITM(原 adb-server-proxy)
|
|
17
|
+
device 模拟网络 adbd / transport 转发(原 adb-device-proxy)
|
|
18
|
+
|
|
19
|
+
示例:
|
|
20
|
+
adbproxy server --help
|
|
21
|
+
adbproxy device --listen 5566 --target usb
|
|
22
|
+
python -m adbproxy server --debug
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def main(argv=None):
|
|
27
|
+
argv = list(sys.argv[1:] if argv is None else argv)
|
|
28
|
+
|
|
29
|
+
if not argv:
|
|
30
|
+
print(_TOP_HELP, file=sys.stderr)
|
|
31
|
+
return 2
|
|
32
|
+
|
|
33
|
+
if argv[0] in ("-h", "--help"):
|
|
34
|
+
print(_TOP_HELP)
|
|
35
|
+
return 0
|
|
36
|
+
|
|
37
|
+
cmd, rest = argv[0], argv[1:]
|
|
38
|
+
if cmd == "server":
|
|
39
|
+
from adbproxy.cli import server as sub
|
|
40
|
+
elif cmd == "device":
|
|
41
|
+
from adbproxy.cli import device as sub
|
|
42
|
+
else:
|
|
43
|
+
print(f"unknown command: {cmd}", file=sys.stderr)
|
|
44
|
+
print(_TOP_HELP, file=sys.stderr)
|
|
45
|
+
return 2
|
|
46
|
+
|
|
47
|
+
old_argv = sys.argv
|
|
48
|
+
try:
|
|
49
|
+
# 旧入口固定读 sys.argv[1:];剥掉子命令名后再调用,避免把
|
|
50
|
+
# "server"/"device" 传给 AdbProxy / ClientMock 的 argparse。
|
|
51
|
+
sys.argv = [old_argv[0], *rest]
|
|
52
|
+
result = sub.main()
|
|
53
|
+
finally:
|
|
54
|
+
sys.argv = old_argv
|
|
55
|
+
|
|
56
|
+
return 0 if result is None else result
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
if __name__ == "__main__":
|
|
60
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import struct
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
PROXY_PORT = 5037
|
|
6
|
+
REAL_ADB_PORT = 5038
|
|
7
|
+
# 源码布局:本文件在 src/adbproxy/config.py,项目根为 src 的上两级。
|
|
8
|
+
# 运行产物统一落到 <project>/out/{logs,files},可用 ADB_PROXY_OUT_DIR 覆盖 out 根目录。
|
|
9
|
+
_SRC_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
10
|
+
_PROJECT_ROOT = os.path.dirname(os.path.dirname(_SRC_DIR))
|
|
11
|
+
_OUT_ROOT = os.environ.get(
|
|
12
|
+
"ADB_PROXY_OUT_DIR", os.path.join(_PROJECT_ROOT, "out")
|
|
13
|
+
)
|
|
14
|
+
LOG_DIR = os.path.join(_OUT_ROOT, "logs")
|
|
15
|
+
FILES_DIR = os.path.join(_OUT_ROOT, "files")
|
|
16
|
+
IDLE_TIMEOUT = 0.15
|
|
17
|
+
MAX_V2_BUF = 1 << 20 # 1 MiB,v2 半包重组缓冲上限
|
|
18
|
+
MAX_CMD = 4096 # 单条命令累积上限
|
|
19
|
+
SYNC_DATA_MAX = (
|
|
20
|
+
64 * 1024
|
|
21
|
+
) # 与 AOSP file_sync_protocol.h:146 一致,DATA 单块上限(校验用)
|
|
22
|
+
MAX_SYNC_FILE = 256 * 1024 * 1024 # 单文件落盘上限 256 MiB,防磁盘失控
|
|
23
|
+
# sync v2 定长 struct 大小(核对 file_sync_protocol.h,packed little-endian)
|
|
24
|
+
# sync_stat_v2: id,error,dev,ino,mode,nlink,uid,gid,size,atime,mtime,ctime
|
|
25
|
+
_STAT_V2_FMT = "<IIQQIIIIQqqq"
|
|
26
|
+
_STAT_V2_SIZE = struct.calcsize(_STAT_V2_FMT) # 72
|
|
27
|
+
# sync_dent_v2: stat_v2 + namelen
|
|
28
|
+
_DENT_V2_FMT = _STAT_V2_FMT + "I"
|
|
29
|
+
_DENT_V2_SIZE = struct.calcsize(_DENT_V2_FMT) # 76,后随 namelen 字节 name
|
|
30
|
+
# sync_stat_v1: id,mode,size,mtime
|
|
31
|
+
_STAT_V1_SIZE = struct.calcsize("<IIII") # 16
|
|
32
|
+
# sync_dent_v1: id,mode,size,mtime,namelen
|
|
33
|
+
_DENT_V1_SIZE = struct.calcsize("<IIIII") # 20,后随 namelen 字节 name
|
|
34
|
+
_SEND_V2_SIZE = struct.calcsize("<III") # sync_send_v2: id,mode,flags = 12
|
|
35
|
+
_RECV_V2_SIZE = struct.calcsize("<II") # sync_recv_v2: id,flags = 8
|
|
36
|
+
|
|
37
|
+
DEFAULT_LISTEN_PORT = 5566
|
|
38
|
+
DEFAULT_ADB_SERVER_PORT = 5037
|
|
39
|
+
DEFAULT_BANNER_FEATURES = "shell_v2,sendrecv_v2"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""ADB server 到 daemon 的传输代理。"""
|