Developing for a Jailbroken iPhone A to Z (iPhone 3.1.2)

Debugging on device. Freaking finally.
Debugging on device. Freaking finally.

UPDATE: There’s a new method for iOS4 but they’re pretty similar anyway.

So it’s been a while, but now that I’m on break again and have some time, I’m doing a bit of iPhone development again. That means I’m going to need to debug on-device (or at least load my app to it to have fun in the real world with my handiwork). This time, the procedure’s a little different though.

Vital stats:
iPhone OS 3.1.2
Xcode version 3.2.1, 64 bit
Mac OSX 10.6.2 Snow Leopard

Let’s do it.

UPDATE: Corrected a problem with the run script build phase: corrected the directory names for the new version and copied the new phase that doesn’t include “resource_rules.plist.”

UPDATE 2: Somehow I forgot the add an identity step. It’s now #1 below. Sorry guys. Also, while this whole thing should apply to iPhoneOS 4, I’m going to officially text it/repost with 4.01 soon.

The Goal: The goal is the same as the last time and the time before that: we want to be able to click “build and go” in Xcode and get the app we’re working on to load to the phone and start up. More than that, we want to be able to DEBUG on the thing!

Abstract: Our methodology is slightly different this time around. This time we’re going to tell Xcode that it doesn’t need to codesign for iPhoneOS targets, then we’re going to tell it don’t codesign for iPhoneOS targets, then we’re going to tell it, well, actually, codesign but do it using our script, not your built in method.

The Process:

    1. UPDATE: You actually have to do this first. Most of you didn’t have a problem, since you had to do it in previous guides, but some people have gotten stuck here because I somehow managed to leave this out entirely. Sorry: You will need a signing identity. We’ll break the check such that it doesn’t have to be an official ADC one, so you can make your own using this guide from apple (coral). What you are doing in this step is creating a “Self-Signing Identity.” Note that you should name the identity “iPhone Developer” EXACTLY to avoid having to change a bunch of the steps below.
    2. Make some Plist adjustments, starting with SDKSettings.plist:
      cd /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.1.2.sdk
      cp SDKSettings.plist SDKSettings.plist.orig
      vi SDKSettings.plist

      Find
      <key>CODE_SIGNING_REQUIRED</key>
      <string>YES</string>

      and change YES to NO
      then find
      <key>ENTITLEMENTS_REQUIRED</key>
      <string>YES</string>
      and change YES to NO again.
    3. Now, move on to the platform Info.plist
      cd /Developer/Platforms/iPhoneOS.platform/
      cp Info.plist Info.plist.orig
      vi Info.plist

      Three times, the following appears:
      <key>CODE_SIGN_CONTEXT_CLASS</key>
      <string>XCiPhoneOSCodeSignContext</string>

      Find each occurrence by, in vi, typing the “/” key and CODE_SIGN_CONTEXT (typing / will open a “find” box at the bottom of the window)
      Replace the
      <string>XCiPhoneOSCodeSignContext</string> with
      <string>XCCodeSignContext</string>
    4. And now the real bad boy, some binary patching of Xcode:
      cd ~/Desktop
      vi script

      hit the “i” key and copy/paste:
      #!/bin/bash
      cd /Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Plug-ins/iPhoneOS\ Build\ System\ Support.xcplugin/Contents/MacOS/
      dd if=iPhoneOS\ Build\ System\ Support of=working bs=500 count=255
      printf "\xc3\x26\x00\x00" >> working
      dd if=iPhoneOS\ Build\ System\ Support of=working bs=1 skip=127504 seek=127504
      /bin/mv -n iPhoneOS\ Build\ System\ Support iPhoneOS\ Build\ System\ Support.original
      /bin/mv working iPhoneOS\ Build\ System\ Support
      chmod a+x iPhoneOS\ Build\ System\ Support

      type the keys, in order: “:” “x” “enter”
      chmod 777 script
      ./script

      If it works right, you should see something like
      255+0 records in
      255+0 records out
      127500 bytes transferred in 0.020355 secs (6263821 bytes/sec)
      189216+0 records in
      189216+0 records out
      189216 bytes transferred in 1.200354 secs (157633 bytes/sec)

At this point, you’re done telling Xcode it doesn’t need to codesign. Now, we tell it don’t codesign:

  1. With a new project open and ready to go (presumably you want to debug this one, though once you change these settings once, they’ll persist from project to project) open Project>Edit Project Settings (from the menu).
    Find “Code Signing Identity” and its child “Any iPhoneOS Device” in the list, and set both to the entry “don’t code sign”

    Screen shot 2010-01-11 at 1.05.42 AM
    Should look like this

    Now you’ve told Xcode “don’t codesign”

  2. The final step is to tell Xcode “well, actually you should codesign.”
    mkdir /Developer/iphoneentitlements312
    cd /Developer/iphoneentitlements312
    curl -O http://www.alexwhittemore.com/iphone/gen_entitlements.txt
    mv gen_entitlements.txt gen_entitlements.py
    chmod 777 gen_entitlements.py

Now you’re good to go! But there’s just one last thing. You have to do this last part for every new project you make. Go to the menu Project > New Build Phase > New Run Script Build Phase. In the window, copy/paste this:

export CODESIGN_ALLOCATE=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/codesign_allocate
export CODESIGN_ALLOCATE=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/codesign_allocate
if [ "${PLATFORM_NAME}" == "iphoneos" ]; then
/Developer/iphoneentitlements312/gen_entitlements.py "my.company.${PROJECT_NAME}" "${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}/${PROJECT_NAME}.xcent";
codesign -f -s "iPhone Developer" --entitlements "${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}/${PROJECT_NAME}.xcent" "${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}/"
fi

That will call the script you just downloaded in step 5 to sign our app with a fake signature. This is important only for debugging. If you do build and go otherwise (in debug build mode) the app will load onto the phone, and will launch and run manually just fine. However, if the debugger tries to launch it then attach to the process (as when build and go is clicked), the app will segfault and die, causing the error
Error from debugger: The program being debugged is not being run

Perhaps the most confusing part about this error is that build and go works fine up until that point WITHOUT disabling regular code signature! If you sign with a fake identity like we used to in the previous tutorials, everything installs fine, but the legit CODESIGN generated signatures cause the segfault, whereas the gen_entitlements.py ones don’t. To further confuse, the regular CODESIGN in this version of Xcode happens last in the build process, wheras it used to be that the custom run script phase happened last before. Meaning we have to kill legit codesigning or it wipes out our fake codesigning. All one monster headache.

But that should do it. Take all those steps and you should be home free for JBDev without paying $99.

Oh right, except the one last (critical) part. You have to have a jailbroken iPhone, and it has to have Installd Patch installed! That part’s critical. You can find Installd Patch in the iphone.org.hk repo at http://iphone.org.hk/apt, if you don’t have it installed.

CREDITS: Once again, credit for this process goes to various posters in this forum thread at iphonedevsdk.com. All of these steps are there somewhere, it just took a while to re piece them together in the right combination.

152 Comments

  1. October 20, 2012

    Why don’t I get a ‘Developer’ folder in my root D:

Leave a Reply

Your email address will not be published. Required fields are marked *