Skip to content
jiaxw32 edited this page Nov 5, 2023 · 1 revision

During normal operations, iTunes communicates with the iPhone using something called “usbmux” – this is a system for multiplexing several “connections” over one USB pipe. Conceptually, it provides a TCP-like system – processes on the host machine open up connections to specific, numbered ports on the mobile device. (This resemblance is more than superficial – on the mobile device, usbmuxd actually makes TCP connections to localhost using the port number you give it.)

在正常操作中,iTunes使用一种称为“usbmux”的东西与iPhone进行通信 - 这是一种通过一个USB管道多路复用几个“连接”的系统。从概念上讲,它提供了类似TCP的系统 - 主机上的进程打开到移动设备上特定编号端口的连接。(这种相似性不仅仅是表面上的 - 在移动设备上,usbmuxd实际上使用您给出的端口号向本地主机建立TCP连接。)

On the Mac, this is handled by /System/Library/PrivateFrameworks/MobileDevice.framework/Resources/usbmuxd, a daemon that is started by launchd (see /System/Library/LaunchDaemons/com.apple.usbmuxd.plist). It creates a listening UNIX Domain Socket at /var/run/usbmuxd. usbmuxd then watches for iPhone connections via USB; when it detects an iPhone running in normal mode (as opposed to recovery mode), it will connect to it and then start relaying requests that it receives via /var/run/usbmuxd – this is to say, usbmuxd is the only thing that actually speaks USB to the iPhone. This means that third-party applications which wish to talk to the iPhone must either do so through usbmuxd, or usbmuxd must be replaced.

在 Mac上,这是由/System/Library/PrivateFrameworks/MobileDevice.framework/Resources/usbmuxd 处理的,它是由launchd启动的守护进程(参见/System/Library/LaunchDaemons/com.apple.usbmuxd.plist)。它在/var/run/usbmuxd创建一个监听UNIX域套接字。然后,usbmuxd通过USB监视iPhone连接;当它检测到运行在正常模式下的iPhone时(而不是恢复模式),它将连接到该设备,并开始转发通过/var/run/usbmuxd收到的请求 - 这就是说,usbmuxd实际上是唯一与iPhone进行USB通信的东西。这意味着希望与iPhone通信的第三方应用程序必须通过usbmuxd进行通信,或者必须替换掉usbmuxd。

Layered Communications

Communications between the host (generally, iTunes running on a Mac or Windows machine) and the device (an iPhone, iPad or iPod touch) take place using a complicated scheme of nested layers. From lowest level to highest, they are:

  • USB protocol: multiplexes multiple data streams over one pair of bulk endpoints
  • usbmuxd protocol: provides a way of opening connections to TCP ports on the device
  • lockdownd protocol: tbd
  • iTunesHelper?
  • AFC?

主机(通常是运行在Mac或Windows机器上的iTunes)和设备(iPhone、iPad或iPod touch)之间的通信采用了一种复杂的嵌套层次结构。从最低级到最高级,它们分别是:

  • USB 协议:通过一个批量端点对多个数据流进行复用
  • usbmuxd 协议:提供了一种打开设备上TCP端口连接的方式
  • lockdownd 协议:待定
  • iTunesHelper?
  • AFC?

Client to usbmuxd

When a process on the host machine wants to talk to the iPhone, it opens up a connection to /var/run/usbmuxd. It then performs an initial handshake; after this handshake, the data in the socket is transparently tunneled to the specified TCP port on the phone. An easy way to watch this happen is to use socat, like so:

当主机上的进程想要与iPhone通信时,它会打开一个连接到/var/run/usbmuxd。然后进行初始握手;在此握手之后,套接字中的数据将透明地隧道传输到手机上指定的TCP端口。观察这个过程发生的一种简单方法是使用socat命令,如下所示:

sudo mv /var/run/usbmuxd /var/run/usbmuxx
sudo socat -t100 -x -v UNIX-LISTEN:/var/run/usbmuxd,mode=777,reuseaddr,fork UNIX-CONNECT:/var/run/usbmuxx

Data structures

All data structures are little-endian

所有的数据结构都是小端字节序。

struct usbmux_header {
	u32 length;	// length of message, including header
	u32 reserved;	// always zero
	u32 type;       // message type
	u32 tag;	// responses to this query will echo back this tag
};

struct usbmux_result {
	struct usbmux_header header;
	u32 result;
};

struct usbmux_connect_request {
	struct usbmux_header header;
	u32  device_id;
	u16  port;		// TCP port number
};

enum {
	usbmux_result  = 1,
	usbmux_connect = 2,
	usbmux_hello   = 3,
};

Sequence of Events

  1. Client opens connection to /var/run/usbmuxd
  2. Client sends "Hello" packet:
10000000 00000000 03000000 02000000
(length = 0x10, reserved = 0, type = 3, tag = 2)
  1. Client receives "Hello" response:
14000000 00000000 01000000 02000000 00000000
(length = 0x14, type = 1, tag = 2, result = 0)
  1. Client receives device ID:
1c 01 00 00 00 00 00 00 04 00 00 00 00 00 00 00  ................
19 00 00 00 91 12 31 33 31 34 64 66 34 61 30 30  ......1314df4a00
65 37 31 37 35 35 62 31 32 30 31 66 64 36 34 34  e71755b1201fd644
35 34 63 63 35 38 36 39 39 63 30 31 66 64 00 00  54cc58699c01fd..
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
[...]
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00 00 00 00 00 00 00 00 00 00 10 fd              ............
(length=0x1c1, type = 4, tag = 0, device_id = 0x19, usb_product_id = 0x1291, serial number string = "1314.....01fd".... ?)
  1. Client sends TCP connect request:
18000000 00000000 02000000 03000000 19000000 00160000
(length = 0x18, type = 2, tag = 3, device_id = 0x19, port = 0x0016 (big-endian) = 22)
  1. Client receives ACK:

    • Connection refused:
    14000000 00000000 01000000 03000000 03000000
    (length = 0x14, type = 1, tag = 3, result = 3 -- connection refused?)
    • Connection established:
    14000000 00000000 01000000 03000000 00000000
    (length = 0x14, type = 1, tag = 3, result = 0 -- no error)

From this point on, data is piped directly between the unix socket on the host and the TCP port on the device.

从这一点开始,数据直接通过主机上的Unix套接字和设备上的TCP端口进行传输。

lockdownd protocol

lockdownd uses port 62078. It uses a simple packet format - each packet is a 32-bit big-endian word indicating the size of the payload of the packet. Packets are in XML plist format, unless otherwise stated; the first two packets are shown in full, and the rest are abbreviated for the sake of readability.

lockdownd使用端口62078。它使用简单的数据包格式 - 每个数据包是一个32位大端字,指示数据包负载的大小。除非另有说明,否则数据包采用XML plist格式;为了易读起见,前两个数据包完整显示,其余部分缩写。

Example: plug iPod touch into iTunes

示例:将iPod touch插入iTunes

1. request: {Label=iTunesHelper, Request=QueryType}
0000011d (length of request, now in big-endian!)

ASCII payload:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Label</key>
	<string>iTunesHelper</string>
	<key>Request</key>
	<string>QueryType</string>
</dict>
</plist>
2. response: {Request=QueryType, Result=Success, Type=com.apple.mobile.lockdown}
00000156 (length)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Request</key>
	<string>QueryType</string>
	<key>Result</key>
	<string>Success</string>
	<key>Type</key>
	<string>com.apple.mobile.lockdown</string>
</dict>
</plist>
3. request: {Label=iTunesHelper, PairRecord={DeviceCertificate=xxxx,HostCertificate=xxxx,HostID=xxxx,RootCertificate=xxxx}, Request=ValidatePair}
<dict>
	<key>Label</key>
	<string>iTunesHelper</string>
	<key>PairRecord</key>
	<dict>
		<key>DeviceCertificate</key>
 		
		LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNOVENDQVIyZ0F3SUJB
		[...]
		RVJUSUZJQ0FURS0tLS0tCg==
		
		<key>HostCertificate</key>
		
		LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN1akNDQWFLZ0F3SUJB
		[...]
		UlRJRklDQVRFLS0tLS0K
		
		<key>HostID</key>
		<string>D7......-....-....-....-........4EFE</string>
		<key>RootCertificate</key>
		
		LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNyVENDQVpXZ0F3SUJB
		[...]
		NUVPRitjZVFNcUovZHBFdz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
		
	</dict>
	<key>Request</key>
	<string>ValidatePair</string>
</dict>
4. response: {Request=ValidatePair, Result=Success}
<dict>
	<key>Request</key>
	<string>ValidatePair</string>
	<key>Result</key>
	<string>Success</string>
</dict>
5. request: {HostID=xxx, Label=iTunesHelper, Request=StartSession}
<dict>
	<key>HostID</key>
	<string>D7......-....-....-....-........4EFE</string>
	<key>Label</key>
	<string>iTunesHelper</string>
	<key>Request</key>
	<string>StartSession</string>
</dict>
6. response: {EnableSessionSSL=true, Request=StartSession, Result=Success, SessionID=xxx}
<dict>
	<key>EnableSessionSSL</key>
	<true/>
	<key>Request</key>
	<string>StartSession</string>
	<key>Result</key>
	<string>Success</string>
	<key>SessionID</key>
	<string>DE622607-91A9-4DA7-A38C-F6DC1F8EF24F</string>
</dict>

usbmuxd to iPhone

(TBD …)

(待定...)

Acknowledgements

This document was originally part of wikee.iphwn.org, which no longer seems to exist. This version was pulled from archive.org on 12 Oct 2011, and was last edited on 13 Jul 2008. All credit for this document should go to the iPhone Dev Team.

这份文件最初是wikee.iphwn.org的一部分,但该网站似乎已经不存在了。此版本是从archive.org于2011年10月12日获取的,并且最后编辑时间为2008年7月13日。对于这份文件的所有功劳应归功于iPhone Dev Team。

Resources

Clone this wiki locally