Прошу прощения, что, по-видимому, из iOS 8.3, для получения любого уникального идентификатора вам нужен более высокий уровень доступа, чем обычный пользователь.
Без использования каких-либо вещей, только с помощью частных фреймворков, библиотек и запросов ядра, любой запрос к уникальным идентификаторам возвращает null.
Иллюстрируя:
Попытка использовать IOKit:
void *IOKit = dlopen("/System/Library/Frameworks/IOKit.framework/IOKit", RTLD_NOW);
if (IOKit)
{
mach_port_t *kIOMasterPortDefault = dlsym(IOKit, "kIOMasterPortDefault");
CFMutableDictionaryRef (*IOServiceMatching)(const char *name) = dlsym(IOKit, "IOServiceMatching");
mach_port_t (*IOServiceGetMatchingService)(mach_port_t masterPort, CFDictionaryRef matching) = dlsym(IOKit, "IOServiceGetMatchingService");
CFTypeRef (*IORegistryEntryCreateCFProperty)(mach_port_t entry, CFStringRef key, CFAllocatorRef allocator, uint32_t options) = dlsym(IOKit, "IORegistryEntryCreateCFProperty");
kern_return_t (*IOObjectRelease)(mach_port_t object) = dlsym(IOKit, "IOObjectRelease");
if (kIOMasterPortDefault && IOServiceGetMatchingService && IORegistryEntryCreateCFProperty && IOObjectRelease)
{
mach_port_t platformExpertDevice = IOServiceGetMatchingService(*kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice"));
if (platformExpertDevice)
{
CFTypeRef platformSerialNumber = IORegistryEntryCreateCFProperty(platformExpertDevice, CFSTR("IOPlatformSerialNumber"), kCFAllocatorDefault, 0);
if (platformSerialNumber && CFGetTypeID(platformSerialNumber) == CFStringGetTypeID())
{
serialNumber = [NSString stringWithString:(__bridge NSString *)platformSerialNumber];
CFRelease(platformSerialNumber);
}
IOObjectRelease(platformExpertDevice);
}
}
dlclose(IOKit);
}
терпит неудачу. Причина: IOPlatformSerialNumber
недоступен. Многие другие запросы работают нормально.
Попытка использовать Mach вызовы, чтобы получить сетевые адаптеры, HW идентификаторы:
int mib[6], len;
char *buf;
unsigned char *ptr;
struct if_msghdr *ifm;
struct sockaddr_dl *sdl;
mib[0] = CTL_NET;
mib[1] = AF_ROUTE;
mib[2] = 0;
mib[3] = AF_LINK;
mib[4] = NET_RT_IFLIST;
if ((mib[5] = if_nametoindex("en0")) == 0) {
perror("if_nametoindex error");
exit(2);
}
if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
perror("sysctl 1 error");
exit(3);
}
if ((buf = malloc(len)) == NULL) {
perror("malloc error");
exit(4);
}
if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
perror("sysctl 2 error");
exit(5);
}
ifm = (struct if_msghdr *)buf;
sdl = (struct sockaddr_dl *)(ifm + 1);
ptr = (unsigned char *)LLADDR(sdl);
printf("%02x:%02x:%02x:%02x:%02x:%02x\n", *ptr, *(ptr+1), *(ptr+2),
*(ptr+3), *(ptr+4), *(ptr+5));
терпит неудачу. Причина: возвращает 02:00:00:00:00:00
для любого сетевого адаптера.
Попытка подключения к lockdownd:
void *libHandle = dlopen("/usr/lib/liblockdown.dylib", RTLD_LAZY);
if (libHandle)
{
lockdown_connect = dlsym(libHandle, "lockdown_connect");
lockdown_copy_value = dlsym(libHandle, "lockdown_copy_value");
id connection = lockdown_connect();
NSString *kLockdownDeviceColorKey
NSString *color = lockdown_copy_value(connection, nil, kLockdownDeviceColorKey);
NSLog(@"color = %@", color);
lockdown_disconnect(connection);
dlclose(libHandle);
}
else {
printf("[%s] Unable to open liblockdown.dylib: %s\n",
__FILE__, dlerror());
}
терпит неудачу. Причина: lockdown_connect()
не работает, возвращается null
.
Попытка использовать libMobileGestalt:
void *libHandle = dlopen("/usr/lib/libMobileGestalt.dylib", RTLD_LAZY);
if (libHandle)
{
MGCopyAnswer = dlsym(libHandle, "MGCopyAnswer");
NSString* value = MGCopyAnswer(CFSTR("SerialNumber"));
NSLog(@"Value: %@", value);
CFRelease(value);
}
терпит неудачу. Причина: запросы на получение уникальных идентификаторов null
. Любой другой запрос работает нормально.
Мое предложение - использовать некоторую технику эскалации привилегий, чтобы получить доступ суперпользователя, а затем запустить любой из перечисленных здесь методов, чтобы получить свойство.
Также распространите исследование на liblockdown. Если он доступен на уровне пользователя (с чем-то другим, кроме lockdown_connect), возможно, это будет возможно прочитать эти вещи.
Возможный дубликат [UIDevice uniqueIdentifier Устаревший - Что делать?] (Http://stackoverflow.com/questions/6993325/uidevice-uniqueidentifier-deprecated-what- to-do-now) – Paulw11
Единственный способ получить уникальный идентификатор устройства - через MDM-маршрут - вам нужно установить профиль управления устройством на устройстве, и ваш сервер сможет получить доступ к UDID – Paulw11
@ Paulw11 благодарит за идею, но, к сожалению, это не помогло бы. И наш вопрос не является дубликатом - это все о ** private apis **, а не публичные, в том числе устаревшие. –