libusbmuxd 1.0.9

libusbmuxd 1.0.9

测试已测试
语言语言 CC
许可 自定义
发布上次发布2014年12月

未命名 维护。



  • Chris Ballinger

背景

'usbmuxd' 代表 "USB 多路复用守护进程"。此守护进程负责通过 USB 在 iPhone 或 iPod touch 上多路复用连接。对用户来说,这意味着您可以通过 USB 同步音乐、联系人、照片等。对开发者来说,这意味着您可以直接连接到设备上的任何监听本地套接字。usbmuxd 不用于点对点数据传输,它使用一个专用的 USB 接口作为虚拟网络设备。

可以在并行的情况下发生多个对不同的 TCP 端口的连接。一个叫做 'iproxy' 的(有用)工具被包含在内,允许您将本地主机端口转发到设备——允许已越狱设备上的 USB SSH,或允许访问锁定守护进程(然后是设备上运行的所有文件访问、同步、通知和备份服务)。

更高级的层由 libimobiledevice 处理。'ifuse' 然后可以在其上运行,并将您的设备的 AFC 文件系统挂载共享。

此软件包包含 usbmuxd 通讯接口库 'libusbmuxd'。

在 python-client 目录中还有一个客户端库的 Python 实现,还有一个名为 tcprelay.py 的示例,它执行与 iproxy 类似的功能。此实现支持 OSX 和 Windows 以及新的基于 iTunes plist 的 usbmuxd 协议,因此它具有便携性,并将在那些操作系统上无需修改即可运行,使用 Apple 的原生 usbmuxd。如果需要在紧急情况下从另一个 OS 识别到您的设备,这很有用。运行 python tcpclient.py --help 以获取使用信息。

许可

本软件包的内容根据 GNU Lesser General Public License(版本 2.1 或,根据您的要求,任何更高版本)进行许可(请参阅 COPYING.LGPLv2.1)。如果源文件的开头指定了一个更宽泛的许可证,则它优先于本许可证。

法律

Apple、iPhone 和 iPod touch 是 Apple Inc. 的注册商标,在美国和其他国家注册。

构建

./autogen.sh make sudo make install

运行(使用 magic)

(拔掉 + 重新连接已越狱的设备)./iproxy 2222 22 & ssh -p 2222 root@localhost

希望您能得到正常的 SSH 登录提示。您目前可能仍有很多调试输出。如果这干扰了您的 ssh 登录,请从不同的 xterminal 或虚拟控制台运行 'ssh' 命令。当然,您需要在越狱的设备上安装 OpenSSH 才能使用此功能。

如果您有 iFuse,可以运行 "ifuse . 这不需要 iproxy,并且在所有设备上都能工作,无论是否越狱。

运行(不含魔法)

如果您的机器上的 'udev' 没有自动运行并且抓取新的 .rules 文件,您需要先手动启动 usbmuxd。通过 'ps aux | grep usbmuxd' 运行它并确认只有一个实例。

sudo usbmuxd -U -v -v & ./iproxy 2222 22 & ssh -p 2222 root@localhost

小贴士:如果禁用了 SSH,则启动 SSH

如果您的设备已越狱,但 SSH 未启动并且您无法(例如,屏幕破裂)进入设备的“服务”控制面板,那么您可以通过挂载(越狱的)文件系统在 USB 上启动 SSH 服务。

您需要使用 'ifuse --afc2'(以便访问设备的根目录)来挂载它,然后编辑

/Library/LaunchDaemons/com.openssh.sshd.plist

删除 以下行

禁用

重新启动设备,然后 sshd 应该正在运行。

待办事项

服务器目前假设设备表现良好并且不会进行大量的检查,例如查找预期的 SEQ 和 ACK 号码。这通常不是问题,但它在调试中很烦人,因为丢失的包(不应该发生,但如果代码有错误则可能发生)会导致信息不同步,然后可能会在后来的数十个包之后崩溃并燃烧。

服务器需要更多的测试和优化。

可能有人应该做一些边缘情况测试的 TCP 内容。

服务器上的 outgoing ACK 处理可能需要一些思考。目前,当有挂起的 ACK 时,我们在超时后发送它(以避免为发送给我们手机上的所有内容发送无负载的 ACK 数据包)。然而,可能有一种更好的方法来处理这个问题。

体系结构信息

iPhone / iPod Touch 实现了一个相当奇怪的 USB 网络系统,在更高的层级上运行。这是当然完全专有的。一般来说,在典型的使用场景中是这样的

  1. iTunes 与 usbmuxd 建立连接并要求其提供设备通知
  2. 用户将手机插入电脑
  3. usbmuxd 检测到手机并用版本包 ping 它
  4. 手机回复
  5. usbmuxd 现在认为手机已连接并通知 iTunes
  6. iTunes 与 usbmuxd 建立另一个单独的连接并要求它连接到设备的 afc 端口
  7. usbmuxd 向手机发送伪 TCP SYN 包
  8. 手机的内核驱动程序收到 SYN 包,并在 afc 端口上本身打开一个 TCP 连接到 localhost
  9. 手机回复伪 TCP SYN/ACK 指示端口已打开且连接可以继续
  10. usbmuxd 向手机发送最终的 ACK
  11. usbmuxd 向 iTunes 发送“连接成功”的消息
  12. 从现在开始,任何 iTunes 打写到 usbmuxd 套接字的数据都通过伪 TCP,通过 USB,然后通过本地的更常规的 TCP 连接到手机的 afc 捕获程序,反之亦然

usbmuxd 协议是一种相对简单的二进制消息协议,在此处有文档说明

http://wikee.iphwn.org/usb:usbmux

请注意,一旦建立了连接,UNIX 套接字基本上变成了 TCP 连接的专用管道,不再可能进行高级控制(关闭套接字将关闭 TCP 连接)。同样的,“监听设备”模式也是如此 - usbmuxd 将拒绝在该模式下发布的任何命令,套接字实际上变成了专用设备通知管道。这意味着您至少需要与 usbmuxd 建立两个连接才能执行任何有用的事情。

在Windows上,usbmuxd的工作方式相同,但使用localhost端口27015的TCP连接来替代UNIX套接字。在OSX上,UNIX套接字位于/var/run/usbmuxd。在这里实现的服务器和客户端采用了默认的同一 个 /var/run/usbmuxd 套接字。

手机协议通过一对USB块端点进行操作。有一个用于包大小信息的外层和“协议”(版本和TCP是唯一两个选项),并且紧随其后的是实际数据通信所用的TCP头。然而,该协议并非实际的TCP,而是一个定制的协议,它出于某种原因使用了标准的TCP头并留空了大部分字段。

没有重排序或重传。没有校验和,没有URG、没有PSH、没有非ACK、没有FIN。实际上存在的是用于流控制的SEQ/ACK/窗口机制,RST被用作唯一的连接断开机制(也是“拒绝连接”的原因),并且连接启动是SYN/SYNACK/ACK。

在Windows上,8位常量缩放。只要协商对应选项,这就是合法的TCP。当然,这种协商在这个协议中没有发生。

请注意,由于没有重传,ACK和窗口之间存在一些重叠,用于流控制。例如,服务器从不触碰其窗口大小,如果其缓冲区已满且客户端不读取数据,就拒绝ACK数据。手机也似乎停止发送数据。

此外,如果手机突然RST,请检查数据包的有效负载以获取文本错误信息。注意:如果它声称遭受失忆症,那可能意味着你通过忽略其流控制/窗口大小溢出了它的输入缓冲区。自己去想吧。可能是一个内核代码的逻辑错误。

请注意,所有正常数据包都需要将标志设置为ACK(仅限ACK)。不支持不ACK的支持。始终保持ACK编号字段有效。

usbmuxd的CONNECT请求端口字段是字节交换(网络字节序)。对于基于plist的协议来说更加令人烦恼,因为在其中字段是纯文本。所以即使对于纯文本int,也需要交换字节(端口22变为5632)。我对在PPC Mac上的新plist协议是否也是如此毫无头绪(新的iTunes对这些可用吗?)

由于USB帧结构存在很多坑,而且实现过程中往往出错(例如libusb,这也是补丁的原因)。基本上,USB Bulk在底层提供了从0到wMaxPacketSize(这里是512字节)字节的数据包传输能力。没有其他高级传输帧结构支持。你通过将这些传输拆分成数据包,以最后一个较短的包标记传输结束来实现这些。关键在于,如果传输恰好可以被512整除,你需要发送一个零长度的包(ZLP)来表示传输结束。libusb默认不设置此选项,导致iPhone的数据包彼此粘在一起,它不喜欢这种情况。实际上,这种帧结构有点多余,因为usbmux包头中包含长度字段,但手机仍希望接收ZLP,否则就会出错。更糟糕的是,usbdevfs强制设置最大传输大小为16k,因此libusb将传输拆分为这个大小。只要将ZLP仅添加到最后一个传输中(补丁做了这个),这就是可行的,但它可以很容易地在接收端引起恶意的竞争条件,因为libusb同时进行多个挂起的读取操作,并在接收到较短的数据后取消剩余的读取(但如果有数据已进入其他请求中怎么办呢?),所以我们只执行16k读取,并自行通过对数据包长度头部进行查看将其连接起来。我们仍然依赖于在非16k且是512的倍数的边界上发送ZLP以结束传输,这似乎工作得很好。我想ZLP可能会在某些情况下导致RX中出现假零字节传输,但我们忽略了这些情况。顺便说一下,由于usbmux协议的16位长度头部,最大数据包/传输大小为65535字节。