Skip to content

Commit

Permalink
fsync: support app container jails
Browse files Browse the repository at this point in the history
  • Loading branch information
mhils committed Sep 3, 2023
1 parent 37c40b3 commit 7d0928f
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 5 deletions.
64 changes: 64 additions & 0 deletions ios/afc/fsync.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/binary"
"fmt"
"io"
"errors"
"os"
"path"
"path/filepath"
Expand All @@ -13,6 +14,7 @@ import (

"github.com/danielpaulus/go-ios/ios"
log "github.com/sirupsen/logrus"
"howett.net/plist"
)

const serviceName = "com.apple.afc"
Expand Down Expand Up @@ -48,6 +50,68 @@ func New(device ios.DeviceEntry) (*Connection, error) {
return &Connection{deviceConn: deviceConn}, nil
}

func NewContainer(device ios.DeviceEntry, bundleID string) (*Connection, error) {
deviceConn, err := ios.ConnectToService(device, "com.apple.mobile.house_arrest")
if err != nil {
return nil, err
}
err = vendContainer(deviceConn, bundleID)
if err != nil {
return nil, err
}
return &Connection{deviceConn: deviceConn}, nil
}

func vendContainer(deviceConn ios.DeviceConnectionInterface, bundleID string) error {
plistCodec := ios.NewPlistCodec()
vendContainer := map[string]interface{}{"Command": "VendContainer", "Identifier": bundleID}
msg, err := plistCodec.Encode(vendContainer)
if err != nil {
return fmt.Errorf("VendContainer Encoding cannot fail unless the encoder is broken: %v", err)
}
err = deviceConn.Send(msg)
if err != nil {
return err
}
reader := deviceConn.Reader()
response, err := plistCodec.Decode(reader)
if err != nil {
return err
}
return checkResponse(response)
}


func checkResponse(vendContainerResponseBytes []byte) error {
response, err := plistFromBytes(vendContainerResponseBytes)
if err != nil {
return err
}
if "Complete" == response.Status {
return nil
}
if response.Error != "" {
return errors.New(response.Error)
}
return errors.New("unknown error during vendcontainer")
}

func plistFromBytes(plistBytes []byte) (vendContainerResponse, error) {
var vendResponse vendContainerResponse
decoder := plist.NewDecoder(bytes.NewReader(plistBytes))

err := decoder.Decode(&vendResponse)
if err != nil {
return vendResponse, err
}
return vendResponse, nil
}

type vendContainerResponse struct {
Status string
Error string
}

// NewFromConn allows to use AFC on a DeviceConnectionInterface, see crashreport for an example
func NewFromConn(deviceConn ios.DeviceConnectionInterface) *Connection {
return &Connection{deviceConn: deviceConn}
Expand Down
16 changes: 11 additions & 5 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ Usage:
ios runwda [--bundleid=<bundleid>] [--testrunnerbundleid=<testbundleid>] [--xctestconfig=<xctestconfig>] [--arg=<a>]... [--env=<e>]... [options]
ios ax [options]
ios debug [options] [--stop-at-entry] <app_path>
ios fsync (rm [--r] | tree | mkdir) --path=<targetPath>
ios fsync (pull | push) --srcPath=<srcPath> --dstPath=<dstPath>
ios fsync [--app=bundleId] (rm [--r] | tree | mkdir) --path=<targetPath>
ios fsync [--app=bundleId] (pull | push) --srcPath=<srcPath> --dstPath=<dstPath>
ios reboot [options]
ios -h | --help
ios --version | version [options]
Expand Down Expand Up @@ -205,8 +205,8 @@ The commands work as following:
> specify runtime args and env vars like --env ENV_1=something --env ENV_2=else and --arg ARG1 --arg ARG2
ios ax [options] Access accessibility inspector features.
ios debug [--stop-at-entry] <app_path> Start debug with lldb
ios fsync (rm [--r] | tree | mkdir) --path=<targetPath> Remove | treeview | mkdir in target path. --r used alongside rm will recursively remove all files and directories from target path.
ios fsync (pull | push) --srcPath=<srcPath> --dstPath=<dstPath> Pull or Push file from srcPath to dstPath.
ios fsync [--app=bundleId] (rm [--r] | tree | mkdir) --path=<targetPath> Remove | treeview | mkdir in target path. --r used alongside rm will recursively remove all files and directories from target path.
ios fsync [--app=bundleId] (pull | push) --srcPath=<srcPath> --dstPath=<dstPath> Pull or Push file from srcPath to dstPath.
ios reboot [options] Reboot the given device
ios -h | --help Prints this screen.
ios --version | version [options] Prints the version
Expand Down Expand Up @@ -802,7 +802,13 @@ The commands work as following:

b, _ = arguments.Bool("fsync")
if b {
afcService, err := afc.New(device)
containerBundleId, _ := arguments.String("--app")
var afcService *afc.Connection
if containerBundleId == "" {
afcService, err = afc.New(device)
} else {
afcService, err = afc.NewContainer(device, containerBundleId)
}
exitIfError("fsync: connect afc service failed", err)
b, _ = arguments.Bool("rm")
if b {
Expand Down

0 comments on commit 7d0928f

Please sign in to comment.