Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS Daemon app will not start (Jailbreak) - how to debug?

I'm building a daemon app for a jailbroken iPhone and followed the guidelines as described in several questions and answers here on stackoverflow and ofcourse Chris Alvares' webpage at http://chrisalvares.com/blog/38/creating-an-iphone-daemon-part-4/

Xcode and the project are patched by Jailcoder to make it run on my device.

One of the posts on here stated that nowadays it is no longer needed to use the open toolchain template. Uploading the app to the /Applications dir and adding a plist file in /System/Library/LaunchDaemons should be sufficient.

I have performed the above steps but the daemon is not started, or at least not running when i check. In the device logs that are available in Xcode organizer the name of the app or its bundle id are not to be found anywhere. I would at least expect an error with a reason why it won't start.

The contents of the plist file copied to /System/Library/LaunchDaemons:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
        <key>Disabled</key>
        <false/>
        <key>Label</key>
        <string>dmn.NoUIDaemon.plist</string>
        <key>OnDemand</key>
        <false/>
        <key>ProgramArguments</key>
        <array>
            <string>/Applications/NoUIDaemon.app/NoUIDaemon</string>
            <string></string>
            <string></string>
        </array>
        <key>StandardErrorPath</key>
        <string>/dev/null</string>
    </dict>
    </plist>

Question: is there a way to debug why it won't start the daemon app? Or have i maybe missed a step besides uploading the app to /Applications and adding the plist file to the LaunchDaemons dir ?

EDIT:

Contents of my main routine:

int main(int argc, char *argv[])
{
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

Error when launching /Applications/NoUIDaemon.app/NoUIDaemon :

R-iPod:/ root# /Applications/NoUIDaemon.app/NoUIDaemon
-sh: /Applications/NoUIDaemon.app/NoUIDaemon: Bad CPU type in executable

Note that the app does work without a problem when i run it on my device from Xcode.

Eventhough the daemon cannot be started manually, the answers to Nate's questions:

1) The plist file in LaunchDaemons is indeed named dmn.NoUIDaemon.plist

2) I made the 'mistake' of forgetting the .plist part in the Label contents, so i have tried it with both values, with and without .plist at the end, no difference ofcourse.

3) I have rebooted the device after installing both the app and the plist file using the reboot command

4) I've made sure all the permissions are the same (0775)

5) Will try this when the Bad CPU issue is resolved and it still doesn't work

FINAL EDIT:

To hide your Daemon app icon on the springboard, add the following to the Info.plist in your .app:

<key>SBAppTags</key>
<array>
    <string>hidden</string>
</array>
like image 988
Ronald Avatar asked Nov 12 '12 14:11

Ronald


1 Answers

As I said in my comment, first try to make sure your daemon executable is runnable:

  1. login to your device as root, via ssh
  2. execute the command /Applications/NoUIDameon.app/NoUIDaemon at the command line
  3. check to see if it's running with ps -Aef | grep NoUIDaemon

If it's not running, I would check to make sure that your build process is fake code-signing the NoUIDaemon executable. Jailbroken phones don't require a valid signature, but they still do require a signature. Also, if it doesn't run (or stay running), it might help for you to post the code from your daemon's main program (e.g. main.m):

int main(int argc, char *argv[]) {
   // what's in here?
}

If that does work, and it runs when you start it manually (but not automatically), then check:

  1. is the plist file above named dmn.NoUIDaemon.plist?
  2. I think this is actually an error in Chris's blog, but the Label value in your plist should be <string>dmn.NoUIDaemon</string>, not <string>dmn.NoUIDaemon.plist</string>. I don't think this would prevent your daemon from running, I think it's just being consistent with the naming convention of system launch daemons.
  3. I don't think just installing the plist file in /System/Library/LaunchDaemons is enough to start the daemon. You probably need to either reboot the phone, or manually launch the daemon with launchctl load -w /System/Library/LaunchDaemons/dmn.NoUIDaemon.plist
  4. check to make sure the file permissions and ownership of your dmn.NoUIDaemon.plist are the same as the other launch daemon plists in /System/Library/LaunchDaemons.
  5. I'm not sure if this is necessary, but I think the name of the daemon (the Label and the name of the plist file) are supposed to match the bundle ID specified in your NoUIDaemon-Info.plist file. So, the Info.plist should have:
    <key>CFBundleExecutable</key>
    <string>NoUIDaemon</string>
    <key>CFBundleIdentifier</key>
    <string>dmn.${PRODUCT_NAME:rfc1034identifier}</string>

or

    <key>CFBundleExecutable</key>
    <string>NoUIDaemon</string>
    <key>CFBundleIdentifier</key>
    <string>dmn.NoUIDaemon</string>

Update:

Also, I don't think your daemon's main program should have a call to UIApplicationMain. It's not supposed to be a UIApplication. It's supposed to be a background process, right? If you look on Page 1 of Chris's blog, it shows an example. Here's an example from one of mine:

int main(int argc, char *argv[]) {
   @autoreleasepool {
      SignalMonitor* daemon = [[SignalMonitor alloc] init];

      // start a timer so that the process does not exit.
      NSTimer* timer = [[NSTimer alloc] initWithFireDate: [NSDate date]
                                                interval: 1.0
                                                  target: daemon
                                                selector: @selector(setup:)
                                                userInfo: nil
                                                 repeats: NO];

      NSRunLoop* runLoop = [NSRunLoop currentRunLoop];
      [runLoop addTimer: timer forMode: NSDefaultRunLoopMode];
      [runLoop run];
   }

   return 0;
}

Also, here's a copy of my daemon's plist file (Info.plist), with your daemon name in it:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>CFBundleDevelopmentRegion</key>
        <string>English</string>
        <key>CFBundleExecutable</key>
        <string>NoUIDaemon</string>
        <key>CFBundleIdentifier</key>
        <string>dmn.NoUIDaemon</string>
        <key>CFBundleInfoDictionaryVersion</key>
        <string>6.0</string>
        <key>CFBundleName</key>
        <string>${PRODUCT_NAME}</string>
        <key>CFBundlePackageType</key>
        <string>APPL</string>
        <key>CFBundleShortVersionString</key>
        <string>1.0</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
        <string>1.0-0</string>
        <key>LSRequiresIPhoneOS</key>
        <true/>
        <key>LSApplicationCategoryType</key>
        <string></string>
</dict>
</plist>
like image 99
Nate Avatar answered Sep 28 '22 07:09

Nate