diff --git a/cmd/ipsw/cmd/idev/idev_fsyms.go b/cmd/ipsw/cmd/idev/idev_fsyms.go index b6690e060..2718b4fc6 100644 --- a/cmd/ipsw/cmd/idev/idev_fsyms.go +++ b/cmd/ipsw/cmd/idev/idev_fsyms.go @@ -75,6 +75,10 @@ var FetchsymsCmd = &cobra.Command{ ldc.Close() } + if err := utils.IsDeveloperImageMounted(dev.UniqueDeviceID); err != nil { + return fmt.Errorf("for device %s: %w", dev.UniqueDeviceID, err) + } + cli, err := fetchsymbols.NewClient(dev.UniqueDeviceID) if err != nil { return fmt.Errorf("failed to connect to fetchsymbols service: %w", err) diff --git a/cmd/ipsw/cmd/idev/idev_screen.go b/cmd/ipsw/cmd/idev/idev_screen.go index 2462a5a4d..1b8e49be9 100644 --- a/cmd/ipsw/cmd/idev/idev_screen.go +++ b/cmd/ipsw/cmd/idev/idev_screen.go @@ -88,6 +88,11 @@ var ScreenCmd = &cobra.Command{ return err } ldc.Close() + + if err := utils.IsDeveloperImageMounted(dev.UniqueDeviceID); err != nil { + return fmt.Errorf("for device %s: ensure Developer Mode is enabled on iOS16+ AND %w", dev.UniqueDeviceID, err) + } + return saveScreenshot(dev, output) } else { devs, err := utils.PickDevices() @@ -96,6 +101,10 @@ var ScreenCmd = &cobra.Command{ } for _, dev := range devs { + if err := utils.IsDeveloperImageMounted(dev.UniqueDeviceID); err != nil { + return fmt.Errorf("for device %s: ensure Developer Mode is enabled on iOS16+ AND %w", dev.UniqueDeviceID, err) + } + if err := saveScreenshot(dev, output); err != nil { return fmt.Errorf("failed to save screenshot: %w", err) } diff --git a/internal/utils/usb.go b/internal/utils/usb.go index 3950adf1c..9935b8039 100644 --- a/internal/utils/usb.go +++ b/internal/utils/usb.go @@ -9,6 +9,7 @@ import ( "github.com/apex/log" "github.com/blacktop/ipsw/pkg/usb" "github.com/blacktop/ipsw/pkg/usb/lockdownd" + "github.com/blacktop/ipsw/pkg/usb/mount" ) func PickDevice() (*lockdownd.DeviceValues, error) { @@ -131,3 +132,22 @@ func PickDevices() ([]*lockdownd.DeviceValues, error) { return picked, nil } } + +func IsDeveloperImageMounted(udid string) error { + cli, err := mount.NewClient(udid) + if err != nil { + return fmt.Errorf("failed to connect to mobile_image_mounter: %w", err) + } + defer cli.Close() + + images, err := cli.ListImages(mount.ImageTypeDeveloper) + if err != nil { + return fmt.Errorf("failed to list images: %w", err) + } + + if len(images) == 0 { + return fmt.Errorf("mount the Developer image with the `ipsw idev img mount` command or by opening Xcode") + } + + return nil +} diff --git a/pkg/usb/fetchsymbols/fetchsymbols.go b/pkg/usb/fetchsymbols/fetchsymbols.go index b94ae5e82..5acaf1301 100644 --- a/pkg/usb/fetchsymbols/fetchsymbols.go +++ b/pkg/usb/fetchsymbols/fetchsymbols.go @@ -30,7 +30,7 @@ type Client struct { func NewClient(udid string) (*Client, error) { c, err := lockdownd.NewClientForService(serviceName, udid, false) if err != nil { - return nil, fmt.Errorf("you might need to enable Developer Mode in your device Settings app OR mount the Developer image with `ipsw idev img mount`: %v", err) + return nil, fmt.Errorf("you might need to enable Developer Mode in your device Settings app: %v", err) } return &Client{ c: c,