Archive for June, 2011

iPhone 3GS et iOS 4.3.1 : jailbreak

Thursday, June 9th, 2011

Dans le cadre d’un projet de développement pour iPhone que j’ai initié dans l’école où j’enseigne, j’ai voulu installer sur mon iPhone l’application maison que nous avions développé.

Pendant le développement, j’avais entamé des démarches auprès d’Apple pour bénéficier de leur programme éducation, censé nous permettre d’obtenir leurs outils de développement (Xcode 4) mais surtout de déploiement. Après 6 semaines d’échanges de courriels, Apple s’obstine et refuse de reconnaître notre école.

Pour ne pas abandonner tout le travail de développement qui a déjà été fait, j’ai donc opté pour la seule solution restante à mes yeux : Jailbreaker mon iPhone dans le but d’y installer notre application maison sans subir les contraintes d’Apple et développer notre application avec Xcode 3.

Jailbreaker l’iPhone

Je possède un iPhone 3GS avec l’iOS 4.3.1. J’ai du faire de nombreuses tentatives pour trouver exactement les bons logiciels et la bonne procédure. Mais j’y suis finalement arrivé.

J’ai commencé par cette page : http://www.limera1n.cc/2011/04/redsn0w-096rc9-download-untethered-431.html

Mais attention : contrairement à ce qu’indique le titre, il faut télécharger la version 096rc12 de redsn0w (le lien fourni dans l’article est correct), puis suivre les même étapes que pour la version 096rc9 : http://www.limera1n.cc/2011/04/jailbreak-431-untethered-redsn0w-096rc9.html

Par contre, la procédure ne mentionne pas une étape cruciale : déterminer si l’iPhone possède une nouvelle ou une ancienne bootRom.

Personnellement, j’ai une ancienne bootRom. Le site http://www.iphone4.fr/comment-connaitre-mon-iboot-sur-mac-os-x/ indique comment le déterminer.

À l’issue de cette procédure, l’iPhone est jailbreaké et il est donc possible d’y installer des applications inofficielles.

Toutefois, reste un problème : faire que XCode accepte de transférer une application sans signature conforme sur l’iPhone.

Déployer une application sur l’iPhone

Pour y arriver, j’ai suivi l’excellente procédure décrite sur cette page : http://www.alexwhittemore.com/?p=398. Comme cette procédure est en anglais et qu’elle utilise des outils difficiles d’accès (vi), je reproduis ici une version légèrement adaptée de cette procédure.

Première étape : obtenir une identité signée

Cette étape ne doit être faite qu’une fois pour toutes. Xcode doit être fermé. L’iPhone ne doit pas être branché à l’ordinateur.

Normalement, c’est Apple qui nous fourni une identité signée, mais plus tard dans la procédure, nous allons supprimer le contrôle de signature effectué par Xcode. Une identité auto-signée est donc suffisante. On l’obtient ainsi :

  1. Ouvrir l’application Trousseau d’accès (Applications > Utilitaires > Troussau d'accès)
  2. Créer un nouveau certificat (Trousseau d'accès > Assistant de certification > Créer un certificat...)
  3. Mettre comme nom iPhone Developer. C’est très important d’orthographier correctement ce nom. Choisir une Racine auto-signée et comme type de certificat, choisir Signature de code. Cocher la case Me laisser ignorer les réglages par défaut. Cliquer sur Continuer.

    Valider l’avertissement en cliquant sur Continuer.
  4. Mettre une durée de 3650 jours et cliquer sur Continuer.
  5. Laisser les champs vides, en particulier l’adresse électronique ! Ne pas toucher au champ Nom. Cliquer sur Continuer.
  6. Valider toutes les étapes suivantes, jusqu’à la dernière.

    Le message indiquant que ce certificat n’est pas approuvé est normal.

Deuxième étape : AppSync sur l’iPhone

Il faut ensuite installer l’application AppSync sur l’iPhone jailbreaké. Pour ce faire, suivre les étapes suivantes :

  1. Ouvrir Cydia, choisir l’onglet Gérer. Cliquer sur Sources, puis sur Modifier et enfin Ajouter.
  2. Taper l’adresse http://cydia.hackulo.us. Un avertissement concernant le piratage vous sera affiché. En l’occurence, nous n’allons pas faire de piratage.
  3. Revenir au menu principal de Cydia, choisir l’onglet Recherche. Taper AppSync et installer AppSync for 4.0+.
  4. Certains disent qu’il faut redémarrer l’iPhone. Je n’ai pas eu à le faire.

Troisième étape : modifier Xcode

Là, on commence le gros du boulot : modifier Xcode pour qu’il accepte de transférer un projet iPhone sur notre iPhone jailbreaké.
Cette procédure a été testée avec Xcode v3.2.6.

  1. Démarrer le Terminal. Taper ceci :
  2. cd /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk
    sudo cp SDKSettings.plist SDKSettings.plist.orig
    sudo pico SDKSettings.plist

    Chercher la clé CODE_SIGNING_REQUIRED et changer sa valeur de YES à NO.
    Chercher la clé ENTITLEMENTS_REQUIRED et changer sa valeur de YES à NO.
    Rappel : avec pico, une recherche se fait avec CTRL+W.

  3. Remonter au niveau de la plateforme :
    cd /Developer/Platforms/iPhoneOS.platform/
    sudo cp Info.plist Info.plist.orig
    sudo pico Info.plist

    Cherche la clé CODE_SIGN_CONTEXT_CLASS, qui apparaît deux fois et remplacer chaque fois XCiPhoneOSCodeSignContext par XCCodeSignContext.

  4. Maintenant, il faut modifier le binaire de Xcode !
    cd ~/Desktop
    pico script

    Copier le code suivant dans le script que l’on vient de créer :

    #!/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
    /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

    Sauver et quitter pico. Reste à changer les droits d’accès sur ce nouveau script et à l’exécuter :

    chmode 777 script
    ./script

    Si tout va bien, vous un affichage similaire à ceci apparaîtra :

    231+1 records in
    231+1 records out
    115904 bytes transferred in 0.024132 secs (4802915 bytes/sec)

    Avec cette étape, on a indiqué à Xcode qu’il n’est pas nécessaire de signer le code. Maintenant, il faut lui dire de ne pas signer le code.

  5. Ouvrir un projet Xcode. Dans Xcode, choisir Project > Edit Project Settings. Ensuite, choisir l’onglet Build.
    Faire une recherche des propriétés Code Signing et mettre Don't Code Sign en regard des propriétés Code Signing Identity et Any iOS.
  6. Ensuite, dire à Xcode qu’il faut quand-même signer le code ! On va faire ça avec un script python.
    mkdir /Developer/iphoneentitlements431
    cd /Developer/iphoneentitlements431
    pico gen_entitlements.py

    Coller dans pico le code python suivant (que j’ai obtenu sur le site d’Alex Whittemore) :

    #!/usr/bin/env python
    
    import sys
    import struct
    
    if len(sys.argv) != 3:
    	print "Usage: %s appname dest_file.xcent" % sys.argv[0]
    	sys.exit(-1)
    
    APPNAME = sys.argv[1]
    DEST = sys.argv[2]
    
    if not DEST.endswith('.xml') and not DEST.endswith('.xcent'):
    	print "Dest must be .xml (for ldid) or .xcent (for codesign)"
    	sys.exit(-1)
    
    entitlements = """
    <?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>application-identifier</key>
        <string>%s</string>
        <key>get-task-allow</key>
        <true/>
    </dict>
    </plist>
    """ % APPNAME
    
    f = open(DEST,'w')
    if DEST.endswith('.xcent'):
    	f.write("\xfa\xde\x71\x71")
    	f.write(struct.pack('>L', len(entitlements) + 8))
    f.write(entitlements)
    f.close()

    Sauver et quitter pico. Reste à changer les droit sur ce script python.

    chmod 777 gen_entitlements.py
  7. Le script étant fait, il faudra que Xcode l’utilise. Mais pour l’instant, il faut connecter l’iPhone à l’ordinateur. Au moment de le connecter, Xcode Organizer averti qu’il n’est pas capable d’identifier l’appareil. J’accepte qu’il le scanne. Une processus se met en route. Le laisser terminer. À l’issue de la procédure, une ampoule est verte à côté de l’iPhone.
  8. Cette dernière étape doit être réalisée pour chaque nouveau projet Xcode. Aller dans le menu Project > New Build Phase > New Run Script Build Phase. Coller le script suivant :
    export CODESIGN_ALLOCATE=/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/codesign_allocate
    if [ "${PLATFORM_NAME}" == "iphoneos" ]; then
    /Developer/iphoneentitlements401/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

    Il n’y a rien d’autre à faire !

Problèmes

Au cours de l’utilisation, vous rencontrerez certainement quelques problèmes, plus particulièrement lorsque depuis Xcode, vous allez exécuter votre projet sur l’iPhone.

The program being debugged is not being run

  1. Double cliquer dans l’arborescence du projet sur Targets > nom du projetRun Script.

    Mettre le curseur dans la fenêtre contenant le code, fermer la fenêtre.
  2. Relancer un Build and Run

The host is no longer paired with the device

Ce problème provoque un reboot de l’iPhone ! Il suffit d’attendre que l’iPhone soit de nouveau disponible.