We're working on a project with my colleagues which involves using a lot of private and non official code. This is not intended for AppStore use.
The first and only requirement we have is to not use jailbreak.
First of all, UDID
or OpenUDID
or any other solutions don't work here and they're not expected to.
We've done a lot of background research and tests, starting with trying to get the IMEI, ICCID, IMSI and the Serial Number programatically. None of the above methods work with iOS 7 and above without jailbreak.
We've also spent a couple of months to play with IOKit
framework using the famous IOKitBrowser and dumping the whole contents of iOS
internals. Unfortunately, we discovered that with iOS 8.3
it stopped working.
We're talking here not about getting the UDID
or any other "mainstream" thing, but generally speaking we need a way to get
any permanent hardware identifier unique enough to identify a device that would persist in spite of device wipes and amongst different iOS versions
This question is no duplicate to others (no solutions are found here, for example) and is targeting solely private APIs.
Any help would be highly appreciated.
I am unsure of your full intentions but would it be enough to have the app generate and store your own unique ID within the app on installation? Then perhaps have the app send that ID to a server and store the IP it came from. Perhaps also have some logic to have the app phone home every so often so you can store additional IP's if they change. Obviously this is not foolproof but it may be the beginnings of a workaround.
What about this: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIDevice_Class/#//apple_ref/occ/instp/UIDevice/identifierForVendor
Since iOS 6 and current in iOS 8
This meets your requirement of:
This is documented to be unique per device and persistent whether from app store or enterprise delivered.
After some digging, I've found that all private APIs use
libMobileGestalt
for getting any hardware identifiers, which in turn usesIOKit
.MobileGestalt
checks sandbox rules for current pid and looks forcom.apple.private.MobileGestalt.AllowedProtectedKeys
entitlement.See the code below:
As described here, UDID is calculated like this:
MobileGestalt
gets these values viaIOKit
like this:If you try to do it yourself, it will fail because new sandbox rules in iOS 8.3 are very strict and deny access to all hardware identifiers like this:
Possible Solution
It looks like the only way you can get UDID is the following:
Confirmed working solution
Here is an example based on RoutingHTTPServer:
Here are the contents of
udid.mobileconfig
:The profile installation will fail (I didn't bother to implement an expected response, see documentation), but the app will get a correct UDID. And you should also sign the mobileconfig.
You could try accessing
lockdownd
API
directly, vialibMobileGestalt.dylib
.Header here. The basic code to access the UDID should be: (you still need to load the dylib)
taken (&slightly modified) from here.
For further information on
libMobileGestalt
, look here.If this fails you could still try communicating with
lockdownd
via an SSL Socket( see here ), no idea how that works though, but you might figure it out.As you may have noticed though, all stuff on this is years old. Still worth a try i guess.
Actually i don't know this solution is helpful or not. but after removed support of UDID. i have manage Unique device identity following way. with help of
Vendor ID
. Here what we did that.As initial while application will run, i will check out that weather
vendor ID
for specific app isstored in key chain or not
. if it not stored then i will store thatvendor ID
inkey chain
. so second time once my app is going to check again that weather vendor ID for specific app it stored of not in key chain. if stored then bring it from key chain and doing action on same according to requirement.so here alway vendor ID is unique for device.
Here are the steps that we keep uniqueness of device with help of
vendor ID
.Step 1 : Integrate Lockbox in your project. that will help you to
stored/retrived
vendor IDin/from
key chain.Step 2 : Here are the code that perform action of
checking vendor ID
andretrieving vendor ID
from key chain.With help of above steps, you always get uniqueness of device. because key chain is never deleted. it always updated.
Hope this help you...
I'm sorry to say that apparently from iOS 8.3, to get any unique identifier you need a higher access level than normal user.
Without exploiting anything, just with private frameworks, libraries and kernel requests, any request to unique identifiers returns null.
Illustrating:
Trying to use IOKit:
Fails. Reason:
IOPlatformSerialNumber
is not accessible. Many other requests work fine.Trying to use Mach calls to get network adapters HW IDs:
Fails. Reason: Returns
02:00:00:00:00:00
for any network adapter.Trying to connect to lockdownd:
Fails. Reason:
lockdown_connect()
fails, returningnull
.Trying to use libMobileGestalt:
Fails. Reason: requests for unique identifiers return
null
. Any other request works fine.My suggestion is to use some privilege escalation technique to get superuser access, then run any of the methods listed here to get the property.
Also, extend the study on liblockdown. If it's accessible at user-level (with something other than lockdown_connect), it might be possible to read these things.