The iPhone Wiki is no longer updated. Visit this article on The Apple Wiki for current information. |
Difference between revisions of "MobileDevice Library"
DarkMalloc (talk | contribs) |
|||
(51 intermediate revisions by 21 users not shown) | |||
Line 1: | Line 1: | ||
+ | {{float toc|right}} |
||
− | MobileDevice Library is used by [[iTunes]] to transfer data between iPhone and computer over the USB connection. |
||
+ | MobileDevice Library is used by [[iTunes]] to transfer data between iPhone and computer over both USB and WiFi connections. |
||
− | === |
+ | === Windows: iTunesMobileDevice.dll === |
+ | * Location: <code>C:\Program Files\Common Files\Apple\Mobile Device Support\iTunesMobileDevice.dll</code> (<code>Program Files (x86)</code> on 64-bit) |
||
+ | * Supporting CoreFoundation.dll (used for CFStringRef, CFPropertyListRef management) is located in the same dir (when using [[iTunes]] prior 9.0). |
||
+ | * For [[iTunes]] 9.0, the location of CoreFoundation.dll is stored in '''InstallDir''' registry value under '''HKLM\SOFTWARE\Apple Inc.\Apple Application Support''' registry key. |
||
+ | === Mac OS X: MobileDevice.framework === |
||
− | * Location : Location is stored in '''iTunesMobileDeviceDLL''' registry value under '''HKLM\SOFTWARE\Apple Inc.\Apple Mobile Device Support\Shared''' key. Usually - C:\Program Files\Common Files\Apple\Mobile Device Support\bin\iTunesMobileDevice.dll. |
||
+ | * Location: /System/Library/PrivateFrameworks/MobileDevice.framework |
||
+ | * Export command: <code>nm /System/Library/PrivateFrameworks/MobileDevice.framework/Versions/A/MobileDevice</code> |
||
+ | === Library Interfaces === |
||
− | * Supporting CoreFoundation.dll (used for CFStringRef, CFPropertyListRef management) is located in the same dir (when using iTunes prior 9.0). |
||
+ | * [http://www.libimobiledevice.org/ libimobiledevice] (provides the same functionality on GNU/Linux) |
||
+ | * [https://github.com/imkira/mobiledevice mobiledevice] (command line utility for interacting with MobileDevice Framework) |
||
+ | * [https://github.com/samdmarshall/SDMMobileDevice SDMMobileDevice] (OS X framework written in C that can be used interchangeably with Apple's private framework MobileDevice.framework) |
||
+ | * [https://bitbucket.org/tristero/mobiledeviceaccess MobileDeviceAccess] (similar to above, but written in Objective-C) |
||
+ | * [http://samdmarshall.com/media/MobileDevice.h MobileDevice.h] (old reverse engineered header for interfacing with MobileDevice library) |
||
− | * For iTunes 9.0 location of CoreFoundation.dll is stored in '''InstallDir''' registry value under '''HKLM\SOFTWARE\Apple Inc.\Apple Application Support''' key, usually C:\Program Files\Common Files\Apple\Apple Application Support\. CoreFoundation.dll from Mobile Device Support\bin should not be used. |
||
− | ===Mac OSX : MobileDevice.framework=== |
||
+ | === Private Functions === |
||
− | * Location : /System/Library/PrivateFrameworks/MobileDevice.framework |
||
− | * Export command : "nm /System/Library/PrivateFrameworks/MobileDevice.framework/Versions/A/MobileDevice" |
||
+ | ==== Obtaining address ==== |
||
− | ===MobileDevice Header (mobiledevice.h)=== |
||
+ | In order to obtain the address of a usable private function in MobileDevice, you will have to be able to understand x86-64 assembly to reverse engineer it. These methods differ slightly based on platform due to how dynamically linked libraries handle position independent code. |
||
− | + | =====Mac OS X (MobileDevice.framework)===== |
|
+ | A private function is not marked as exported in the mach-o symbol table. This means it cannot be called by simply linking against the library. To call unexported functions, the mach-o symbol table must be stepped through manually to find the offset of a particular function call. Calls can be verified by checking against the offset of the name inside the name table. |
||
+ | =====Windows (MobileDevice.dll)===== |
||
− | <pre> |
||
+ | Unlike OS X's dynamically linkable libraries, Windows dynamic libraries do not support position independent code in the same manner. A private function will not have its name in the exported symbol table, so in a debugger, like GDB, it will show up as part of another function. However, you will know that it is a separate function as a new stack frame is set up. |
||
− | #ifndef MOBILEDEVICE_H |
||
− | #define MOBILEDEVICE_H |
||
− | #define CF_BUILDING_CF_AS_LIB |
||
− | #include <CoreFoundation/CoreFoundation.h> |
||
− | //typedef unsigned int unsigned int; |
||
− | + | === Known Error Codes === |
|
+ | * kAMDSuccess = 0x0 |
||
− | #define MDERR_APPLE_MOBILE (err_system(0x3a)) |
||
+ | * kAMDUndefinedError = 0xe8000001 |
||
− | #define MDERR_IPHONE (err_sub(0)) |
||
+ | * kAMDBadHeaderError = 0xe8000002 |
||
+ | * kAMDNoResourcesError = 0xe8000003 |
||
+ | * kAMDReadError = 0xe8000004 |
||
+ | * kAMDWriteError = 0xe8000005 |
||
+ | * kAMDUnknownPacketError = 0xe8000006 |
||
+ | * kAMDInvalidArgumentError = 0xe8000007 |
||
+ | * kAMDNotFoundError = 0xe8000008 |
||
+ | * kAMDIsDirectoryError = 0xe8000009 |
||
+ | * kAMDPermissionError = 0xe800000a |
||
+ | * kAMDNotConnectedError = 0xe800000b |
||
+ | * kAMDTimeOutError = 0xe800000c |
||
+ | * kAMDOverrunError = 0xe800000d |
||
+ | * kAMDEOFError = 0xe800000e |
||
+ | * kAMDUnsupportedError = 0xe800000f |
||
+ | * kAMDFileExistsError = 0xe8000010 |
||
+ | * kAMDBusyError = 0xe8000011 |
||
+ | * kAMDCryptoError = 0xe8000012 |
||
+ | * kAMDInvalidResponseError = 0xe8000013 |
||
+ | * kAMDMissingKeyError = 0xe8000014 |
||
+ | * kAMDMissingValueError = 0xe8000015 |
||
+ | * kAMDGetProhibitedError = 0xe8000016 |
||
+ | * kAMDSetProhibitedError = 0xe8000017 |
||
+ | * kAMDRemoveProhibitedError = 0xe8000018 |
||
+ | * kAMDImmutableValueError = 0xe8000019 |
||
+ | * kAMDPasswordProtectedError = 0xe800001a |
||
+ | * kAMDMissingHostIDError = 0xe800001b |
||
+ | * kAMDInvalidHostIDError = 0xe800001c |
||
+ | * kAMDSessionActiveError = 0xe800001d |
||
+ | * kAMDSessionInactiveError = 0xe800001e |
||
+ | * kAMDMissingSessionIDError = 0xe800001f |
||
+ | * kAMDInvalidSessionIDError = 0xe8000020 |
||
+ | * kAMDMissingServiceError = 0xe8000021 |
||
+ | * kAMDInvalidServiceError = 0xe8000022 |
||
+ | * kAMDInvalidCheckinError = 0xe8000023 |
||
+ | * kAMDCheckinTimeoutError = 0xe8000024 |
||
+ | * kAMDMissingPairRecordError = 0xe8000025 |
||
+ | * kAMDInvalidActivationRecordError = 0xe8000026 |
||
+ | * kAMDMissingActivationRecordError = 0xe8000027 |
||
+ | * kAMDWrongDroidError = 0xe8000028 |
||
+ | * kAMDSUVerificationError = 0xe8000029 |
||
+ | * kAMDSUPatchError = 0xe800002a |
||
+ | * kAMDSUFirmwareError = 0xe800002b |
||
+ | * kAMDProvisioningProfileNotValid = 0xe800002c |
||
+ | * kAMDSendMessageError = 0xe800002d |
||
+ | * kAMDReceiveMessageError = 0xe800002e |
||
+ | * kAMDMissingOptionsError = 0xe800002f |
||
+ | * kAMDMissingImageTypeError = 0xe8000030 |
||
+ | * kAMDDigestFailedError = 0xe8000031 |
||
+ | * kAMDStartServiceError = 0xe8000032 |
||
+ | * kAMDInvalidDiskImageError = 0xe8000033 |
||
+ | * kAMDMissingDigestError = 0xe8000034 |
||
+ | * kAMDMuxError = 0xe8000035 |
||
+ | * kAMDApplicationAlreadyInstalledError = 0xe8000036 |
||
+ | * kAMDApplicationMoveFailedError = 0xe8000037 |
||
+ | * kAMDApplicationSINFCaptureFailedError = 0xe8000038 |
||
+ | * kAMDApplicationSandboxFailedError = 0xe8000039 |
||
+ | * kAMDApplicationVerificationFailedError = 0xe800003a |
||
+ | * kAMDArchiveDestructionFailedError = 0xe800003b |
||
+ | * kAMDBundleVerificationFailedError = 0xe800003c |
||
+ | * kAMDCarrierBundleCopyFailedError = 0xe800003d |
||
+ | * kAMDCarrierBundleDirectoryCreationFailedError = 0xe800003e |
||
+ | * kAMDCarrierBundleMissingSupportedSIMsError = 0xe800003f |
||
+ | * kAMDCommCenterNotificationFailedError = 0xe8000040 |
||
+ | * kAMDContainerCreationFailedError = 0xe8000041 |
||
+ | * kAMDContainerP0wnFailedError = 0xe8000042 |
||
+ | * kAMDContainerRemovalFailedError = 0xe8000043 |
||
+ | * kAMDEmbeddedProfileInstallFailedError = 0xe8000044 |
||
+ | * kAMDErrorError = 0xe8000045 |
||
+ | * kAMDExecutableTwiddleFailedError = 0xe8000046 |
||
+ | * kAMDExistenceCheckFailedError = 0xe8000047 |
||
+ | * kAMDInstallMapUpdateFailedError = 0xe8000048 |
||
+ | * kAMDManifestCaptureFailedError = 0xe8000049 |
||
+ | * kAMDMapGenerationFailedError = 0xe800004a |
||
+ | * kAMDMissingBundleExecutableError = 0xe800004b |
||
+ | * kAMDMissingBundleIdentifierError = 0xe800004c |
||
+ | * kAMDMissingBundlePathError = 0xe800004d |
||
+ | * kAMDMissingContainerError = 0xe800004e |
||
+ | * kAMDNotificationFailedError = 0xe800004f |
||
+ | * kAMDPackageExtractionFailedError = 0xe8000050 |
||
+ | * kAMDPackageInspectionFailedError = 0xe8000051 |
||
+ | * kAMDPackageMoveFailedError = 0xe8000052 |
||
+ | * kAMDPathConversionFailedError = 0xe8000053 |
||
+ | * kAMDRestoreContainerFailedError = 0xe8000054 |
||
+ | * kAMDSeatbeltProfileRemovalFailedError = 0xe8000055 |
||
+ | * kAMDStageCreationFailedError = 0xe8000056 |
||
+ | * kAMDSymlinkFailedError = 0xe8000057 |
||
+ | * kAMDiTunesArtworkCaptureFailedError = 0xe8000058 |
||
+ | * kAMDiTunesMetadataCaptureFailedError = 0xe8000059 |
||
+ | * kAMDAlreadyArchivedError = 0xe800005a |
||
+ | * kAMDProhibitedBySupervision = 0xe8000083 |
||
+ | For the latest error codes you can look at the pseudo-code of AMDErrorString |
||
− | /* Apple Mobile (AM*) errors */ |
||
− | #define MDERR_OK ERR_SUCCESS |
||
− | #define MDERR_SYSCALL (ERR_MOBILE_DEVICE | 0x01) |
||
− | #define MDERR_OUT_OF_MEMORY (ERR_MOBILE_DEVICE | 0x03) |
||
− | #define MDERR_QUERY_FAILED (ERR_MOBILE_DEVICE | 0x04) |
||
− | #define MDERR_INVALID_ARGUMENT (ERR_MOBILE_DEVICE | 0x0b) |
||
− | #define MDERR_DICT_NOT_LOADED (ERR_MOBILE_DEVICE | 0x25) |
||
− | |||
− | /* Messages passed to device notification callbacks: passed as part of |
||
− | * am_device_notification_callback_info. */ |
||
− | #define ADNCI_MSG_CONNECTED 1 |
||
− | #define ADNCI_MSG_DISCONNECTED 2 |
||
− | #define ADNCI_MSG_UNKNOWN 3 |
||
− | |||
− | typedef struct am_recovery_device am_recovery_device; |
||
− | |||
− | struct am_device_notification_callback_info { |
||
− | struct am_device *dev; /* 0 device */ |
||
− | unsigned int msg; /* 4 one of ADNCI_MSG_* */ |
||
− | } __attribute__ ((packed)); |
||
− | |||
− | /* The type of the device notification callback function. */ |
||
− | typedef void(*am_device_notification_callback)(struct |
||
− | am_device_notification_callback_info *); |
||
− | |||
− | /* The type of the device restore notification callback functions. |
||
− | * TODO: change to correct type. */ |
||
− | typedef void (*am_restore_device_notification_callback)(am_recovery_device *); |
||
− | |||
− | /* This is a CoreFoundation object of class AMRecoveryModeDevice. */ |
||
− | struct am_recovery_device { |
||
− | unsigned char unknown0[8]; /* 0 */ |
||
− | am_restore_device_notification_callback callback; /* 8 */ |
||
− | void *user_info; /* 12 */ |
||
− | unsigned char unknown1[12]; /* 16 */ |
||
− | unsigned int readwrite_pipe; /* 28 */ |
||
− | unsigned char read_pipe; /* 32 */ |
||
− | unsigned char write_ctrl_pipe; /* 33 */ |
||
− | unsigned char read_unknown_pipe; /* 34 */ |
||
− | unsigned char write_file_pipe; /* 35 */ |
||
− | unsigned char write_input_pipe; /* 36 */ |
||
− | } __attribute__ ((packed)); |
||
− | |||
− | struct afc_connection { |
||
− | unsigned int handle; /* 0 */ |
||
− | unsigned int unknown0; /* 4 */ |
||
− | unsigned char unknown1; /* 8 */ |
||
− | unsigned char padding[3]; /* 9 */ |
||
− | unsigned int unknown2; /* 12 */ |
||
− | unsigned int unknown3; /* 16 */ |
||
− | unsigned int unknown4; /* 20 */ |
||
− | unsigned int fs_block_size; /* 24 */ |
||
− | unsigned int sock_block_size; /* 28: always 0x3c */ |
||
− | unsigned int io_timeout; /* 32: from AFCConnectionOpen, usu. 0 */ |
||
− | void *afc_lock; /* 36 */ |
||
− | unsigned int context; /* 40 */ |
||
− | } __attribute__ ((packed)); |
||
− | |||
− | /* A CoreFoundation object of class AMRestoreModeDevice. */ |
||
− | struct am_restore_device { |
||
− | unsigned char unknown[32]; |
||
− | int port; |
||
− | } __attribute__ ((packed)); |
||
− | |||
− | |||
− | /* The type of the _AMDDeviceAttached function. |
||
− | * TODO: change to correct type. */ |
||
− | typedef void *amd_device_attached_callback; |
||
− | |||
− | struct am_device { |
||
− | unsigned char unknown0[16]; /* 0 - zero */ |
||
− | unsigned int device_id; /* 16 */ |
||
− | unsigned int product_id; /* 20 - set to AMD_IPHONE_PRODUCT_ID */ |
||
− | char *serial; /* 24 - set to UDID, Unique Device Identifier */ |
||
− | unsigned int unknown1; /* 28 */ |
||
− | unsigned int unknown2; /* 32 - reference counter, increased by AMDeviceRetain, decreased by AMDeviceRelease*/ |
||
− | unsigned int lockdown_conn; /* 36 */ |
||
− | unsigned char unknown3[8]; /* 40 */ |
||
− | unsigned int unknown4; /* 48 - used to store CriticalSection Handle*/ |
||
− | unsigned char unknown5[24]; /* 52 */ |
||
− | } __attribute__ ((packed)); |
||
− | |||
− | struct am_device_notification { |
||
− | unsigned int unknown0; /* 0 */ |
||
− | unsigned int unknown1; /* 4 */ |
||
− | unsigned int unknown2; /* 8 */ |
||
− | am_device_notification_callback callback; /* 12 */ |
||
− | unsigned int unknown3; /* 16 */ |
||
− | } __attribute__ ((packed)); |
||
− | |||
− | unsigned int AMDeviceNotificationSubscribe(am_device_notification_callback |
||
− | callback, unsigned int unused0, unsigned int unused1, unsigned int |
||
− | dn_unknown3, struct am_device_notification **notification); |
||
− | |||
− | unsigned int AMRestoreRegisterForDeviceNotifications( |
||
− | am_restore_device_notification_callback dfu_connect_callback, |
||
− | am_restore_device_notification_callback recovery_connect_callback, |
||
− | am_restore_device_notification_callback dfu_disconnect_callback, |
||
− | am_restore_device_notification_callback recovery_disconnect_callback, |
||
− | unsigned int unknown0, |
||
− | void *user_info); |
||
− | |||
− | CFMutableDictionaryRef AMRestoreCreateDefaultOptions(CFAllocatorRef allocator); |
||
− | |||
− | unsigned int AMRestoreEnableFileLogging(char *path); |
||
− | unsigned int AMDeviceEnterRecovery(struct am_device *device); |
||
− | |||
− | unsigned int AMDeviceRetain(struct am_device *device); |
||
− | CFStringRef AMDeviceCopyValue(struct am_device *device, CFStringRef domain, CFStringRef cfstring); |
||
− | |||
− | unsigned int AMDeviceStartService(struct am_device *device, CFStringRef service_name, void **handle, int *socket_fd); |
||
− | |||
− | unsigned int AMDPostNotification(int socket, CFStringRef notification, CFStringRef userinfo); |
||
− | unsigned int AMDeviceConnect(struct am_device *device); |
||
− | |||
− | unsigned int AMDShutdownNotificationProxy(int socket); |
||
− | |||
− | unsigned int AMDeviceIsPaired(struct am_device *device); |
||
− | unsigned int AMDevicePair(struct am_device *device); |
||
− | unsigned int AMDeviceValidatePairing(struct am_device *device); |
||
− | unsigned int AMDeviceStartSession(struct am_device *device); |
||
− | |||
− | unsigned int AMRestorePerformDFURestore(struct am_recovery_device *rdev, CFDictionaryRef opts, void *callback, void *user_info); |
||
− | |||
− | int sendCommandToDevice(am_recovery_device *rdev, CFStringRef cfs, int block); |
||
− | int sendFileToDevice(am_recovery_device *rdev, CFStringRef filename); |
||
− | |||
− | #endif |
||
− | </pre> |
||
− | |||
− | ===AFC Connection=== |
||
− | ... |
||
− | |||
− | ===Locking the Device for Sync=== |
||
− | When iTunes sends a new song to the device, the device shows a "Sync in progress" screen and when complete, the Music app on the device re-reads the iTunesDB file so it picks up the new song. |
||
− | |||
− | To get this behaviour, first start the notification service: |
||
− | <pre>SOCKET socket; |
||
− | AMDeviceStartService(dev, CFSTR("com.apple.mobile.notification_proxy"), &socket, NULL);</pre> |
||
− | |||
− | Now we post a notificaton message to signal that we are going to start a sync: |
||
− | <pre>AMDPostNotification(socket, CFSTR("com.apple.itunes-mobdev.syncWillStart"), NULL);</pre> |
||
− | |||
− | Next we open the itunes lock file: |
||
− | <pre>afc_file_ref lockref; |
||
− | AFCFileRefOpen(conn, "/com.apple.itunes.lock_sync", 2, &lockref);</pre> |
||
− | |||
− | Now post a notification to say we are going to lock this file, and try and lock it. |
||
− | If the AFCFileRefLock call fails, pause and repeat. |
||
− | <pre>AMDPostNotification(socket, CFSTR("com.apple.itunes-mobdev.syncLockRequest"), NULL); |
||
− | mach_error_t error = AFCFileRefLock(conn, lockref);</pre> |
||
− | |||
− | When the file is successfully locked, post another notification, and stop the notification service. |
||
− | <pre>AMDPostNotification(socket,CFSTR("com.apple.itunes-mobdev.syncDidStart"), NULL); |
||
− | AMDShutdownNotificationProxy(socket);</pre> |
||
− | |||
− | Now the sync can proceed, so copy your files across and make the changes to the iTunesDB. |
||
− | |||
− | To release the lock, start the notification system again, unlock and close the lock file, and send a sync finished notification message: |
||
− | |||
− | <pre>AFCFileRefUnlock(conn, lockref); |
||
− | AFCFileRefClose(conn, lockref); |
||
− | AMDeviceStartService(dev, CFSTR("com.apple.mobile.notification_proxy"), &socket, NULL); |
||
− | AMDPostNotification(socket, &CFSTR("com.apple.itunes-mobdev.syncDidFinish"), NULL); |
||
− | AMDShutdownNotificationProxy(socket);</pre> |
||
− | |||
− | To handle "Slide to Cancel" and terminate sync when user slides cancel switch, use AMDObserveNotification to subscribe notifications about “com.apple.itunes-client.syncCancelRequest”. Then start listening for notifications (AMDListenForNotifications) until you get “AMDNotificationFaceplant”. |
||
− | When notification got, you should unlock and close lock file handle (don’t sure if you need to post “syncDidFinish” to proxy, seems it doesn’t matter) and terminate sync gracefully. |
||
− | The same notification is also got when you unplug your device, so you should always be ready for errors. |
||
− | |||
− | NOTE: You may find that starting the notification_proxy service once and once only at the start of your app and using the same socket in calls to AMDPostNotification works better. iTunes opens and closes the notification_proxy regularly, but it appears to be a bit flakey when you open/close it all the time. |
||
− | |||
− | ===Private Functions=== |
||
− | |||
− | ====How to find address of privates functions in iTunesMobileDevice.dll or MobileDevice.framework==== |
||
− | |||
− | In order to obtain the address of a usable private function in MobileDevice, you will have to be able to understand x86-64 assembly to reverse engineer it. A private function will not have its name exported in the mach-o symbol table, so in a debugger, like GDB, it will show up as part of another function. However, you will know that it is a separate function as a new stack frame is set up. |
||
− | |||
− | ====Private Function Address List==== |
||
− | |||
− | =====OSX.6 - iTunes 9.0.2(25)===== |
||
− | <pre>unsigned int sendCommandToiBoot(struct am_recovery_device *rdev, CFStringRef command, int u);</pre> |
||
− | Address is obtainable by adding 868(0x364) to the address of AMRecoveryDeviceGetProductType(), a public symbol that you can obtain via nlist() or dlsym(). |
||
− | Address: 0x1000245ea |
||
− | |||
− | Parameters |
||
− | 1. rdev - the device you wish to send the command to. |
||
− | 2. a CFStringRef of the command to send. |
||
− | 3. an integer, whose use is currently unknown, but should be set to 0 to work. |
||
− | |||
− | <pre>unsigned int sendFileToiDevice(struct am_recovery_device *rdev, CFStringRef filename);</pre> |
||
− | Address is obtainable by adding 1763(0x6e3) to the address of AMRecoveryDeviceGetProductType(), a public symbol that you can obtain via nlist() or dlsym(). |
||
− | Address: 0x100024969 |
||
− | |||
− | Parameters |
||
− | 1. rdev - the device you wish to send the file to. |
||
− | 2. a CFStringRef of the path to the file to send. |
||
− | |||
− | |||
− | =====OSX.6 - iTunes 9.0.3(15)===== |
||
− | <pre>unsigned int sendCommandToiBoot(struct am_recovery_device *rdev, CFStringRef command, int u);</pre> |
||
− | Addresss: AMRecoveryDeviceGetProductType() + 0x37f(895); full offset: 0x2a0ed |
||
− | |||
− | <pre>unsigned int sendFileToiDevice(struct am_recovery_device *rdev, CFStringRef filename);</pre> |
||
− | Address: AMRecoveryDeviceGetProductType()+0x6f3(1790); full offset: 0x2a46c |
||
− | |||
− | ===Libraries Implementations=== |
||
− | |||
− | * [http://gojohnnyboi.com/source/afcinstall.cpp afcinstall (command line, os x file install via afc)] |
||
− | * [http://code.google.com/p/iphuc/ iPhuc (Command line utility)] |
||
− | * [http://code.google.com/p/iphucwin32/ iPhuc Win32 (Command line utility)] |
||
− | * [http://code.google.com/p/manzana/ manzana (.Net Library)] |
||
− | * [http://code.google.com/p/independence/source/browse/trunk/libPhoneInteraction/ libPhoneInteraction (C Library)] |
Latest revision as of 13:18, 24 January 2020
MobileDevice Library is used by iTunes to transfer data between iPhone and computer over both USB and WiFi connections.
Windows: iTunesMobileDevice.dll
- Location:
C:\Program Files\Common Files\Apple\Mobile Device Support\iTunesMobileDevice.dll
(Program Files (x86)
on 64-bit) - Supporting CoreFoundation.dll (used for CFStringRef, CFPropertyListRef management) is located in the same dir (when using iTunes prior 9.0).
- For iTunes 9.0, the location of CoreFoundation.dll is stored in InstallDir registry value under HKLM\SOFTWARE\Apple Inc.\Apple Application Support registry key.
Mac OS X: MobileDevice.framework
- Location: /System/Library/PrivateFrameworks/MobileDevice.framework
- Export command:
nm /System/Library/PrivateFrameworks/MobileDevice.framework/Versions/A/MobileDevice
Library Interfaces
- libimobiledevice (provides the same functionality on GNU/Linux)
- mobiledevice (command line utility for interacting with MobileDevice Framework)
- SDMMobileDevice (OS X framework written in C that can be used interchangeably with Apple's private framework MobileDevice.framework)
- MobileDeviceAccess (similar to above, but written in Objective-C)
- MobileDevice.h (old reverse engineered header for interfacing with MobileDevice library)
Private Functions
Obtaining address
In order to obtain the address of a usable private function in MobileDevice, you will have to be able to understand x86-64 assembly to reverse engineer it. These methods differ slightly based on platform due to how dynamically linked libraries handle position independent code.
Mac OS X (MobileDevice.framework)
A private function is not marked as exported in the mach-o symbol table. This means it cannot be called by simply linking against the library. To call unexported functions, the mach-o symbol table must be stepped through manually to find the offset of a particular function call. Calls can be verified by checking against the offset of the name inside the name table.
Windows (MobileDevice.dll)
Unlike OS X's dynamically linkable libraries, Windows dynamic libraries do not support position independent code in the same manner. A private function will not have its name in the exported symbol table, so in a debugger, like GDB, it will show up as part of another function. However, you will know that it is a separate function as a new stack frame is set up.
Known Error Codes
- kAMDSuccess = 0x0
- kAMDUndefinedError = 0xe8000001
- kAMDBadHeaderError = 0xe8000002
- kAMDNoResourcesError = 0xe8000003
- kAMDReadError = 0xe8000004
- kAMDWriteError = 0xe8000005
- kAMDUnknownPacketError = 0xe8000006
- kAMDInvalidArgumentError = 0xe8000007
- kAMDNotFoundError = 0xe8000008
- kAMDIsDirectoryError = 0xe8000009
- kAMDPermissionError = 0xe800000a
- kAMDNotConnectedError = 0xe800000b
- kAMDTimeOutError = 0xe800000c
- kAMDOverrunError = 0xe800000d
- kAMDEOFError = 0xe800000e
- kAMDUnsupportedError = 0xe800000f
- kAMDFileExistsError = 0xe8000010
- kAMDBusyError = 0xe8000011
- kAMDCryptoError = 0xe8000012
- kAMDInvalidResponseError = 0xe8000013
- kAMDMissingKeyError = 0xe8000014
- kAMDMissingValueError = 0xe8000015
- kAMDGetProhibitedError = 0xe8000016
- kAMDSetProhibitedError = 0xe8000017
- kAMDRemoveProhibitedError = 0xe8000018
- kAMDImmutableValueError = 0xe8000019
- kAMDPasswordProtectedError = 0xe800001a
- kAMDMissingHostIDError = 0xe800001b
- kAMDInvalidHostIDError = 0xe800001c
- kAMDSessionActiveError = 0xe800001d
- kAMDSessionInactiveError = 0xe800001e
- kAMDMissingSessionIDError = 0xe800001f
- kAMDInvalidSessionIDError = 0xe8000020
- kAMDMissingServiceError = 0xe8000021
- kAMDInvalidServiceError = 0xe8000022
- kAMDInvalidCheckinError = 0xe8000023
- kAMDCheckinTimeoutError = 0xe8000024
- kAMDMissingPairRecordError = 0xe8000025
- kAMDInvalidActivationRecordError = 0xe8000026
- kAMDMissingActivationRecordError = 0xe8000027
- kAMDWrongDroidError = 0xe8000028
- kAMDSUVerificationError = 0xe8000029
- kAMDSUPatchError = 0xe800002a
- kAMDSUFirmwareError = 0xe800002b
- kAMDProvisioningProfileNotValid = 0xe800002c
- kAMDSendMessageError = 0xe800002d
- kAMDReceiveMessageError = 0xe800002e
- kAMDMissingOptionsError = 0xe800002f
- kAMDMissingImageTypeError = 0xe8000030
- kAMDDigestFailedError = 0xe8000031
- kAMDStartServiceError = 0xe8000032
- kAMDInvalidDiskImageError = 0xe8000033
- kAMDMissingDigestError = 0xe8000034
- kAMDMuxError = 0xe8000035
- kAMDApplicationAlreadyInstalledError = 0xe8000036
- kAMDApplicationMoveFailedError = 0xe8000037
- kAMDApplicationSINFCaptureFailedError = 0xe8000038
- kAMDApplicationSandboxFailedError = 0xe8000039
- kAMDApplicationVerificationFailedError = 0xe800003a
- kAMDArchiveDestructionFailedError = 0xe800003b
- kAMDBundleVerificationFailedError = 0xe800003c
- kAMDCarrierBundleCopyFailedError = 0xe800003d
- kAMDCarrierBundleDirectoryCreationFailedError = 0xe800003e
- kAMDCarrierBundleMissingSupportedSIMsError = 0xe800003f
- kAMDCommCenterNotificationFailedError = 0xe8000040
- kAMDContainerCreationFailedError = 0xe8000041
- kAMDContainerP0wnFailedError = 0xe8000042
- kAMDContainerRemovalFailedError = 0xe8000043
- kAMDEmbeddedProfileInstallFailedError = 0xe8000044
- kAMDErrorError = 0xe8000045
- kAMDExecutableTwiddleFailedError = 0xe8000046
- kAMDExistenceCheckFailedError = 0xe8000047
- kAMDInstallMapUpdateFailedError = 0xe8000048
- kAMDManifestCaptureFailedError = 0xe8000049
- kAMDMapGenerationFailedError = 0xe800004a
- kAMDMissingBundleExecutableError = 0xe800004b
- kAMDMissingBundleIdentifierError = 0xe800004c
- kAMDMissingBundlePathError = 0xe800004d
- kAMDMissingContainerError = 0xe800004e
- kAMDNotificationFailedError = 0xe800004f
- kAMDPackageExtractionFailedError = 0xe8000050
- kAMDPackageInspectionFailedError = 0xe8000051
- kAMDPackageMoveFailedError = 0xe8000052
- kAMDPathConversionFailedError = 0xe8000053
- kAMDRestoreContainerFailedError = 0xe8000054
- kAMDSeatbeltProfileRemovalFailedError = 0xe8000055
- kAMDStageCreationFailedError = 0xe8000056
- kAMDSymlinkFailedError = 0xe8000057
- kAMDiTunesArtworkCaptureFailedError = 0xe8000058
- kAMDiTunesMetadataCaptureFailedError = 0xe8000059
- kAMDAlreadyArchivedError = 0xe800005a
- kAMDProhibitedBySupervision = 0xe8000083
For the latest error codes you can look at the pseudo-code of AMDErrorString