How To Make An iLiberty+ / iLibertyX Payload (Revised)

NOTICE: Contents subject to change.

UPDATE: Revised to include the new format for the latest iLiberty+ version.

NOTICE: New payload header is not compatible with old versions (prior 1.3.0) of iLiberty+. If you have made your own payloads for old version iLiberty+, you may have to change the header slightly to use it on new iLiberty+ version, but normally the script body doesn’t need to change.

With the release of iLiberty+ (Windows) and iLibertyX (OS X), iPhone hacking has become a really easy thing. With iLiberty+‘s open structure, it’s pretty easy to implement customized functions into it. This article explains in detail the payload technique used in iLiberty+. NOTE: iLiberty+ and iLibertyX comply to the same payload calling conventions, so the payload written for iLiberty+ also works on iLibertyX.

What Is A Payload

A payload is a package which does a specific job. A payload can do many things to your iPhone, e.g. jailbreak, activate, unlock, system tuning, issue fixing, etc. In iLiberty+, a payload consists of two parts:

1. A payload script
2. A payload archive

The payload script is vital, it’s a must for a payload, the archive is optional. Both the script and the archive pack (if there is) must be put into the payload folder under the iLiberty+ application folder.

For most of the work, an archive is required. For example, to install the BSD Subsystem, you have to have the archive downloaded from its original site. However, in some cases, there’ll be no archive. For example, to fix some 3rd party application issues on 1.1.3, all you have to do is only to create a symbolic link, no need to create any file.

How Payloads Are Put On Device

When you have chosen some payloads to execute, iLiberty+ will pack them into a single ZIP archive and upload it to iPhone before ramdisk boot. In pass 2, the master script will extract the archive into user’s Media folder, after extraction, the Media folder has the following structure:

    +- bin
    +- iLiberty_Signature
    +- payload/
    +- payload/
    +- payload/
    +- payload/

The bin folder contains a minimal set of utilities that iLiberty+ requires. The is the main script that calls each and every payload script in alphabetical order. The iLiberty_Signature is a footprint to help script determine the payload location. Please remember the above structure, knowing the payload location and structure will help you write your own payload.

Payload Script Naming

The script name does not need to follow any rules. But since the scripts are called one by one in their alphebetical order, so normally payload scripts are prefixed by a 2-digit number (range from 00 to 99). Because some special payload needs to be run before others, we have used the following rules in our payloads:

00 to 09 for important payloads that normally require some priviliges, activation, unlock, etc important payloads all fall into this range. For example, activation is normally the first thing to do, so it’s called 00Activate.

On the other hand, 3rd party payloads are just add-ons to iPhone system softwares, so they have the lowerest order, we would like to use 90 to 99 for them.

In order to make several payloads can be done in correct order, we have arranged some important payloads in this order:

00 – Activation, Baseband erase/reflash
01 – Bootloader upgrade/downgrade
02 – Unlock
10 – Patches
87 – Cydia
88 – Installer
89 – BSD
90 – 99 Apps

The above arrangement ensures when multiple payloads are checked, they can be executed in a reasonable manner. For example, suppose we want to downgrade our bootloader to 3.9, then unlock it with AnySIM. From the above order, we know the bootloader will be downgraded first, when it’s done, the unlock will follow, and it’s just the correct order. If we don’t follow the above order, i.e. the unlock comes before bootloader downgrade, then it’ll fail.

Of course you don’t have to follow the above rules, but knowing the rule is good, because it allows you to give a correct script name to your payload. Let’s say we have a very kewl payload and we want it to be the very first payload to execute, we can name it:

And it will be first executed. Similarly, if we want to let a script run last, then name it to:

This will make it the last payload to execute.

Payload Script Header

The new payload script header is not compatible with old versions of iLiberty+, so this section is devided into two parts.

New format (for iLiberty+ version 1.3.0 and later)

iLiberty+‘s payload script must comply to some conventions in order to be detected by the iLiberty+ application executable. The script must contains a header that describes things like the payload name, the archive, etc. The script header is in the following format:

# Id:      similar to bundleIdentifier
# Name:    name of the payload
# Author:  author of payload
# Version: payload version
# Script:  link to payload script
# Pack:    link to payload archive (can be empty if there's no zip archive needed)
# URL:     link to author's site
# Desc:    payload description line #1, you may
#          seperate descriptions into several lines
#          without problem

The first line indicates the shell the script uses, normally it’s /bin/sh, but there’s no problem using others (e.g. /usr/bin/python as long as it’s installed). Other lines are pretty self-descriptive. If there’s no contents for a field, just leave the filed name there, like this:

# Pack:

There’s one thing needs to be mentioned, the Desc field must be the last field in header, it can contain multile lines, it ends in an blank link or an empty comment line. So all the following formats are correct:

Example 1:
# Desc: This is a single line description

Example 2:
# Desc: This description contains 2 lines
#         and it ends with an empty comment

Example 3:
# Desc: This description ends with a blank line

We’ll see a real example, the following script header is from a bundled script:

# Id:      com.zjlotto.iLiberty.Unlock
# Name:    Unlock 03.14.08_G - 04.04.05_G
# Author:  George Zhu
# Version: 1.1
# Script:
# Pack:
# URL:
# Desc:    This payload works on both bootloader 3.9 and 4.6, for bootloader
#          4.6 it will change baseband to 04.02.13_G after unlock.

The above is the unlock payload script header, you can see it’s pretty easy understand it.

Old format (for iLiberty+ version prior 1.3.0)

Old format is slightly simpler, it is in the following format:

# Name: name of the payload
# Pack: archive name (can be empty if there's no zip archive needed)
# URL: link to download the archive (can be empty if there's no zip archive needed)
# Desc: payload description line #1
#       description continues to line #2
#       the last line #3

NOTICE: Due to the different meaning of Pack and URL in new and old versions of iLiberty+, the new payload is not compatible with old iLiberty+ versions.

A real example:

# Name: OpenSSH 4.6p1-2
# Pack:
# URL:
# Desc: OpenSSH Package

From the header we know, the payload is named OpenSSH 4.6p1-2, it requires an archive pack named, the archive pack can be downloaded from

Payload Script Body

Following the script header, the script body begins. This is the real script you would like to execute on iPhone, you may write it in any way you prefer, but there are some points need to be considered:

Minimal BSD Tool Set

A newly jailbroken/activated iPhone doesn’t have BSD Subsystem installed, iLiberty+ has copied a very limited tool set onto phone. The utilities are packed in the, when being extracted, they are put into the bin folder under user’s (mobile or root) Media folder. Here’s the list:


You should avoid modifying by yourself because any further update may change this file and wipe out your modifications. If you need some special utilities that have not included in the, please include them into your payload archive, in a sub-folder /bin. As an example, please check an archive.

Internal Functions

An internal function script named is copied to /bin2. Your script should source it to get the basic environment setup correctly (e.g. PATH, DEBUG, etc). So the following line should be put at the very beginning of the script (after the header):

. /bin2/ (deprecated)

After sourcing it, the following environment variables are set:

SIGNATURE   - a signature file
PL          - payload folder name
PL_DIR      - full path to payload folder
AFC_DIR     - full path to user's media folder
USER_DIR    - full path to user's home directory
OPTIONS     - contains user selected options, mainly for
DEBUG       - 1 = on which logs all output, sent from GUI
DEBUG_DELAY - time (in seconds) to delay for debug, sent from GUI
DEBUG_LOG   - debug log file name

There’re some internal functions defined in the

Syntax: GetFirmwareVersion var_name

Syntax: GetBasebandVersion var_name default_version

Syntax: GetBootloaderVersion var_name

Syntax: GetEnvironment hasBSD hasInstaller

The functions return the result into the variable you defined while calling the function. Here’s an example:


GetFirmwareVersion var_fw_version
if [ ${var_fw_version} != "1.1.3" ]; then
    echo "Error: not version 1.1.3"
    exit 1

GetBasebandVersion var_bb_version
if [ ${var_bb_version} != "04.03.13_G" ]; then
    echo "Error: not baseband 04.03.13"
    exit 1

GetBasebandVersion var_bb_version DEFAULT_VALUE
if [ ${var_bb_version} = "DEFAULT_VALUE" ]; then
    echo "Error: unable to determine baseband version"
    exit 1

GetBootloaderVersion var_bl_version
if [ ${var_bl_version} != "3.9_M3S2" ]; then
    echo "Error: not bootloader 3.9"
    exit 1

GetEnvironment hasBSD hasInstaller
if [ ${hasBSD} = "BSD" ]; then
    echo "Found BSD"
elif [ ${hasBSD} = "CYDIA" ]; then
    echo "Found Cydia"
    echo "No BSD/Cydia installed"
if [ ${hasInstaller} = "INSTALLER" ]; then
    echo "Found Installer"
elif [ ${hasInstaller} = "CYDIA" ]; then
    echo "Found Cydia"
    echo "Installer not found"

You script may call these internal functions in case your payload is for a specific firmware/baseband/bootloader version.


Here are some examples which may help you further understand the payload script.

Example 1: Activate 1.1.4

Activativation requires to patch /usr/lib/lockdownd, so the script to activate 1.1.4 is mainly replacing the old lockdownd with a patched one. First, the header, we have described it earlier, so we’ll just skip it:

Script header for latest iLiberty+

# Id:      com.zjlotto.iLiberty.Activate
# Name:    Activate 1.1.4
# Author:  George Zhu
# Version: 1.0
# Script:
# Pack:
# URL:
# Desc:    Activates iPhone firmware 1.1.4 with a patched lockdownd.

Script header for old iLiberty+ versions (prior 1.3.0)

# Name: Activate 1.1.4
# Pack:
# URL:
# Desc: Activate iPhone firmware 1.1.4 with a patched lockdownd.

Now the main script body, we first invoke the internal functions to examine the firmware version, if firmware version is not 1.1.4, we pause for a few seconds so that user can know what happens:

echo "Activating 1.1.4..."
GetFirmwareVersion fw_version
if [ ${fw_version} != "1.1.4" ]; then
	echo "Wrong firmware version: ${fw_version}"
	sleep 5
	exit 1

When version check succeeds, we can now extract our patched lockdownd to replace the old one, we also added some error detection and permission fix to make it fail-safe:

unzip -q -o ${PL_DIR}/ -d /usr/libexec/
if [ $? -ne 0 ]; then
	sleep 10
chmod 555 /usr/libexec/lockdownd

Last, we remove our archive:

rm -f ${PL_DIR}/
echo "Done"

NOTE: Although master script will clean up the entire payload folder at the end of execution, it’s a good idea to clean up our own package before leaving, because if there’re many payloads to install, the payload folder may occupy quite some disk spaces.

Example 2: General Fix for 3rd Party Apps

This is an example about how to write a script-only payload. Notice, in script-only payload, the PACK and URL fields in script header must be left blank.

Since many 3rd party application issue can be solved by adding a symbolic link as below:

For latest iLiberty+ (version 1.3.0 and above)

# Id: com.zjlotto.iLiberty.Fix3rdPartyApp
# Name: General Fix for 3rd Party App Issues
# Author: <author>
# Version: 1.0
# Script:
# Pack:
# URL:
# Desc: This tiny payload creates a symbolic link for libgcc_s.1.dylib,
# this dynamic library is required by most 3rd party application.
echo "Adding libgcc_s.1.dylib symbolic link..."
GetFirmwareVersion fw_ver
if [ ${fw_ver} != "1.1.3" -a ${fw_ver} != "1.1.4" ]; then
    echo "Lower versions need no fix"
    sleep 5
    exit 0
mkdir -p /usr/local/arm-apple-darwin/lib
ln -s /usr/lib/libgcc_s.1.dylib /usr/local/arm-apple-darwin/lib/.

For old iLiberty+ versions (prior 1.3.0)

/usr/local/arm-apple-darwin/lib/libgcc_s.1.dylib -> /usr/lib/libgcc_s.1.dylib

We can make a simple payload to fix it for us:

# Name: General Fix for 3rd Party App Issues
# Pack:
# URL:
# Desc: This tiny payload creates a symbolic link for libgcc_s.1.dylib,
# this dynamic library is required by most 3rd party application.
echo "Adding libgcc_s.1.dylib symbolic link..."
GetFirmwareVersion fw_ver
if [ ${fw_ver} != "1.1.3" -a ${fw_ver} != "1.1.4" ]; then
    echo "Lower versions need no fix"
    sleep 5
    exit 0
mkdir -p /usr/local/arm-apple-darwin/lib
ln -s /usr/lib/libgcc_s.1.dylib /usr/local/arm-apple-darwin/lib/.

NOTE: If there’s anything missing or not clearly explained in the article, please let me know. Comments are welcome.


  1. TK
    Posted March 27, 2008 at 12:03 am | Permalink

    I wonder if you could include a descriptive tutorial in just a simple jailbreak with adding the necessary payload, IE: Installer, OpenSSH, BSD Subsystem.
    There are many people who use AT&T as their providers, thus we only need to jailbreak our phones and add installer..
    My hat is off to you and your team on such an innovative tool for us who use Iphone. You for sure will be getting my donation in the sum of $100.00 when it is released today, great work~!

  2. Posted March 27, 2008 at 12:23 am | Permalink

    If u just need the jailbreak and Installer, then just check the Installer (jailbreak is checked by default), then click Go.

  3. TK
    Posted March 27, 2008 at 12:39 am | Permalink

    Downloading it now George… If you need a faster server for apps let me know… Thanks for the prompt reply..

  4. TK
    Posted March 27, 2008 at 12:42 am | Permalink

    George what apps does the installer install on it by default? If i need BSD SubSytem and SSH do it need to customize a payload?
    Also do i need to be diconnected from itunes before i install? I am on 1.1.4 otb.. Do i just turn on iphone, connect to dock, then install?

  5. TK
    Posted March 27, 2008 at 12:43 am | Permalink

    Download failed, unexpected end of archive…

  6. Posted March 27, 2008 at 12:45 am | Permalink

    Server too busy, over 1000 concurrent downloads.

  7. Liu Bin
    Posted March 27, 2008 at 1:27 am | Permalink

    Advanced–Available Payloads(9)–Unlock for 3.14/04.01/04.02/04.03/04/05 最后的04/05应该是04.05 请大侠改下

  8. TK
    Posted March 27, 2008 at 2:53 am | Permalink

    Well all went fine for a bit, now i have lost my WiFi access, “unable to join Linksys”.
    It use to work all the time before.. I have a 16GB Iphone with 1.1.4OTB, i did Jailbreak only with Installer.. Any ideas why i lost my WiFi?

  9. david ross
    Posted March 27, 2008 at 1:01 pm | Permalink

    I am trying to recover voicemails and text files in my Iphone, the screen is cracked and white lighted but I can see the music,photo itunes control files with touchcopy and ziphone. Is there a way to get at all the files in this thing and maybe run undelete software also? The phone now shows up in my vista network and sharing center as “home” it asks for user name and password, I have tried root /dottie and alpine but can’t get it open. I am new to this and kinda bouncing around trying things. Some stable guidance would sure be appreciated

  10. M.Klinge
    Posted March 28, 2008 at 2:48 am | Permalink

    Hi there :)

    First of all thx for a all that time and efford you and the other guys has put into making this great piece of software :)

    As I would like to be able to make my own payloads I have a few, prolly very noobish questions, but here we go:

    When making the .sh file what editor do you recomend me to use?

    If I use a link to a given software, lets say OpenSSH, would I also need to include the into the payload or will iLiberty+ download it directly from the url given in the header?

    Will every payload be installed in the media folder unless told otherwise, or do I need to specify where to install the payload, openSSH for instance?

    Hopefully you will have time to help me abit on those questions :)


  11. Posted March 28, 2008 at 3:19 am | Permalink

    Hi George

    iLibertyX is perfect. I have created a couple of payloads but something seems to be wrong:

    2008-03-27 17:04:23 +0100 Phase 2 starting
    2008-03-27 17:04:23 +0100 Unpacking payload…
    2008-03-27 17:04:27 +0100 /var/mobile/Media/payload/ no such file or directory: /bin2/
    2008-03-27 17:04:27 +0100 Installing
    2008-03-27 17:04:27 +0100 ———————
    2008-03-27 17:04:27 +0100 /var/mobile/Media/payload/ command not found: GetFirmwareVersion
    2008-03-27 17:04:27 +0100 /var/mobile/Media/payload/ parse error: condition expected: !=

    Somehow /bin2/ cannot be called and hence the defined functions do not work.

    I have tried with some of the payloads from your site, but get the same error. Commands like unzip etc. woks.

    I am on mac os x 10.4, iPhone 1.1.4 3.9BL


  12. Posted March 28, 2008 at 3:05 pm | Permalink


    iLiberty+ and iLiberyX are developed by different people, we had communication problems in the past (we’re on different timezone and I had problem accessing the repo) so the two versions might not be exactly the same. The is included in (under /bin folder), which is extracted and moved to /bin2 on iLiberty+, but it might be moved to another place in iLibertyX (or might be missing). Please use the following syntax to source the


    The $FUNCTIONS is set before calling payload so every payload is able to use it.

    Another workaround is to check where is moved or missing:

    1. Check if there’s a file /bin/ in
    2. Check the / in to find out where it copies to

    When you have found the location of, you may change accordingly in your script.

    We’re working on the update and will try to make iLiberty+ and iLiberyX work in the exactly same way.

  13. Posted March 29, 2008 at 3:58 am | Permalink


    It works with . $FUNCTIONS


  14. Flavio
    Posted April 10, 2008 at 9:23 pm | Permalink

    ’m trying to fix the WiFi problem. I’ve downloaded the payload pack made by I’m on a mac, I’m using Safari.
    The pack is in .tar and I’ve decompressed it. Now I have the 4 .zip files with its .sh files. The problem is that I can’t to select them from iLiberty ( Apps Tab > Select a custom payload manually) . It appears grayed, as if the files is not supported. Sorry for my english. Thank you

  15. Ariel
    Posted April 13, 2008 at 1:50 pm | Permalink

    Same problem as Flavio. How do I get the payload pack to be recognized by iLiberty+? I’ve read your instructions several times, buy no help.
    Thanks in advance!

  16. Posted April 13, 2008 at 2:29 pm | Permalink

    @Ariel, check This Link, Script/Pack URL parsing bug.

  17. Cassian
    Posted April 15, 2008 at 6:00 am | Permalink

    after hours of debugging my custom payloads (none of them ever worked) it seems that iLiberty cant handle payload scripts edited with wordpad editor.
    I just edited one char in a comment line of the youtube fix which comes with iLiberty, and this is the log after saving with Wordpad and executing it with iLiberty:

    2008-04-14 21:43:55 +0200 iLiberty+ – Pass 2 Starting
    2008-04-14 21:43:55 +0200 Unpacking main payload…
    2008-04-14 21:44:00 +0200
    2008-04-14 21:44:00 +0200 /var/mobile/Media/payload/ command not found: ^M
    2008-04-14 21:44:00 +0200 /var/mobile/Media/payload/ no such file or directory: /bin2/^M
    2008-04-14 21:44:01 +0200 /var/mobile/Media/payload/ command not found: ^M
    2008-04-14 21:44:01 +0200 YouTube Fix
    2008-04-14 21:44:01 +0200 ———–
    2008-04-14 21:44:01 +0200 /var/mobile/Media/payload/ command not found: ^M
    2008-04-14 21:44:01 +0200 /var/mobile/Media/payload/ command not found: ^M
    2008-04-14 21:44:01 +0200 Extracting package…
    2008-04-14 21:44:01 +0200 /var/mobile/Media/payload/ parse error near `\n’
    2008-04-14 21:44:01 +0200
    2008-04-14 21:44:01 +0200 Housekeeping…Done
    2008-04-14 21:44:02 +0200 iLiberty+ – Pass 2 Completed
    I would call that a bug.:)
    Is there a editor for Windows I can use?

  18. Posted April 15, 2008 at 9:16 am | Permalink

    @Cassian, hmm…that’s an interesting thought. Do you think Unix is totally a bug because it can’t understand the end-of-line characters in Windows’ text files ?

    There’re some editors that can handle Unix text files correctly, I’ve been using Vi for Windows, sometimes I also use UltraEdit and you may find many others through Google.

  19. cassian
    Posted April 15, 2008 at 1:52 pm | Permalink

    ok so it looks like I’m the lonely windows fool jumped in this trap..:)
    dont want to argue about this just thought it could be helpful to mention theres a problem in using windows editors .

  20. Quench
    Posted April 29, 2008 at 4:31 am | Permalink

    I have iLiberty+ 1.51. I am trying to write a custom payload to install the Term-VT100 app. (I think this should be included as a standard option BTW)
    I have created a script with the required header fields. Saved it as but I can not select it from liberty+ as a custom payload. I rename it to .lby still not allowed.
    I note that the .lby files in the payloads folder are not text files they are binary files.
    So how do I get my script recognised?
    Can I reference the script and pack on the mac filesystem without having to put them on my website ?


  21. Andre1C
    Posted May 6, 2008 at 8:00 am | Permalink

    Hi, George!

    Wrote custom payloads for v1.2 – all was working. After installing v1.3 was changed header as you described, but iLiberty wont install my payload’s.
    I have 1 uestion if iLiberty check script adress from the header and compares local script with this one n link?


  22. Posted May 6, 2008 at 2:17 pm | Permalink

    @Andre1C, good question :) iLiberty+ examines local payloads in the following steps:

    1. Get all *.sh files in payload directory, and put them into a payload list
    2. Check a *.sh file to get essential info
    3. If the Pack field is not empty, check if the pack file (filename extracted from URL) exists in payload directory, if it does not exist, then remove it from payload list
    4. Loop to step 2 till all scripts processed
    5. Output the final payload list

    From the above procedure, if you want a payload to be recognized by iLiberty+, it must be:

    1. A single .sh script in payload directory, the Pack field in .sh script is empty


    2. A .sh script and an archive described in Pack field both exist in payload directory

  23. Andre1C
    Posted May 6, 2008 at 8:37 pm | Permalink

    No, the problem was that iLiberty+ 1.3 recognize my ayloads, but won’t install them on iPhone.
    So, the question is if the script file isn’t loaded on http server and header strng that describes script adress looks like “http:\\” iLiberty+ 1.3 will not add ths payload to ramdisk?


  24. Quench
    Posted May 7, 2008 at 2:04 am | Permalink

    Why isn’t this recognised!!!?
    I have a file which starts

    # Id: 1
    # Name: Terminal App
    # Author: Stuart Gall
    # Version: 0.1
    # Script: /
    # Pack: /
    # URL: http://none.none
    # Desc: Install Terminal app

    When I try to select custom payload manually the file is greyed out. (ILiberty + 1.51)

  25. Andre1C
    Posted May 9, 2008 at 6:30 am | Permalink

    George, I really need your help.
    People asking me why my payloads won’t be installed under iLiberty+ 1.3 (they are recognized but not installed).
    If you have an ICQ or MSN account please email me your contact info.


  26. Posted May 9, 2008 at 8:41 am | Permalink

    @Andre1C, if iL+ recognizes your payload, it will load it if you check it, same algo.

  27. Slake
    Posted May 16, 2008 at 7:53 pm | Permalink

    About the editors, you can use SciTE. Its free and light.
    Free download from

  28. noty
    Posted January 15, 2009 at 2:05 pm | Permalink

    is there a way to make a payload (bundle) for yellowsn0w 0.9.6 so i can include in my custom firmware using pwnagetool without installing cydia or installer?


  29. Posted January 20, 2009 at 1:42 am | Permalink

    @noty, nope, iLiberty+ is for1.x only.