Skip to content

Commit

Permalink
Merge pull request #9 from SolskGaer/pcapd
Browse files Browse the repository at this point in the history
commiuncate with pcapd to do packet sniffering, replace rvictl
  • Loading branch information
electricbubble authored Jun 22, 2021
2 parents ac5f6d4 + f359b23 commit f5c29fd
Show file tree
Hide file tree
Showing 7 changed files with 244 additions and 13 deletions.
44 changes: 37 additions & 7 deletions device.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@ import (
"context"
"errors"
"fmt"
"os"
"path"
"strings"
"time"

"github.com/electricbubble/gidevice/pkg/ipa"
"github.com/electricbubble/gidevice/pkg/libimobiledevice"
"github.com/electricbubble/gidevice/pkg/nskeyedarchiver"
uuid "github.com/satori/go.uuid"
"howett.net/plist"
"os"
"path"
"strings"
"time"
)

const LockdownPort = 62078
Expand Down Expand Up @@ -43,6 +44,7 @@ type device struct {
houseArrest HouseArrest
syslogRelay SyslogRelay
crashReportMover CrashReportMover
pcapd Pcapd
}

func (d *device) Properties() DeviceProperties {
Expand Down Expand Up @@ -150,9 +152,9 @@ func (d *device) DeletePairRecord() (err error) {
}

func (d *device) lockdownService() (lockdown Lockdown, err error) {
if d.lockdown != nil {
return d.lockdown, nil
}
// if d.lockdown != nil {
// return d.lockdown, nil
// }

var innerConn InnerConn
if innerConn, err = d.NewConnect(LockdownPort, 0); err != nil {
Expand Down Expand Up @@ -460,6 +462,34 @@ func (d *device) SyslogStop() {
d.syslogRelay.Stop()
}

func (d *device) PcapdService() (pcapd Pcapd, err error) {
// if d.pcapd != nil {
// return d.pcapd, nil
// }
if _, err = d.lockdownService(); err != nil {
return nil, err
}
if d.pcapd, err = d.lockdown.PcapdService(); err != nil {
return nil, err
}
pcapd = d.pcapd
return
}

func (d *device) Pcap() (lines <-chan []byte, err error) {
if _, err = d.PcapdService(); err != nil {
return nil, err
}
return d.pcapd.Packet(), nil
}

func (d *device) PcapStop() {
if d.pcapd == nil {
return
}
d.pcapd.Stop()
}

func (d *device) crashReportMoverService() (crashReportMover CrashReportMover, err error) {
if d.crashReportMover != nil {
return d.crashReportMover, nil
Expand Down
5 changes: 3 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/electricbubble/gidevice
go 1.16

require (
github.com/satori/go.uuid v1.2.0 // indirect
howett.net/plist v0.0.0-20201203080718-1454fab16a06 // indirect
github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40
github.com/satori/go.uuid v1.2.0
howett.net/plist v0.0.0-20201203080718-1454fab16a06
)
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 h1:EnfXoSqDfSNJv0VBNqY/88RNnhSGYkrHaO0mmFGbVsc=
github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40/go.mod h1:vy1vK6wD6j7xX6O6hXe621WabdtNkou2h7uRtTfRMyg=
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
13 changes: 11 additions & 2 deletions idevice.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import (
"bytes"
"context"
"fmt"
"github.com/electricbubble/gidevice/pkg/libimobiledevice"
"github.com/electricbubble/gidevice/pkg/nskeyedarchiver"
"log"
"time"

"github.com/electricbubble/gidevice/pkg/libimobiledevice"
"github.com/electricbubble/gidevice/pkg/nskeyedarchiver"
)

type Usbmux interface {
Expand Down Expand Up @@ -61,6 +62,10 @@ type Device interface {
Syslog() (lines <-chan string, err error)
SyslogStop()

PcapdService() (pcapd Pcapd, err error)
Pcap() (packet <-chan []byte, err error)
PcapStop()

crashReportMoverService() (crashReportMover CrashReportMover, err error)
MoveCrashReport(hostDir string, opts ...CrashReportMoverOption) (err error)

Expand Down Expand Up @@ -196,6 +201,10 @@ type SyslogRelay interface {
Stop()
}

type Pcapd interface {
Packet() <-chan []byte
Stop()
}
type CrashReportMover interface {
Move(hostDir string, opts ...CrashReportMoverOption) (err error)
walkDir(dirname string, fn func(path string, info *AfcFileInfo)) (err error)
Expand Down
14 changes: 12 additions & 2 deletions lockdown.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@ import (
"encoding/pem"
"errors"
"fmt"
"github.com/electricbubble/gidevice/pkg/libimobiledevice"
uuid "github.com/satori/go.uuid"
"math/big"
"strconv"
"strings"
"time"

"github.com/electricbubble/gidevice/pkg/libimobiledevice"
uuid "github.com/satori/go.uuid"
)

var _ Lockdown = (*lockdown)(nil)
Expand Down Expand Up @@ -447,6 +448,15 @@ func (c *lockdown) SyslogRelayService() (syslogRelay SyslogRelay, err error) {
return
}

func (c *lockdown) PcapdService() (pcapd Pcapd, err error) {
var innerConn InnerConn
if innerConn, err = c._startService(libimobiledevice.PcapdServiceName, nil); err != nil {
return nil, err
}
pcapdClient := libimobiledevice.NewPcapdClient(innerConn)
return newPcapdClient(pcapdClient), nil
}

func (c *lockdown) CrashReportMoverService() (crashReportMover CrashReportMover, err error) {
var innerConn InnerConn
if innerConn, err = c._startService(libimobiledevice.CrashReportMoverServiceName, nil); err != nil {
Expand Down
60 changes: 60 additions & 0 deletions pcapd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package giDevice

import (
"log"

"github.com/electricbubble/gidevice/pkg/libimobiledevice"
)

type pcapdClient struct {
stop chan struct{}
c *libimobiledevice.PcapdClient
}

func newPcapdClient(c *libimobiledevice.PcapdClient) *pcapdClient {
return &pcapdClient{
stop: make(chan struct{}),
c: c,
}
}

func (c *pcapdClient) Packet() <-chan []byte {
packetCh := make(chan []byte, 10)
go func() {
for {
select {
case <-c.stop:
return
default:
pkt, err := c.c.ReceivePacket()
if err != nil {
close(packetCh)
return
}
var payload []byte
_ = pkt.Unmarshal(&payload)
raw, err := c.c.GetPacket(payload)
if err != nil {
close(packetCh)
return
}
res, err := c.c.CreatePacket(raw)
if err != nil {
log.Println("failed to create packet")
return
}
packetCh <- res
}
}
}()
return packetCh
}

func (c *pcapdClient) Stop() {
select {
case <-c.stop:
default:
close(c.stop)
}
c.c.Close()
}
119 changes: 119 additions & 0 deletions pkg/libimobiledevice/pcapd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package libimobiledevice

import (
"bytes"
"encoding/binary"
"fmt"
"io/ioutil"
"time"

"github.com/lunixbochs/struc"
)

const PcapdServiceName = "com.apple.pcapd"

func NewPcapdClient(innerConn InnerConn) *PcapdClient {
return &PcapdClient{
client: newServicePacketClient(innerConn),
}
}

type PcapdClient struct {
filter func(*IOSPacketHeader) bool
client *servicePacketClient
}

func (c *PcapdClient) ReceivePacket() (respPkt Packet, err error) {
var bufLen []byte
if bufLen, err = c.client.innerConn.Read(4); err != nil {
return nil, fmt.Errorf("lockdown(Pcapd) receive: %w", err)
}
lenPkg := binary.BigEndian.Uint32(bufLen)

buffer := bytes.NewBuffer([]byte{})
buffer.Write(bufLen)

var buf []byte
if buf, err = c.client.innerConn.Read(int(lenPkg)); err != nil {
return nil, fmt.Errorf("lockdown(Pcapd) receive: %w", err)
}
buffer.Write(buf)

if respPkt, err = new(servicePacket).Unpack(buffer); err != nil {
return nil, fmt.Errorf("lockdown(Pcapd) receive: %w", err)
}

debugLog(fmt.Sprintf("<-- %s\n", respPkt))

return
}

type IOSPacketHeader struct {
HdrSize uint32 `struc:"uint32,big"`
Version uint8 `struc:"uint8,big"`
PacketSize uint32 `struc:"uint32,big"`
Type uint8 `struc:"uint8,big"`
Unit uint16 `struc:"uint16,big"`
IO uint8 `struc:"uint8,big"`
ProtocolFamily uint32 `struc:"uint32,big"`
FramePreLength uint32 `struc:"uint32,big"`
FramePstLength uint32 `struc:"uint32,big"`
IFName string `struc:"[16]byte"`
Pid int32 `struc:"int32,little"`
ProcName string `struc:"[17]byte"`
Unknown uint32 `struc:"uint32,little"`
Pid2 int32 `struc:"int32,little"`
ProcName2 string `struc:"[17]byte"`
Unknown2 [8]byte `struc:"[8]byte"`
}

func (c *PcapdClient) GetPacket(buf []byte) ([]byte, error) {
iph := IOSPacketHeader{}
preader := bytes.NewReader(buf)
_ = struc.Unpack(preader, &iph)

if c.filter != nil {
if !c.filter(&iph) {
return nil, nil
}
}

packet, err := ioutil.ReadAll(preader)
if err != nil {
return packet, err
}
if iph.FramePreLength == 0 {
ext := []byte{0xbe, 0xfe, 0xbe, 0xfe, 0xbe, 0xfe, 0xbe, 0xfe, 0xbe, 0xfe, 0xbe, 0xfe, 0x08, 0x00}
return append(ext, packet...), nil
}
return packet, nil
}

type PcaprecHdrS struct {
TsSec int `struc:"uint32,little"` /* timestamp seconds */
TsUsec int `struc:"uint32,little"` /* timestamp microseconds */
InclLen int `struc:"uint32,little"` /* number of octets of packet saved in file */
OrigLen int `struc:"uint32,little"` /* actual length of packet */
}

func (c *PcapdClient) CreatePacket(packet []byte) ([]byte, error) {
now := time.Now()
phs := &PcaprecHdrS{
int(now.Unix()),
int(now.UnixNano() / 1e6),
len(packet),
len(packet),
}
var buf bytes.Buffer
err := struc.Pack(&buf, phs)
if err != nil {
return nil, err
}

buf.Write(packet)
return buf.Bytes(), nil
}

func (c *PcapdClient) Close() {
c.client.innerConn.Close()
}

0 comments on commit f5c29fd

Please sign in to comment.