verificar puedo privacidad digitos desbloquear contraseña con como codigo cambiar bloqueado apple app ios iphone cocoa-touch iphone-privateapi iokit

ios - privacidad - no puedo verificar app en iphone



Identificador de dispositivo único privado en iOS (8)

¿Qué pasa con esto ?: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIDevice_Class/#//apple_ref/occ/instp/UIDevice/identifierForVendor

Una cadena alfanumérica que identifica de forma única un dispositivo para el proveedor de la aplicación. (solo lectura)

El valor de esta propiedad es el mismo para las aplicaciones que provienen del mismo proveedor que se ejecuta en el mismo dispositivo. Se devuelve un valor diferente para las aplicaciones en el mismo dispositivo que provienen de diferentes proveedores y para las aplicaciones en diferentes dispositivos, independientemente del proveedor.

Desde iOS 6 y actual en iOS 8

Esto cumple con su requisito de:

cualquier identificador de hardware permanente lo suficientemente único como para identificar un dispositivo que persistiría a pesar de las toallitas del dispositivo y entre las diferentes versiones de iOS

Esto se documenta como único por dispositivo y persistente, ya sea desde la tienda de aplicaciones o la empresa entregada.

Normalmente, el proveedor está determinado por los datos proporcionados por la App Store. Si la aplicación no se instaló desde la tienda de aplicaciones (como aplicaciones empresariales y aplicaciones aún en desarrollo), entonces se calcula un identificador de proveedor en función de la ID del paquete de la aplicación. Se supone que el ID del paquete está en formato de DNS inverso.

Estamos trabajando en un proyecto con mis colegas, que implica el uso de muchos códigos privados y no oficiales. Esto no es para el uso de AppStore.

El primer y único requisito que tenemos es no usar jailbreak.

En primer lugar, UDID o OpenUDID o cualquier otra solución no funcionan aquí y no se espera que lo hagan .

Hemos realizado una gran cantidad de investigaciones y pruebas de antecedentes, comenzando con el intento de obtener el IMEI , ICCID, IMSI y el Número de serie programáticamente. Ninguno de los métodos anteriores funciona con iOS 7 y superior sin jailbreak.

También hemos pasado un par de meses para jugar con el framework IOKit utilizando el famoso IOKitBrowser y descargando todo el contenido de las iOS internas de iOS . Desafortunadamente, descubrimos que con iOS 8.3 dejó de funcionar.

Estamos hablando aquí no acerca de obtener el UDID o cualquier otra cosa "convencional", pero en general , necesitamos una forma de obtener

cualquier identificador de hardware permanente lo suficientemente único como para identificar un dispositivo que persistiría a pesar de borrados de dispositivos y entre diferentes versiones de iOS

Esta pregunta no está duplicada para otros ( no se encuentran soluciones aquí , por ejemplo) y está dirigida solo a API privadas .

Cualquier ayuda sería muy apreciada.


¿Se le permite preguntar al usuario por su MSISDN? (números de teléfono internacionales) Como lo que WhatsApp está haciendo cuando inicias sesión con ellos por primera vez al confirmar con un código de SMS enviado al usuario msisdn. Si conoce el MSISDN de sus usuarios, puede mantenerlos en la base de datos de sus servidores y solo permitir que un msisdn de la lista blanca se registre y use sus servicios. Si desea estar más seguro, puede enviar los mensajes de texto con más frecuencia; sin embargo, hay una forma de entender el cambio de la tarjeta SIM (esto es para t-mobile y uso de Europa, supongo) desde la aplicación para que el usuario no pueda engañarlo. enviando SMS para un MSISDN diferente y luego cambia a su tarjeta sim real MSISDN.

Los MSISDN son únicos en todo el mundo y están protegidos por los operadores de telecomunicaciones, así que supongo que esta solución es estrictamente segura. ¿Qué dices? buena suerte

actualización: de hecho al leer su pregunta cuidadosamente otra vez, creo que no desea que el usuario inicie sesión con ninguna información, ¿verdad? si ese es el caso, perdón por la respuesta incorrecta: /

nota: ¿por qué no puedes usar

[[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString]

el identificador de publicidad es exclusivo del dispositivo y permanente, supongo. No sé si puedes usarlo privadamente, aunque ...


Después de algunas excavaciones, descubrí que todas las API privadas usan libMobileGestalt para obtener identificadores de hardware, que a su vez usan IOKit . MobileGestalt comprueba las reglas de sandbox para el pid actual y busca la titularidad de com.apple.private.MobileGestalt.AllowedProtectedKeys .

Vea el código a continuación:

signed int __fastcall sub_2EB8803C(int a1, int a2, int a3, int a4) { int v4; // r5@1 int v5; // r4@1 int v6; // r10@1 int v7; // r2@1 int v8; // r0@3 int v9; // r6@3 int v10; // r11@4 int v11; // r4@4 int v12; // r0@5 signed int v13; // r6@6 int v14; // r6@7 char *v15; // r0@7 int v16; // r1@7 int v17; // r1@14 int v18; // r3@16 int v19; // r5@16 signed int v20; // r1@17 int v21; // r0@17 __CFString *v22; // r2@19 int v23; // r4@27 __CFString *v24; // r2@27 int v26; // [sp+8h] [bp-428h]@1 char v27; // [sp+10h] [bp-420h]@1 int v28; // [sp+414h] [bp-1Ch]@1 v26 = a2; v4 = a1; v5 = a3; v6 = a4; v28 = __stack_chk_guard; memset(&v27, 0, 0x401u); v7 = *(_DWORD *)(dword_32260254 + 260); if ( !v7 ) v7 = sub_2EB8047C(65, 2); v8 = ((int (__fastcall *)(int, _DWORD))v7)(v4, "com.apple.private.MobileGestalt.AllowedProtectedKeys"); v9 = v8; if ( !v8 ) goto LABEL_12; v10 = v5; v11 = CFGetTypeID(v8); if ( v11 != CFArrayGetTypeID() ) { v14 = (int)"/SourceCache/MobileGestalt/MobileGestalt-297.1.14/MobileGestalt.c"; v15 = rindex("/SourceCache/MobileGestalt/MobileGestalt-297.1.14/MobileGestalt.c", 47); v16 = *(_DWORD *)(dword_32260254 + 288); if ( v15 ) v14 = (int)(v15 + 1); if ( !v16 ) v16 = sub_2EB8047C(72, 2); ((void (__fastcall *)(int))v16)(v4); _MGLog(3, v14); LABEL_12: v13 = 0; goto LABEL_13; } v12 = CFArrayGetCount(v9); if ( CFArrayContainsValue(v9, 0, v12, v26) ) v13 = 1; else v13 = sub_2EB7F948(v9, v26, v10, "MGCopyAnswer"); LABEL_13: if ( !v6 ) goto LABEL_30; v17 = *(_DWORD *)(dword_32260254 + 288); if ( !v17 ) v17 = sub_2EB8047C(72, 2); v19 = ((int (__fastcall *)(int))v17)(v4); if ( v13 != 1 ) { v21 = *(_DWORD *)v6; if ( *(_DWORD *)v6 ) { v22 = CFSTR(" and IS NOT appropriately entitled"); goto LABEL_22; } v23 = CFStringCreateMutable(0, 0); *(_DWORD *)v6 = v23; sub_2EB7F644(v19, &v27); v24 = CFSTR("pid %d (%s) IS NOT appropriately entitled to fetch %@"); goto LABEL_29; } v20 = MGGetBoolAnswer((int)CFSTR("LBJfwOEzExRxzlAnSuI7eg")); v21 = *(_DWORD *)v6; if ( v20 == 1 ) { if ( v21 ) { v22 = CFSTR(" but IS appropriately entitled; all is good in the world"); LABEL_22: CFStringAppendFormat(v21, 0, v22, v18); goto LABEL_30; } v23 = CFStringCreateMutable(0, 0); *(_DWORD *)v6 = v23; sub_2EB7F644(v19, &v27); v24 = CFSTR("pid %d (%s) IS appropriately entitled to fetch %@; all is good in the world"); LABEL_29: CFStringAppendFormat(v23, 0, v24, v19); goto LABEL_30; } if ( v21 ) { CFRelease(v21); *(_DWORD *)v6 = 0; } *(_DWORD *)v6 = 0; LABEL_30: if ( __stack_chk_guard != v28 ) __stack_chk_fail(__stack_chk_guard - v28); return v13; } signed int __fastcall sub_2EB88228(int a1, int a2, int a3) { int v3; // r4@1 int v4; // r10@1 int v5; // r0@1 int v6; // r6@1 int v7; // r5@5 signed int result; // r0@6 char v9; // [sp+8h] [bp-420h]@5 int v10; // [sp+40Ch] [bp-1Ch]@1 v3 = a1; v4 = a3; v10 = __stack_chk_guard; v5 = sandbox_check(); v6 = v5; if ( v5 ) v5 = 1; if ( v4 && v5 == 1 ) { memset(&v9, 0, 0x401u); v7 = CFStringCreateMutable(0, 0); *(_DWORD *)v4 = v7; sub_2EB7F644(v3, &v9); CFStringAppendFormat(v7, 0, CFSTR("pid %d (%s) does not have sandbox access for %@"), v3); } result = 0; if ( !v6 ) result = 1; if ( __stack_chk_guard != v10 ) __stack_chk_fail(result); return result; }

Como se describe here , UDID se calcula así:

UDID = SHA1(serial + ECID + wifiMac + bluetoothMac)

MobileGestalt obtiene estos valores a través de IOKit esta manera:

CFMutableDictionaryRef service = IOServiceMatching("IOPlatformExpertDevice"); io_service_t ioservice = IOServiceGetMatchingService(kIOMasterPortDefault, service); CFTypeRef entry = IORegistryEntryCreateCFProperty(ioservice, CFSTR("IOPlatformSerialNumber"), kCFAllocatorDefault, 0); const UInt8 * data = CFDataGetBytePtr(entry); CFStringRef string = CFStringCreateWithCString(kCFAllocatorDefault, data, kCFStringEncodingUTF8);

Si intenta hacerlo usted mismo, fallará porque las nuevas reglas de sandbox en iOS 8.3 son muy estrictas y niegan el acceso a todos los identificadores de hardware como este:

deny iokit-get-properties IOPlatformSerialNumber

Solución posible

Parece que la única forma en que puede obtener UDID es la siguiente:

  1. Inicie un servidor web dentro de la aplicación con dos páginas: una debería devolver un perfil MobileConfiguration especialmente diseñado y otra debería recopilar UDID. Más información here , here y here .
  2. Abre la primera página en Mobile Safari desde el interior de la aplicación y lo redirige a Settings.app solicitando la instalación del perfil de configuración. Después de instalar el perfil, UDID se envía a la segunda página web y puede acceder a él desde dentro de la aplicación. (Settings.app tiene todos los derechos necesarios y diferentes reglas de sandbox).

Solución de trabajo confirmada

Aquí hay un ejemplo basado en RoutingHTTPServer :

import UIKit import RoutingHTTPServer @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var bgTask = UIBackgroundTaskInvalid let server = HTTPServer() func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { application.openURL(NSURL(string: "http://localhost:55555")!) return true } func applicationDidEnterBackground(application: UIApplication) { bgTask = application.beginBackgroundTaskWithExpirationHandler() { dispatch_async(dispatch_get_main_queue()) {[unowned self] in application.endBackgroundTask(self.bgTask) self.bgTask = UIBackgroundTaskInvalid } } } } class HTTPServer: RoutingHTTPServer { override init() { super.init() setPort(55555) handleMethod("GET", withPath: "/") { $1.setHeader("Content-Type", value: "application/x-apple-aspen-config") $1.respondWithData(NSData(contentsOfFile: NSBundle.mainBundle().pathForResource("udid", ofType: "mobileconfig")!)!) } handleMethod("POST", withPath: "/") { let raw = NSString(data:$0.body(), encoding:NSISOLatin1StringEncoding) as! String let plistString = raw.substringWithRange(Range(start: raw.rangeOfString("<?xml")!.startIndex,end: raw.rangeOfString("</plist>")!.endIndex)) let plist = NSPropertyListSerialization.propertyListWithData(plistString.dataUsingEncoding(NSISOLatin1StringEncoding)!, options: .allZeros, format: nil, error: nil) as! [String:String] let udid = plist["UDID"]! println(udid) // Here is your UDID! $1.statusCode = 200 $1.respondWithString("see https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/iPhoneOTAConfiguration/ConfigurationProfileExamples/ConfigurationProfileExamples.html") } start(nil) } }

Aquí están los contenidos de udid.mobileconfig :

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>PayloadContent</key> <dict> <key>URL</key> <string>http://localhost:55555</string> <key>DeviceAttributes</key> <array> <string>IMEI</string> <string>UDID</string> <string>PRODUCT</string> <string>VERSION</string> <string>SERIAL</string> </array> </dict> <key>PayloadOrganization</key> <string>udid</string> <key>PayloadDisplayName</key> <string>Get Your UDID</string> <key>PayloadVersion</key> <integer>1</integer> <key>PayloadUUID</key> <string>9CF421B3-9853-9999-BC8A-982CBD3C907C</string> <key>PayloadIdentifier</key> <string>udid</string> <key>PayloadDescription</key> <string>Install this temporary profile to find and display your current device''s UDID. It is automatically removed from device right after you get your UDID.</string> <key>PayloadType</key> <string>Profile Service</string> </dict> </plist>

La instalación del perfil fallará (no me molesté en implementar una respuesta esperada, consulte la documentation ), pero la aplicación obtendrá un UDID correcto. Y también debe firmar el dispositivo móvil .


En realidad no sé si esta solución es útil o no. pero después de eliminar el soporte de UDID. He gestionado la identidad única del dispositivo de la siguiente manera. con la ayuda de la Vendor ID del Vendor ID . Aquí lo que hicimos eso.

Como inicial, mientras se ejecuta la aplicación, verificaré que la vendor ID tiempo para la aplicación específica esté stored in key chain or not . si no se almacena, almacenaré esa vendor ID en la key chain . así que por segunda vez una vez que mi aplicación vaya a verificar nuevamente que la ID del proveedor del tiempo para la aplicación específica que almacenó no esté en la cadena de llaves. si está almacenado, tráigalo del llavero y haga lo mismo de acuerdo con el requisito. so here alway vendor ID is unique for device.

Estos son los pasos que mantenemos la singularidad del dispositivo con la ayuda de la vendor ID del vendor ID .

Paso 1 : Integrar Lockbox en tu proyecto. eso le ayudará a stored/retrived identificación del proveedor in/from llavero.

Paso 2 : Aquí está el código que realiza la acción de checking vendor ID y retrieving vendor ID del retrieving vendor ID de la cadena de claves.

-(NSString*)getidentifierForVendor{ NSString *aStrExisting = [Lockbox stringForKey:[[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleIdentifierKey]]; if (aStrExisting == Nil) { NSString *aVendorID = [[[UIDevice currentDevice]identifierForVendor]UUIDString]; aStrExisting=aVendorID; [Lockbox setString:aVendorID forKey:[[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleIdentifierKey]]; return aVendorID; }else{ return aStrExisting; }

Con la ayuda de los pasos anteriores, siempre obtiene la exclusividad del dispositivo. porque el llavero nunca se elimina. siempre actualizado.

Espero que esto te ayude ...


Lamento decir que, aparentemente desde iOS 8.3, para obtener un identificador único necesita un nivel de acceso superior al del usuario normal.

Sin explotar nada, solo con marcos privados, bibliotecas y solicitudes de núcleo, cualquier solicitud a identificadores únicos devuelve nulo.

Ilustrando:

Intentando usar 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); }

Falla Motivo: IOPlatformSerialNumber no es accesible. Muchas otras solicitudes funcionan bien.

Intentando usar las llamadas de Mach para obtener adaptadores de red ID de 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));

Falla Motivo: Devuelve 02:00:00:00:00:00 para cualquier adaptador de red.

Tratando de conectarse a 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()); }

Falla Motivo: lockdown_connect() falla y devuelve null .

Intentando usar 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); }

Falla Motivo: las solicitudes de identificadores únicos devuelven null . Cualquier otra solicitud funciona bien.

Mi sugerencia es utilizar alguna técnica de escalamiento de privilegios para obtener acceso de superusuario, luego ejecutar cualquiera de los métodos enumerados aquí para obtener la propiedad.

Además, extienda el estudio sobre liblockdown. Si es accesible a nivel de usuario (con algo distinto de lockdown_connect), es posible que lea estas cosas.


No estoy seguro de sus intenciones completas, pero ¿sería suficiente que la aplicación genere y almacene su propia ID única dentro de la aplicación en la instalación? Entonces quizás la aplicación envíe ese ID a un servidor y almacene la IP de la que proviene. Quizás también tenga algo de lógica tener el teléfono de la aplicación en casa cada cierto tiempo para que pueda almacenar direcciones IP adicionales si cambian. Obviamente, esto no es infalible, pero puede ser el comienzo de una solución.


No sé si las soluciones comerciales son de su interés, pero visite http://www.appsflyer.com

No estoy afiliado a ellos, pero usamos su SDK en mi empleador anterior. Tienen un dispositivo de tecnología de huella digital que funciona.

Nota: si el usuario restablece el IDFA, entonces AppsFlyer lo verá como un nuevo dispositivo. Sin embargo, y ha pasado un tiempo así que no puedo recordar, creo que puede usar su SDK, no usar AdSupport.framework, y entonces no tendrán el IDFA disponible para ellos. Así que supongo que las huellas dactilares de sus dispositivos pueden funcionar.

También tienen competidores, búsqueda de huellas dactilares de dispositivos. Echa un vistazo a Yozio y branch.io, ambos afirman que hacen esto. No he usado su producto, solo he visto sus sitios web.


Puede intentar acceder a la API lockdownd directamente, a través de libMobileGestalt.dylib .

Encabezado here . El código básico para acceder al UDID debe ser: (aún necesita cargar el dylib)

CFStringRef udid = (CFStringRef)MGCopyAnswer(kMGUniqueDeviceID);

tomado (y ligeramente modificado) desde here .

Para más información sobre libMobileGestalt , mira here .

Si esto falla, aún podría intentar comunicarse con lockdownd través de un Socket SSL (vea here ), aunque no tengo idea de cómo funciona, pero podría averiguarlo.

Como habrás notado, sin embargo, todas las cosas en esto tienen años. Todavía vale la pena intentarlo, supongo.