UPDATE: I should have read Geohot’s driver code earlier, the secrets to USB communication with iPhone in recovery mode is right inside the code. Thanks timschuerewegen’s comment which drives me to read Geohot’s code and it does help. This article seems dumb if you have read Geohot’s code, but at least it shows you how I reverse the code to analyze and learn before I read the actual source iBooter uses to access the device.
UPDATE: I’ve figured out how to handle recovery mode using Apple iBoot USB Driver, Geohot’s driver is a very good starting point to learn for beginners. I’ve written a dirty class to handle it, here’s a snapshot of my test program which uses LibUSB to access Apple iBoot USB Driver:
Source code for is available: HERE (there might be bugs in code)
NOTICE: The GUI uses Raize Component Suite so you will not be able to compile it if you don’t have this component, but it’s easy to write your own GUI using the included unitIUSB class.
— old post follows —
I’m curious about everything I don’t know and always try to learn from other people’s code, this time I turn to iBooter because I want to implement the bi-directional communication facility into iLiberty+. As of the time this article was written, there’s no iBooter source code yet, so I fired up my favorite IDA Pro and took a brief look at what’s inside iBooter.
The program is very small (about 9.5KB) so it’s sort of easy to disassemble, and the flow is straightforward, all operations are based on the LibUSB, this is good because LibUSB has various libraries, even including a BCC import library, so writing a similar function in C++ Builder will not be too difficult.
Later I decided to go further to see how it works, following main(), I soon got to a function which was used to find the recovery device (iPhone), I took a deep look into it, then I found 2 interesting values that I didn’t know: 0×5AC and 0×1280. The following is the flowchart of the function:
usb_device_handle *getRecoveryDeviceHandle()

The program tried to cycle through all devices on all buses to find out the recovery device, the above two values (0×5AC and 0×1280) were used to examine if the device is what we’re looking for, since the values are compared with some data in usb_device, here’s the definition for usb_device:
struct usb_device {
struct usb_device *next, *prev;
char filename[LIBUSB_PATH_MAX];
struct usb_bus *bus;
struct usb_device_descriptor descriptor;
struct usb_config_descriptor *config;
void *dev; /* Darwin support */
unsigned char devnum;
unsigned char num_children;
struct usb_device **children;
};
In the program, the value 0×5AC was compared with value at offset 0×214 which I thought was the low word of dev (because next and prev each occupied 4 bytes, filename occupied 0×200 bytes, bus occupied 4 bytes, decscriptor and config each took 4 bytes, that sums up to 8+0×200+4+8 = 0×214), and value 0×1280 was compared with value at offset 0×216 which I thought was the high word of dev. I quickly checked the LibUSB documentation, no description about this. Header file was not helpful at all, there’s only a comment /* Darwin support */ so I had no idea what it was for, just speculating it’s some kind of signature, but it’s weird to use a pointer for signature purpose.
I sent a quick and dirty question to cmw (the developer of iBooter) trying to get an answer, seemed like the guy’s busy on pwnage thing so I got the same quick and dirty answer: “Just wait for the source, will be available next week”.
UPDATE: cmw has mailed me and confirmed again the source will be released next week and he’s doing cleanup for the code, nice.
Later, I thought maybe I made some mistakes, so I checked it again, this time I figured out what was wrong. The descriptor was not a pointer, it’s a structure, so it occupied more bytes, the offset 0×214 and 0×216 actually falled into the structure usb_device_descriptor, my calculation was wrong. Here’s the definition for usb_device_descriptor:
struct usb_device_descriptor {
unsigned char bLength;
unsigned char bDescriptorType;
unsigned short bcdUSB;
unsigned char bDeviceClass;
unsigned char bDeviceSubClass;
unsigned char bDeviceProtocol;
unsigned char bMaxPacketSize0;
unsigned short idVendor;
unsigned short idProduct;
unsigned short bcdDevice;
unsigned char iManufacturer;
unsigned char iProduct;
unsigned char iSerialNumber;
unsigned char bNumConfigurations;
};
Combined the above 2 structures (struct usb_device and struct usb_device_descriptor), the calculation resulted in:
offset 0x214,0x215 = idVendor (short occupies 2 bytes) offset 0x216,0x217 = idProduct (short occupies 2 bytes)
According to the above analysis, if idVendor is 0×5AC and idProduct is 0×1280 then it’s an iPhone, although I didn’t know if I was correct or not, it looked reasonable.
UPDATE: according to This Link offered by AViegas, 0×5AC does mean Apple, but the 0×1280 (I think its device id for iPhone) is not listed there, maybe iPhone is just too new to be included.
Anyway, before the source is released, I can still learn it from reversing, fortunately the code is not complex compared with other programs. Last, thanks cmw to write such an amazing tool, I’ll say it’s valuable both in functionalities and in education :) I had never written any USB related programs, and this reversing will be a very good starting point for me.
UPDATE: The function analyzed in this article is a typical function to detect and open a designated device (as illustrated in LibUSB’s documentation), it can be reversed to the following C++ code:
#define ID_APPLE 0x5AC #define ID_IPHONE 0x1280 struct usb_dev_handle *GetRecoveryDeviceHandle(void) { struct usb_bus *busses = usb_get_busses(); if (busses) { struct usb_bus *bus; for (bus=busses; bus != NULL; bus=bus->next) { struct usb_device *dev; for (dev=bus->devices; dev != NULL; dev=dev->next) { if (dev->idVendor == ID_APPLE && dev->idProduct == ID_IPHONE) return usb_open(dev); } } } return NULL; }
BTW, idProduct returns different values for recovery mode and normal mode, as shown below:
Recovery mode: idVendor: 0×5AC, idProduct: 0×1280
Normal mode: idVendor: 0×5AC, idProduct: 0×1290


17 Comments
iBooter = libusb + http://iphonejtag.blogspot.com/2008/01/113-unlock-and-linux-driver.html
I like the IDA theme colors very much!
Can you provide it or is it pre-made and somewhere available for download?
Do you know what the reason why so many iphones have no wifi
@idatheme, it’s not a pre-made theme, it’s my customized theme. I don’t know how to export IDA theme, so here’re the snapshots of my color scheme, you may adjust your color accordingly:
Color settings: Here
Arrow settings: Here
Graph settings: Here
@timschuerewegen, Windows also uses that driver ? I think Windows only uses Apple Recovery (iBoot) USB Driver. Geohot developed that driver for Linux. So:
For Windows, iBooter = LibUSB + Apple iBoot USB Driver
For Linux, iBooter = LibUSB + Geohot iPhone Linux Drvier (statically linked)
And iBooter doesn’t access USB Driver directly, it accesses LibUSB, and which in turn accesses USB Driver.
Thanks!
@george, sorry but you’re wrong :)
iBooter (on any platform) = libusb + client code from George Hotz’s iphone linux driver
You don’t need to disassemble iBooter if you know how to use LibUSB (not that difficult) and understand what George Hotz’s client code is doing.
@timschuerewegen, yeah I might be wrong because I didnt even read geohot’s code :) and I was just thinking in a normal sense that a user application should not deal with hardware directly, from you comment it seems like I really need to read the driver code. The reason I need to disassemble iBooter is simply because I have no idea how to use LibUSB at all (as I said I didn’t write any USB code) so I gotta see how it calls LibUSB, and in what sequence etc, that’s my way to learn LibUSB.
George: You either misspelled productID or there is something fishy around here.
mav@marle:~$ lsusb
Bus 005 Device 004: ID 05ac:1290 Apple Computer, Inc.
My iPhone identifies itself as 0×1290, not 0×1280. It’s the 8G one.
@mav, if you read the article carefully, you should know it’s for the recovery mode device :)
Okay, to clarify it: iPhone in recovery mode: 0×1280, iPhone in normal mode: 0×1290.
Okay, now everything’s clear :).
Do you mind to share your C++ Builder Code?
Thank you ;-)
Ben
@Ben, refresh to see the source, hope it helps.
great, thanks!
Also, my touch cant respond to anything!!1 I think it got something bad
why won’t iliberty ” go for it ” to jail break the iphone i have.. it has 0 functionality ..please respond thru my email please … if any one has an answer …. i hope i did not get screwed in purchasing this program …
Hi George, first off thank you for a great programme, it does everything needed with ease and simplicity. I would be writing unless I had a problem, and my problem is the dreaded ‘repair needed’. What’s the problem here and can it be resolved. I am hoping it’s going to be easy. If you can help, I would sincerely appreciate it.
Without wishing to be self congratulatory, it was with great empathy and sympathy that, through our church, we made our donation to Christian Aid, specifically for the flood and earthquake in China. Not everyone spends their time navel gazing and fixated on their own problems.
Again thanks