2010年10月11日 星期一

spirit @ iphone JB case study

有 JB 過 iphone 的人,應該對 spirit 不陌生. 底下就針對 spirit 的 JB flow 做簡易的分析. 在之前的 post IPhone Case Study 有大概介紹過, 如何用 libimobiledevice 來 access iphone 的 file system, 可參考 iphone wiki 是如何使用 MobileDevice. flow charts step1. find top flow
    idevice_get_device_list() //透過'usblib'取得 idevice(iphone) 的位置
    memset()                  //建立個 mem space 給 idevice
    memcpy()                  
    idevice_device_list_free()//free device list
    idevice_new()             //建立 idevice
    time()                    //建立 time stamp
    send_files_thread()       //把 dylib 放到 (idevice)iphone 上
    restore_thread()          //同時 backup (idevice) 的資料
    idevice_free()            //free idevice
step 2. call 'idevice_get_device_list()' @ libimobiledevice 會去 call 'usbmuxd' lib 來取得 dev_list
idevice_error_t idevice_get_device_list(char ***devices, int *count)
{
...
 if (usbmuxd_get_device_list(&dev_list) < 0) {
                debug_info("ERROR: usbmuxd is not running!\n", __func__);
                return IDEVICE_E_NO_DEVICE;
        }
...

        for (i = 0; dev_list[i].handle > 0; i++) {
                newlist = realloc(*devices, sizeof(char*) * (newcount+1));
                newlist[newcount++] = strdup(dev_list[i].uuid);
                *devices = newlist;
        }

}
usbmux為 iphone 跟 pc 間的主要橋樑,流程可參考 usbmuxd 內的 README, 從流程中大概可以知道 usbmuxed 會建立起一組 tcp (ssl) 的連線. 利用這個 channel 來做 synchronous iphone and pc 的動作. 而 channel 間彼此是用 XML Message @ Mac OS X 的 format 來溝通.利用 plist @ python 的 lib 當 XML parser, 把上層的 command 跟底層 Transport layer 的 info 做溝通.
0. iTunes opens a connection to usbmuxd and asks it for device notifications
1. User inserts phone into computer
2. usbmuxd notices the phone and pings it with a version packet
3. phone replies
4. usbmuxd now considers the phone to be connected and tells iTunes
5. iTunes opens another separate connection to usbmuxd and asks it to connect
   to, say, the afc port on the device
6. usbmuxd sends a pseudo-TCP SYN packet to the phone
7. the phone's kernel driver receives the SYN packet and itself opens a
   TCP connection to localhost on the afc port
8. the phone replies with a pseudo-TCP SYN/ACK indicating that the port is open
   and the connection can proceed
7. usbmuxd sends a final ACK to the phone
8. usbmuxd replies to iTunes with a "connection successful" message
9. any data that iTunes writes to the usbmuxd socket from now on is forwarded,
   through pseudo-TCP, through USB, back into a more regular TCP connection to
   localhost, to the afc daemon on the phone, and vice versa
 plist_t n = plist_dict_get_item(props, "DeviceID");
             plist_get_uint_val(n, &val);
             dev->device_id = (uint32_t)val;
//建立到上層的 dev struct 中
  
         n = plist_dict_get_item(props, "ProductID");
         n = plist_dict_get_item(props, "SerialNumber");
         n = plist_dict_get_item(props, "LocationID");

//取得 DeviceID, ProductID...後,利用 SSL 產生 private key 建立加密的socket 連線
step 3. 把 dylib 透過底層的link 加載到 idevice(iphone)的 file system 上. 結論 Level 1. usblib usb connect Level 2. usbmuxd socket connect Level 3. libimobiledevic application/usr space ps: 如果你很懶的話,可以直接用 ubuntu 提供好的 package + source code Refs: iphone wiki libimobiledevic

沒有留言:

張貼留言