-
-
Notifications
You must be signed in to change notification settings - Fork 190
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
569 additions
and
16 deletions.
There are no files selected for viewing
2 changes: 1 addition & 1 deletion
2
ios/debugproxy/binforward.go → ios/debugproxy/usbmuxd/binforward.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
package debugproxy | ||
package usbmuxd | ||
|
||
import ( | ||
"encoding/hex" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
ios/debugproxy/decoders.go → ios/debugproxy/usbmuxd/decoders.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
package debugproxy | ||
package usbmuxd | ||
|
||
import ( | ||
"bytes" | ||
|
2 changes: 1 addition & 1 deletion
2
ios/debugproxy/dumpingconn.go → ios/debugproxy/usbmuxd/dumpingconn.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
package debugproxy | ||
package usbmuxd | ||
|
||
import ( | ||
"encoding/hex" | ||
|
2 changes: 1 addition & 1 deletion
2
ios/debugproxy/lockdownhandler.go → ios/debugproxy/usbmuxd/lockdownhandler.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
package debugproxy | ||
package usbmuxd | ||
|
||
import ( | ||
"bytes" | ||
|
2 changes: 1 addition & 1 deletion
2
ios/debugproxy/muxhandler.go → ios/debugproxy/usbmuxd/muxhandler.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
package debugproxy | ||
package usbmuxd | ||
|
||
import ( | ||
"bytes" | ||
|
2 changes: 1 addition & 1 deletion
2
ios/debugproxy/socket_mover.go → ios/debugproxy/usbmuxd/socket_mover.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
package debugproxy | ||
package usbmuxd | ||
|
||
import ( | ||
"fmt" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
//go:build darwin | ||
|
||
package utun | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"io" | ||
"os" | ||
"path" | ||
|
||
"github.com/google/gopacket" | ||
"github.com/google/gopacket/layers" | ||
"github.com/sirupsen/logrus" | ||
) | ||
|
||
type connection struct { | ||
id connectionId | ||
w payloadWriter | ||
outPath string | ||
inPath string | ||
service string | ||
} | ||
|
||
func newConnection(id connectionId, p string, service string) (*connection, error) { | ||
inPath := path.Join(p, "incoming") | ||
incoming, err := os.OpenFile(inPath, os.O_CREATE|os.O_WRONLY, os.ModePerm) | ||
if err != nil { | ||
return nil, fmt.Errorf("newConnection: could not open file for incoming connection dump: %w", err) | ||
} | ||
outPath := path.Join(p, "outgoing") | ||
outgoing, err := os.OpenFile(outPath, os.O_CREATE|os.O_WRONLY, os.ModePerm) | ||
if err != nil { | ||
return nil, fmt.Errorf("newConnection: could not open file for outgoing connection dump: %w", err) | ||
} | ||
pw := payloadWriter{ | ||
incoming: incoming, | ||
outgoing: outgoing, | ||
} | ||
return &connection{ | ||
id: id, | ||
w: pw, | ||
outPath: outPath, | ||
inPath: inPath, | ||
service: service, | ||
}, nil | ||
} | ||
|
||
func (c connection) handlePacket(p gopacket.Packet, ip *layers.IPv6, tcp *layers.TCP) { | ||
if tcp.SYN && tcp.SrcPort == c.id.localPort { | ||
logrus.Infof("new connection %s", c.id) | ||
} | ||
if len(tcp.Payload) > 0 { | ||
c.w.Write(c.direction(tcp), tcp.Payload) | ||
} | ||
} | ||
|
||
func (c connection) direction(tcp *layers.TCP) direction { | ||
if c.id.localPort == tcp.SrcPort { | ||
return outgoing | ||
} else { | ||
return incoming | ||
} | ||
} | ||
|
||
func (c connection) Close() error { | ||
_ = c.w.Close() | ||
logrus.WithField("connection", c.id.String()).WithField("service", c.service).Info("closing connection") | ||
err := parseConnectionData(c.outPath, c.inPath) | ||
if err != nil { | ||
logrus.WithField("connection", c.id.String()). | ||
WithField("service", c.service). | ||
WithError(err). | ||
Warn("failed parsing data") | ||
} | ||
return nil | ||
} | ||
|
||
func (c connectionId) String() string { | ||
return fmt.Sprintf("%d-%d", c.localPort, c.remotePort) | ||
} | ||
|
||
func parseConnectionData(outgoing string, incoming string) error { | ||
dir := path.Dir(outgoing) | ||
|
||
outFile, err := os.OpenFile(outgoing, os.O_RDONLY, os.ModePerm) | ||
if err != nil { | ||
return err | ||
} | ||
defer outFile.Close() | ||
inFile, err := os.OpenFile(incoming, os.O_RDONLY, os.ModePerm) | ||
if err != nil { | ||
return err | ||
} | ||
defer inFile.Close() | ||
|
||
t := detectType(outFile) | ||
|
||
switch t { | ||
case http2: | ||
_ = createDecodingFiles(dir, "http.frames", func(outgoing, incoming pair) error { | ||
outErr := decodeHttp2FrameHeaders(outgoing.w, outFile, true) | ||
inErr := decodeHttp2FrameHeaders(incoming.w, inFile, false) | ||
return errors.Join(outErr, inErr) | ||
}) | ||
_, _ = outFile.Seek(0, io.SeekStart) | ||
_, _ = inFile.Seek(0, io.SeekStart) | ||
return createDecodingFiles(dir, "http.bin", func(outgoing, incoming pair) error { | ||
outErr := decodeHttp2(outgoing.w, outFile, true) | ||
inErr := decodeHttp2(incoming.w, inFile, false) | ||
if err := errors.Join(outErr, inErr); err != nil { | ||
//return err | ||
} | ||
return parseConnectionData(outgoing.p, incoming.p) | ||
}) | ||
case remoteXpc: | ||
return createDecodingFiles(dir, "xpc.jsonl", func(outgoing, incoming pair) error { | ||
outErr := decodeRemoteXpc(outgoing.w, outFile) | ||
inErr := decodeRemoteXpc(incoming.w, inFile) | ||
return errors.Join(outErr, inErr) | ||
}) | ||
case remoteDtx: | ||
return createDecodingFiles(dir, "dtx", func(outgoing, incoming pair) error { | ||
outErr := decodeRemoteDtx(outgoing.w, outFile) | ||
inErr := decodeRemoteDtx(incoming.w, inFile) | ||
return errors.Join(outErr, inErr) | ||
}) | ||
default: | ||
stat, _ := os.Stat(outgoing) | ||
if stat.Size() == 0 { | ||
return nil | ||
} | ||
return fmt.Errorf("unknown content type: %s/%s", outgoing, incoming) | ||
} | ||
} | ||
|
||
func createDecodingFiles(dir, suffix string, consumer func(outgoing, incoming pair) error) error { | ||
outPath := path.Join(dir, fmt.Sprintf("outgoing.%s", suffix)) | ||
inPath := path.Join(dir, fmt.Sprintf("incoming.%s", suffix)) | ||
|
||
outFile, err := os.OpenFile(outPath, os.O_CREATE|os.O_WRONLY, os.ModePerm) | ||
if err != nil { | ||
return err | ||
} | ||
defer outFile.Close() | ||
inFile, err := os.OpenFile(inPath, os.O_CREATE|os.O_WRONLY, os.ModePerm) | ||
if err != nil { | ||
return err | ||
} | ||
defer inFile.Close() | ||
|
||
return consumer(pair{outPath, outFile}, pair{inPath, inFile}) | ||
} | ||
|
||
type pair struct { | ||
p string | ||
w io.Writer | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
//go:build darwin | ||
|
||
package utun | ||
|
||
import ( | ||
"bytes" | ||
"encoding/binary" | ||
"encoding/json" | ||
"errors" | ||
"io" | ||
|
||
dtx "github.com/danielpaulus/go-ios/ios/dtx_codec" | ||
"github.com/danielpaulus/go-ios/ios/xpc" | ||
log "github.com/sirupsen/logrus" | ||
http22 "golang.org/x/net/http2" | ||
) | ||
|
||
type contentType int | ||
|
||
const ( | ||
http2 = contentType(iota) | ||
remoteXpc | ||
remoteDtx | ||
unknown | ||
) | ||
|
||
func detectType(r io.ReadSeeker) contentType { | ||
offset, err := r.Seek(0, io.SeekCurrent) | ||
if err != nil { | ||
return unknown | ||
} | ||
defer func() { | ||
r.Seek(offset, io.SeekStart) | ||
}() | ||
b := make([]byte, 4) | ||
_, err = r.Read(b) | ||
if err != nil { | ||
return unknown | ||
} | ||
if string(b) == "PRI " { | ||
return http2 | ||
} | ||
i := binary.LittleEndian.Uint32(b) | ||
if i == 0x29b00b92 { | ||
return remoteXpc | ||
} | ||
if string(b[:3]) == "y[=" { | ||
return remoteDtx | ||
} | ||
|
||
return unknown | ||
} | ||
|
||
func decodeHttp2(w io.Writer, r io.Reader, needSkip bool) error { | ||
if needSkip { | ||
_, err := io.CopyN(io.Discard, r, 24) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
framer := http22.NewFramer(io.Discard, r) | ||
for { | ||
f, err := framer.ReadFrame() | ||
if err != nil { | ||
return err | ||
} | ||
if f.Header().Type == http22.FrameData { | ||
dataFrame := f.(*http22.DataFrame) | ||
if _, err := w.Write(dataFrame.Data()); err != nil { | ||
return err | ||
} | ||
} | ||
} | ||
} | ||
|
||
func decodeHttp2FrameHeaders(w io.Writer, r io.Reader, needSkip bool) error { | ||
if needSkip { | ||
_, err := io.CopyN(io.Discard, r, 24) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
framer := http22.NewFramer(io.Discard, r) | ||
for { | ||
f, err := framer.ReadFrame() | ||
if err != nil { | ||
return err | ||
} | ||
_, err = w.Write(append([]byte(f.Header().String()), '\n')) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
} | ||
|
||
func decodeRemoteXpc(w io.Writer, r io.Reader) error { | ||
for { | ||
m, err := xpc.DecodeMessage(r) | ||
if err != nil { | ||
if errors.Is(err, io.EOF) { | ||
return nil | ||
} | ||
return err | ||
} | ||
|
||
b, err := json.Marshal(m) | ||
if err != nil { | ||
return err | ||
} | ||
buf := bytes.NewBuffer(nil) | ||
json.Compact(buf, b) | ||
if _, err := io.Copy(w, buf); err != nil { | ||
return err | ||
} | ||
if m.IsFileOpen() { | ||
log.Info("file transfer started, skipping remaining data ") | ||
return nil | ||
} | ||
} | ||
} | ||
|
||
func decodeRemoteDtx(w io.Writer, r io.Reader) error { | ||
for { | ||
m, err := dtx.ReadMessage(r) | ||
if err != nil { | ||
if errors.Is(err, io.EOF) { | ||
return nil | ||
} | ||
return err | ||
} | ||
|
||
buf := bytes.NewBufferString(m.StringDebug() + "\n") | ||
if _, err := io.Copy(w, buf); err != nil { | ||
return err | ||
} | ||
} | ||
} |
Oops, something went wrong.