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.
Files changed (58) hide show
  1. adbproxy-0.1.0/LICENSE +21 -0
  2. adbproxy-0.1.0/PKG-INFO +254 -0
  3. adbproxy-0.1.0/README.md +233 -0
  4. adbproxy-0.1.0/pyproject.toml +37 -0
  5. adbproxy-0.1.0/setup.cfg +4 -0
  6. adbproxy-0.1.0/src/adbproxy/__init__.py +2 -0
  7. adbproxy-0.1.0/src/adbproxy/__main__.py +5 -0
  8. adbproxy-0.1.0/src/adbproxy/cli/__init__.py +1 -0
  9. adbproxy-0.1.0/src/adbproxy/cli/device.py +13 -0
  10. adbproxy-0.1.0/src/adbproxy/cli/main.py +60 -0
  11. adbproxy-0.1.0/src/adbproxy/cli/server.py +13 -0
  12. adbproxy-0.1.0/src/adbproxy/config.py +39 -0
  13. adbproxy-0.1.0/src/adbproxy/device/__init__.py +1 -0
  14. adbproxy-0.1.0/src/adbproxy/device/app.py +532 -0
  15. adbproxy-0.1.0/src/adbproxy/device/backend.py +242 -0
  16. adbproxy-0.1.0/src/adbproxy/device/banner.py +33 -0
  17. adbproxy-0.1.0/src/adbproxy/device/connection.py +505 -0
  18. adbproxy-0.1.0/src/adbproxy/device/session.py +304 -0
  19. adbproxy-0.1.0/src/adbproxy/device/stream_table.py +125 -0
  20. adbproxy-0.1.0/src/adbproxy/observers/__init__.py +1 -0
  21. adbproxy-0.1.0/src/adbproxy/observers/events.py +19 -0
  22. adbproxy-0.1.0/src/adbproxy/observers/install.py +126 -0
  23. adbproxy-0.1.0/src/adbproxy/observers/shell.py +371 -0
  24. adbproxy-0.1.0/src/adbproxy/observers/stream.py +94 -0
  25. adbproxy-0.1.0/src/adbproxy/observers/sync.py +550 -0
  26. adbproxy-0.1.0/src/adbproxy/protocols/__init__.py +1 -0
  27. adbproxy-0.1.0/src/adbproxy/protocols/adb.py +66 -0
  28. adbproxy-0.1.0/src/adbproxy/protocols/payload/__init__.py +17 -0
  29. adbproxy-0.1.0/src/adbproxy/protocols/payload/install.py +44 -0
  30. adbproxy-0.1.0/src/adbproxy/protocols/payload/shell_v2.py +28 -0
  31. adbproxy-0.1.0/src/adbproxy/protocols/payload/sync.py +180 -0
  32. adbproxy-0.1.0/src/adbproxy/protocols/smart_socket/__init__.py +33 -0
  33. adbproxy-0.1.0/src/adbproxy/protocols/smart_socket/classifier.py +78 -0
  34. adbproxy-0.1.0/src/adbproxy/protocols/smart_socket/conversation.py +335 -0
  35. adbproxy-0.1.0/src/adbproxy/protocols/smart_socket/handshake.py +75 -0
  36. adbproxy-0.1.0/src/adbproxy/protocols/smart_socket/wire.py +82 -0
  37. adbproxy-0.1.0/src/adbproxy/protocols/transport/__init__.py +52 -0
  38. adbproxy-0.1.0/src/adbproxy/protocols/transport/codec.py +90 -0
  39. adbproxy-0.1.0/src/adbproxy/protocols/transport/constants.py +21 -0
  40. adbproxy-0.1.0/src/adbproxy/protocols/transport/errors.py +5 -0
  41. adbproxy-0.1.0/src/adbproxy/runtime/__init__.py +1 -0
  42. adbproxy-0.1.0/src/adbproxy/runtime/adb_process.py +195 -0
  43. adbproxy-0.1.0/src/adbproxy/runtime/capture.py +41 -0
  44. adbproxy-0.1.0/src/adbproxy/runtime/logging.py +113 -0
  45. adbproxy-0.1.0/src/adbproxy/runtime/sockets.py +14 -0
  46. adbproxy-0.1.0/src/adbproxy/server/__init__.py +1 -0
  47. adbproxy-0.1.0/src/adbproxy/server/app.py +221 -0
  48. adbproxy-0.1.0/src/adbproxy/server/connection.py +378 -0
  49. adbproxy-0.1.0/src/adbproxy.egg-info/PKG-INFO +254 -0
  50. adbproxy-0.1.0/src/adbproxy.egg-info/SOURCES.txt +56 -0
  51. adbproxy-0.1.0/src/adbproxy.egg-info/dependency_links.txt +1 -0
  52. adbproxy-0.1.0/src/adbproxy.egg-info/entry_points.txt +4 -0
  53. adbproxy-0.1.0/src/adbproxy.egg-info/requires.txt +10 -0
  54. adbproxy-0.1.0/src/adbproxy.egg-info/top_level.txt +1 -0
  55. adbproxy-0.1.0/tests/test_cli_main.py +86 -0
  56. adbproxy-0.1.0/tests/test_dynamic_commands.py +582 -0
  57. adbproxy-0.1.0/tests/test_imports.py +97 -0
  58. 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.
@@ -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
+ - 代理是透明的:解析失败不会改写或阻断转发字节
@@ -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"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,2 @@
1
+ """ADB proxy implementations and protocol observers."""
2
+
@@ -0,0 +1,5 @@
1
+ """python -m adbproxy → 统一 CLI。"""
2
+
3
+ from adbproxy.cli.main import main
4
+
5
+ raise SystemExit(main())
@@ -0,0 +1 @@
1
+ """代理程序命令行入口(统一 adbproxy 与兼容旧脚本)。"""
@@ -0,0 +1,13 @@
1
+ """ADB 设备端代理命令行入口。"""
2
+
3
+ import sys
4
+
5
+ from adbproxy.device.app import ClientMock
6
+
7
+
8
+ def main(argv=None):
9
+ ClientMock(sys.argv[1:] if argv is None else argv).serve()
10
+
11
+
12
+ if __name__ == "__main__":
13
+ main()
@@ -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,13 @@
1
+ """ADB 服务端代理命令行入口。"""
2
+
3
+ import sys
4
+
5
+ from adbproxy.server.app import AdbProxy
6
+
7
+
8
+ def main():
9
+ AdbProxy(sys.argv[1:]).serve()
10
+
11
+
12
+ if __name__ == "__main__":
13
+ 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 的传输代理。"""