danielpaulus / go-ios

This is an operating system independent implementation of iOS device features. You can run UI tests, launch or kill apps, install apps etc. with it.
MIT License
906 stars 175 forks source link

iOS 17 support #265

Open danielpaulus opened 1 year ago

danielpaulus commented 1 year ago

My initial research indicates that iOS 17 works with a virtual ethernet adapter to some degree. I guess they are starting to deprecate USBMUXd now finally. Connect an ios 17 device and run arp- a and you will find that it shows up there. Using ios pcap I am pretty sure I was able to capture some traffic that opens the syslog/console service while opening the MacOS console app. Also, when running XCTest with dproxy enabled, it stays mostly empty except for lockdown.

bikeebh commented 1 year ago

we are not able to capture screenshot using this ios screenshot {"level":"info","msg":"no udid specified using first device in list","time":"2023-06-07T13:55:19+05:30","udid":"00008030-000E70963608802E"} {"err":"Could not start service:com.apple.mobile.screenshotr with reason:'InvalidService'. Have you mounted the Developer Image?","level":"fatal","msg":"Starting Screenshotr failed with","time":"2023-06-07T13:55:19+05:30"}

And in Xcode-beta-15 i am not able to find image for iOS 17 version

all command is failing where image mount is require

danielpaulus commented 1 year ago

Yes it seems like all of those go through the virtual Ethernet adapter. I wonder if they will add them back when iOS17 comes out of Beta, but they probably won't. And even if they do, we got to figure out how to use Ethernet rather than USBMUXd it seems.

danielpaulus commented 1 year ago

Seems like a lot is changing. We saw some QUIC(https://en.wikipedia.org/wiki/QUIC) traffic and JSON RPC. Also a new DeviceFramework. Exciting weeks ahead!

dvdmssmnn commented 1 year ago

The RPC that is being used seems to be something called Mercury (it's at /Library/Developer/PrivateFrameworks/Mercury.framework, and it's implement in Swift (as well as the new CoreDevice.framework, which is also in PrivateFrameworks).

CoreDevice also comes with a tool called devicectl, which (finally) allows to execute single actions like installing, pairing etc.

My debugging capabilities of Swift on x86_64 are not that great, but one interesting bit that I got so far was a reply from the device with it's capabilities

"capabilities" => <array: 0x600000c0abb0> { count = 29, capacity = 29, contents =
    0: <dictionary: 0x600002608fc0> { count = 2, transaction: 0, voucher = 0x0, contents =
        "featureIdentifier" => <string: 0x600000c0abe0> { length = 55, contents = "com.apple.coredevice.feature.sendmemorywarningtoprocess" }
        "name" => <string: 0x600000c0ac10> { length = 30, contents = "Send Memory Warning to Process" }
    }
    1: <dictionary: 0x600002609020> { count = 2, transaction: 0, voucher = 0x0, contents =
        "featureIdentifier" => <string: 0x600000c0aca0> { length = 45, contents = "com.apple.coredevice.feature.viewdevicescreen" }
        "name" => <string: 0x600000c0acd0> { length = 18, contents = "View Device Screen" }
    }
    2: <dictionary: 0x600002609080> { count = 2, transaction: 0, voucher = 0x0, contents =
        "featureIdentifier" => <string: 0x600000c0ad60> { length = 44, contents = "com.apple.coredevice.feature.spawnexecutable" }
        "name" => <string: 0x600000c0ad90> { length = 16, contents = "Spawn Executable" }
    }
    3: <dictionary: 0x6000026090e0> { count = 2, transaction: 0, voucher = 0x0, contents =
        "featureIdentifier" => <string: 0x600000c0ae20> { length = 46, contents = "com.apple.coredevice.feature.launchapplication" }
        "name" => <string: 0x600000c0ae50> { length = 18, contents = "Launch Application" }
    }
    4: <dictionary: 0x600002609140> { count = 2, transaction: 0, voucher = 0x0, contents =
        "featureIdentifier" => <string: 0x600000c0aee0> { length = 41, contents = "com.apple.coredevice.feature.uninstallapp" }
        "name" => <string: 0x600000c0af10> { length = 21, contents = "Uninstall Application" }
    }
    5: <dictionary: 0x6000026091a0> { count = 2, transaction: 0, voucher = 0x0, contents =
        "featureIdentifier" => <string: 0x600000c0afa0> { length = 42, contents = "com.apple.coredevice.feature.transferFiles" }
        "name" => <string: 0x600000c0afd0> { length = 14, contents = "Transfer Files" }
    }
    6: <dictionary: 0x600002609200> { count = 2, transaction: 0, voucher = 0x0, contents =
        "featureIdentifier" => <string: 0x600000c0b060> { length = 42, contents = "com.apple.coredevice.feature.listprocesses" }
        "name" => <string: 0x600000c0b090> { length = 14, contents = "List Processes" }
    }
    7: <dictionary: 0x600002609260> { count = 2, transaction: 0, voucher = 0x0, contents =
        "featureIdentifier" => <string: 0x600000c0b0f0> { length = 48, contents = "com.apple.coredevice.feature.sendsignaltoprocess" }
        "name" => <string: 0x600000c0b120> { length = 22, contents = "Send Signal to Process" }
    }
    8: <dictionary: 0x6000026092c0> { count = 2, transaction: 0, voucher = 0x0, contents =
        "featureIdentifier" => <string: 0x600000c0b180> { length = 54, contents = "com.apple.coredevice.feature.monitorprocesstermination" }
        "name" => <string: 0x600000c0b1b0> { length = 31, contents = "Monitor Process for Termination" }
    }
    9: <dictionary: 0x600002609320> { count = 2, transaction: 0, voucher = 0x0, contents =
        "featureIdentifier" => <string: 0x600000c0b240> { length = 47, contents = "com.apple.coredevice.feature.disableddiservices" }
        "name" => <string: 0x600000c0b2a0> { length = 37, contents = "Disable Developer Disk Image Services" }
    }
    10: <dictionary: 0x600002609380> { count = 2, transaction: 0, voucher = 0x0, contents =
        "featureIdentifier" => <string: 0x600000c0b330> { length = 41, contents = "com.apple.coredevice.feature.getlockstate" }
        "name" => <string: 0x600000c0b360> { length = 14, contents = "Get Lock State" }
    }
    11: <dictionary: 0x6000026093e0> { count = 2, transaction: 0, voucher = 0x0, contents =
        "featureIdentifier" => <string: 0x600000c0b3c0> { length = 52, contents = "com.apple.dt.remoteFetchSymbols.dyldSharedCacheFiles" }
        "name" => <string: 0x600000c0b3f0> { length = 31, contents = "com.apple.dt.remoteFetchSymbols" }
    }
    12: <dictionary: 0x600002609440> { count = 2, transaction: 0, voucher = 0x0, contents =
        "featureIdentifier" => <string: 0x600000c0b480> { length = 47, contents = "com.apple.coredevice.feature.querymobilegestalt" }
        "name" => <string: 0x600000c0b4b0> { length = 19, contents = "Query MobileGestalt" }
    }
    13: <dictionary: 0x6000026094a0> { count = 2, transaction: 0, voucher = 0x0, contents =
        "featureIdentifier" => <string: 0x600000c0b540> { length = 41, contents = "com.apple.coredevice.feature.rebootdevice" }
        "name" => <string: 0x600000c0b570> { length = 13, contents = "Reboot Device" }
    }
    14: <dictionary: 0x600002609500> { count = 2, transaction: 0, voucher = 0x0, contents =
        "featureIdentifier" => <string: 0x600000c0b600> { length = 39, contents = "com.apple.coredevice.feature.rsyncfiles" }
        "name" => <string: 0x600000c0b630> { length = 11, contents = "Rsync Files" }
    }
    15: <dictionary: 0x600002609560> { count = 2, transaction: 0, voucher = 0x0, contents =
        "featureIdentifier" => <string: 0x600000c0b690> { length = 50, contents = "com.apple.coredevice.feature.acquireusageassertion" }
        "name" => <string: 0x600000c0b6c0> { length = 23, contents = "Acquire Usage Assertion" }
    }
    16: <dictionary: 0x6000026095c0> { count = 2, transaction: 0, voucher = 0x0, contents =
        "featureIdentifier" => <string: 0x600000c0b750> { length = 40, contents = "com.apple.coredevice.feature.installroot" }
        "name" => <string: 0x600000c0b780> { length = 12, contents = "Install Root" }
    }
    17: <dictionary: 0x600002609620> { count = 2, transaction: 0, voucher = 0x0, contents =
        "featureIdentifier" => <string: 0x600000c0b810> { length = 38, contents = "com.apple.coredevice.feature.listroots" }
        "name" => <string: 0x600000c0b840> { length = 10, contents = "List Roots" }
    }
    18: <dictionary: 0x600002609680> { count = 2, transaction: 0, voucher = 0x0, contents =
        "featureIdentifier" => <string: 0x600000c0b8d0> { length = 41, contents = "com.apple.coredevice.feature.unpairdevice" }
        "name" => <string: 0x600000c0b900> { length = 13, contents = "Unpair Device" }
    }
    19: <dictionary: 0x6000026096e0> { count = 2, transaction: 0, voucher = 0x0, contents =
        "featureIdentifier" => <string: 0x600000c0b990> { length = 42, contents = "com.apple.coredevice.feature.uninstallroot" }
        "name" => <string: 0x600000c0b9c0> { length = 14, contents = "Uninstall Root" }
    }
    20: <dictionary: 0x600002609740> { count = 2, transaction: 0, voucher = 0x0, contents =
        "featureIdentifier" => <string: 0x600000c0ba50> { length = 45, contents = "com.apple.coredevice.feature.fetchddimetadata" }
        "name" => <string: 0x600000c0bab0> { length = 44, contents = "Fetch Developer Disk Image Services Metadata" }
    }
    21: <dictionary: 0x6000026097a0> { count = 2, transaction: 0, voucher = 0x0, contents =
        "featureIdentifier" => <string: 0x600000c0bb40> { length = 37, contents = "com.apple.coredevice.feature.listapps" }
        "name" => <string: 0x600000c0bb70> { length = 17, contents = "List Applications" }
    }
    22: <dictionary: 0x600002609800> { count = 2, transaction: 0, voucher = 0x0, contents =
        "featureIdentifier" => <string: 0x600000c0bc00> { length = 47, contents = "com.apple.coredevice.feature.capturesysdiagnose" }
        "name" => <string: 0x600000c0bc30> { length = 19, contents = "Capture Sysdiagnose" }
    }
    23: <dictionary: 0x600002609860> { count = 2, transaction: 0, voucher = 0x0, contents =
        "featureIdentifier" => <string: 0x600000c0bcc0> { length = 39, contents = "com.apple.coredevice.feature.installapp" }
        "name" => <string: 0x600000c0bcf0> { length = 19, contents = "Install Application" }
    }
    24: <dictionary: 0x6000026098c0> { count = 2, transaction: 0, voucher = 0x0, contents =
        "featureIdentifier" => <string: 0x600000c0bd80> { length = 42, contents = "com.apple.coredevice.feature.getdeviceinfo" }
        "name" => <string: 0x600000c0bdb0> { length = 26, contents = "Fetch Extended Device Info" }
    }
    25: <dictionary: 0x600002609920> { count = 2, transaction: 0, voucher = 0x0, contents =
        "featureIdentifier" => <string: 0x600000c0be40> { length = 45, contents = "com.apple.coredevice.feature.debugserverproxy" }
        "name" => <string: 0x600000c0bea0> { length = 39, contents = "com.apple.internal.dt.remote.debugproxy" }
    }
    26: <dictionary: 0x600002609980> { count = 2, transaction: 0, voucher = 0x0, contents =
        "featureIdentifier" => <string: 0x600000c0bf00> { length = 20, contents = "com.apple.dt.profile" }
        "name" => <string: 0x600000c0bf60> { length = 34, contents = "com.apple.instruments.dtservicehub" }
    }
    27: <dictionary: 0x6000026099e0> { count = 2, transaction: 0, voucher = 0x0, contents =
        "featureIdentifier" => <string: 0x600000c20000> { length = 42, contents = "com.apple.coredevice.feature.fetchappicons" }
        "name" => <string: 0x600000c20030> { length = 23, contents = "Fetch Application Icons" }
    }
    28: <dictionary: 0x600002609a40> { count = 2, transaction: 0, voucher = 0x0, contents =
        "featureIdentifier" => <string: 0x600000c200c0> { length = 45, contents = "com.apple.coredevice.feature.disconnectdevice" }
        "name" => <string: 0x600000c200f0> { length = 22, contents = "Disconnect from Device" }
    }
}

(there's more in this response, mostly device infos)

If those features correspond to the services that we are used to, then pretty much everything has changed 😄

dvdmssmnn commented 1 year ago

The comment above is wrong. I tried to intercept the wrong communication 🤦 There are two connections open devicectl -> CoreDeviceService -> Device and I got the one from devicectl to CoreDeviceService, which only happens on the host, and doesn't talk to the device

jobeylev commented 1 year ago

Hey, I am trying to estimate the impact of this on our organization. Any thoughts as to how long it would take to implement support for iOS 17? Any more details you can share about the challenges involved?

danielpaulus commented 1 year ago

Not much yet, except that I am pretty confident go-ios will support it. I will look into it more in the coming weeks.

Valkhes commented 1 year ago

Could be a great thing to take a look at what pymobiledevice3 is doing, as it seems they managed to work with the new personalized developer disk image : https://github.com/doronz88/pymobiledevice3/issues/471

prncvrm commented 1 year ago

any timelines on this?

krishtoautomate commented 1 year ago

xcrun devicectl help

psych0der commented 1 year ago

@prncvrm can you take it up? Let's do it

danielpaulus commented 7 months ago

ios17 support is now mostly merged to main. Linux support is included. I am working on Windows now and then will make a release soon. If you want to try, ask on Discord for help or look at the makefile in the latest main :-)

krishtoautomate commented 7 months ago

Any idea what this does? com.apple.coredevice.feature.viewdevicescreen

bikee1235 commented 7 months ago

@danielpaulus just take latest pull from master and after building executable i am getting error while taking screenshot

dev@dev-MacBook-Pro go-ios-main % ./go-ios screenshot {"level":"info","msg":"no udid specified using first device in list","time":"2024-02-15T11:12:44+05:30","udid":"75accbfa747805f55f4363dbeef66f8d62d2f05f"} {"level":"warning","msg":"failed to get tunnel info","time":"2024-02-15T11:12:44+05:30","udid":"75accbfa747805f55f4363dbeef66f8d62d2f05f"} {"err":"Could not start service:com.apple.mobile.screenshotr with reason:'InvalidService'. Have you mounted the Developer Image?","level":"fatal","msg":"Starting Screenshotr failed with","time":"2024-02-15T11:12:44+05:30"}

but the same time when we are capturing screenshot from xcode it working

is this fix included in latest release

merih-sakarya commented 4 months ago

I wanted to check whether the issue has been resolved. Could you confirm whether the latest version of the library supports iOS 17?

Thank you!

Valkhes commented 4 months ago

go-ios supports iOS 17 tunnels, but a lot of services are not implemented (screenshoting for exemple)