-
-
Notifications
You must be signed in to change notification settings - Fork 162
/
binforward.go
134 lines (119 loc) · 4.1 KB
/
binforward.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package debugproxy
import (
"encoding/hex"
"io"
"path"
ios "github.com/danielpaulus/go-ios/ios"
log "github.com/sirupsen/logrus"
)
type serviceConfig struct {
codec func(string, string, *log.Entry) decoder
handshakeOnlySSL bool
}
//serviceConfigurations stores info about which codec to use for which service by name.
//In addition, DTX based services only execute a SSL Handshake
//and then go back to sending unencrypted data right after the handshake.
var serviceConfigurations = map[string]serviceConfig{
"com.apple.instruments.remoteserver": {NewDtxDecoder, true},
"com.apple.accessibility.axAuditDaemon.remoteserver": {NewDtxDecoder, true},
"com.apple.testmanagerd.lockdown": {NewDtxDecoder, true},
"com.apple.debugserver": {NewBinDumpOnly, true},
"com.apple.instruments.remoteserver.DVTSecureSocketProxy": {NewDtxDecoder, false},
"com.apple.testmanagerd.lockdown.secure": {NewDtxDecoder, false},
"bindumper": {NewBinDumpOnly, false},
}
func getServiceConfigForName(serviceName string) serviceConfig {
if val, ok := serviceConfigurations[serviceName]; ok {
return val
}
return serviceConfigurations["bindumper"]
}
type BinaryForwardingProxy struct {
deviceConn ios.DeviceConnectionInterface
decoder decoder
}
func (b BinaryForwardingProxy) Close() {
b.deviceConn.Close()
}
func (b BinaryForwardingProxy) Send(msg []byte) error {
return b.deviceConn.Send(msg)
}
func (b *BinaryForwardingProxy) ReadMessage() ([]byte, error) {
r := b.deviceConn.Reader()
buffer := make([]byte, 1024)
n, err := r.Read(buffer)
if err != nil {
return make([]byte, 0), err
}
return buffer[0:n], nil
}
func handleConnectToService(connectRequest ios.UsbMuxMessage,
decodedConnectRequest map[string]interface{},
p *ProxyConnection,
muxOnUnixSocket *ios.UsbMuxConnection,
muxToDevice *ios.UsbMuxConnection,
serviceInfo PhoneServiceInformation) {
err := muxToDevice.SendMuxMessage(connectRequest)
if err != nil {
panic("Failed sending muxmessage to device")
}
connectResponse, err := muxToDevice.ReadMessage()
muxOnUnixSocket.SendMuxMessage(connectResponse)
serviceConfig := getServiceConfigForName(serviceInfo.ServiceName)
binToDevice := BinaryForwardingProxy{muxToDevice.ReleaseDeviceConnection(), serviceConfig.codec(
path.Join(p.info.ConnectionPath, "from-device.json"),
path.Join(p.info.ConnectionPath, "from-device.bin"),
p.log,
)}
binOnUnixSocket := BinaryForwardingProxy{muxOnUnixSocket.ReleaseDeviceConnection(), serviceConfig.codec(
path.Join(p.info.ConnectionPath, "to-device.json"),
path.Join(p.info.ConnectionPath, "to-device.bin"),
p.log,
)}
if serviceInfo.UseSSL {
if serviceConfig.handshakeOnlySSL {
binToDevice.deviceConn.EnableSessionSslHandshakeOnly(p.pairRecord)
binOnUnixSocket.deviceConn.EnableSessionSslServerModeHandshakeOnly(p.pairRecord)
} else {
binToDevice.deviceConn.EnableSessionSsl(p.pairRecord)
binOnUnixSocket.deviceConn.EnableSessionSslServerMode(p.pairRecord)
}
}
proxyBinDumpConnection(p, binOnUnixSocket, binToDevice)
}
func proxyBinDumpConnection(p *ProxyConnection, binOnUnixSocket BinaryForwardingProxy, binToDevice BinaryForwardingProxy) {
go proxyBinFromDeviceToHost(p, binOnUnixSocket, binToDevice)
for {
bytes, err := binOnUnixSocket.ReadMessage()
binOnUnixSocket.decoder.decode(bytes)
if err != nil {
binOnUnixSocket.Close()
binToDevice.Close()
if err == io.EOF {
p.LogClosed()
return
}
p.log.Debug("Failed reading bytes", err)
return
}
binToDevice.Send(bytes)
}
}
func proxyBinFromDeviceToHost(p *ProxyConnection, binOnUnixSocket BinaryForwardingProxy, binToDevice BinaryForwardingProxy) {
for {
bytes, err := binToDevice.ReadMessage()
binToDevice.decoder.decode(bytes)
if err != nil {
binOnUnixSocket.Close()
binToDevice.Close()
if err == io.EOF {
p.LogClosed()
return
}
p.log.Debug("Failed reading bytes", err)
return
}
p.log.WithFields(log.Fields{"direction": "device2host"}).Trace(hex.Dump(bytes))
binOnUnixSocket.Send(bytes)
}
}