Search code examples
iosobjective-cipcjailbreaktheos

Theos inter-app communication using mach ports


I am trying to send data between an App and a console app (using theos) on iOS 8.

I have tried:

Application:

CFMessagePortRef port = CFMessagePortCreateLocal(kCFAllocatorDefault, CFSTR("co.test"), &message_callback, NULL, NULL);

This works fine. NSLog(@"%@", port) returns:

<CFMessagePort 0x17018bef0 [0x198094f50]>{locked = Maybe, valid = Yes, remote = No, name = co.test, source = 0x0, callout = message_callback (0x1000e979c), context = <CFMessagePort context 0x0>}

However when trying to do the same thing on the console app:

CFMessagePortRef port = CFMessagePortCreateLocal(kCFAllocatorDefault, CFSTR("co.test"), &message_callback, NULL, NULL);

I always get the error:

*** CFMessagePort: bootstrap_register(): failed 1100 (0x44c) 'Permission denied', port = 0xc03, name = 'co.test'

Even though I am using the same com.apple.security.application-groups entitlement for both:

<key>com.apple.security.application-groups</key>
<array>
    <string>co.test</string>
</array>

Can anyone shed any light - maybe the above is a terrible approach and I am missing an easier way to accomplish my goal?

My goal is to be able to pass a NSDictionary between an app running on SpringBoard and a daemon built with theos.

Note: I have no intention of distributing this app on the app store


Solution

  • Application: .......CFSTR("co.test")
    Console App: ... CFSTR("co.test")

    You need to append an additional string to the end of your application group identifier.

    Apple:

    Mach port names must begin with the application group identifier, followed by a period (.), followed by a name of your choosing.

    For example, if your application group’s name is Z123456789.com.example.app-group, you might create a Mach port named Z123456789.com.example.app-group.Port_of_Kobe.

    CFMessagePort and sandboxing

    Another crash seems to occur if you create multiple Message Ports use the same Message Port Name. Perhaps from an app with the same bundle ID or some other situation in which there should only be a single Message Port and one is already running.

    I notice it when I run one version of my macOS app from /Applications/, and another via Xcode.

    *** CFMessagePort: bootstrap_register(): failed 1100 (0x44c) 'Permission denied', port = 0xcd07, name = 'XXXYYYZZZZ.MyAppGroupName'