2011-08-12 13 views
5

Leí un blog muy interesante sobre la implementación de protección antipiratería en sus aplicaciones. Algunos de ellos ya no funcionan, algunos lo hacen. Los 2 que todavía son efectivos hasta cierto punto son los 2 últimos en la lista. http://shmoopi.wordpress.com/2011/06/19/27/Verificación de cifrado ejecutable contra medida de piratería

El que estoy interesado es el último. Código a continuación. Lo he implementado en mi AppDelegate.m

Antipiratería a través de la verificación de encriptación.

encabezados obligatorios

#import <dlfcn.h> 
#import <mach-o/dyld.h> 
#import <TargetConditionals.h> 

Encryption Struct

#if TARGET_IPHONE_SIMULATOR && !defined(LC_ENCRYPTION_INFO) 
#define LC_ENCRYPTION_INFO 0x21 
struct encryption_info_command 
{ 
uint32_t cmd; 
uint32_t cmdsize; 
uint32_t cryptoff; 
uint32_t cryptsize; 
uint32_t cryptid; 
}; 
#endif 

métodos necesarios

int main (int argc, char *argv[]); 

static BOOL is_encrypted() 
{ 
const struct mach_header *header; 
Dl_info dlinfo; 

/* Fetch the dlinfo for main() */ 
if (dladdr(main, &dlinfo) == 0 || dlinfo.dli_fbase == NULL) 
{ 
    NSLog(@"Could not find main() symbol (very odd)"); 
    return NO; 
} 
header = dlinfo.dli_fbase; 

/* Compute the image size and search for a UUID */ 
struct load_command *cmd = (struct load_command *) (header+1); 

for (uint32_t i = 0; cmd != NULL && i < header->ncmds; i++) 
{ 
    /* Encryption info segment */ 
    if (cmd->cmd == LC_ENCRYPTION_INFO) 
    { 
     struct encryption_info_command *crypt_cmd = (struct encryption_info_command *) cmd; 
     /* Check if binary encryption is enabled */ 
     if (crypt_cmd->cryptid < 1) 
     { 
      return NO; 
     } 
     return YES; 
    } 

    cmd = (struct load_command *) ((uint8_t *) cmd + cmd->cmdsize); 
} 
return NO; 
} 

Este método comprueba para ver si el binario todavía está cifrada.

Cuando ejecuto esto en el dispositivo conectado al Xcode me da un falso positivo en esta línea

if (crypt_cmd->cryptid < 1) 
{ 
    NSLog(@"Pirated from (crypt_cmd->cryptid < 1) "); 
    return NO; 
} 

Me preguntaba ¿Es posible que las compilaciones Xcode pone en el dispositivo para fines de depuración no se encriptado? Y solo está encriptado cuando la compilación se envía a Apple para su uso en iTunes. Por lo tanto, estoy obteniendo este falso positivo cuando reviso el código.

Muchas gracias, -Code

Respuesta

0

Parece que este está buscando el bloque de firma en la cabecera dyload. Esto significa que solo verá esto en el código que está firmado. Lo más probable es que su código no se firme automáticamente para la depuración (innecesario), aunque se firmará cuando vaya al dispositivo.

Es posible que desee hacer que esta comprobación completa sea condicional en el proyecto que se ejecuta en un dispositivo iOS en lugar de en el simulador. Cualquier binario enviado a un dispositivo iOS debe estar firmado.

#if !(TARGET_IPHONE_SIMULATOR) 
your check 
#endif // 
+0

Incluso en mi dispositivo de prueba funciona de la misma manera. Me pregunto ¿es el hecho de que Apple aplica el cifrado cuando lo preparan para la tienda de aplicaciones? Entonces no se aplica cuando lo construimos nosotros mismos en nuestros dispositivos locales. –

1

He estado investigando esto también recientemente y he probado con los mismos resultados. Resulta que este código te dice SÍ o NO en función de si el binario está encriptado con FairPlay DRM de Apple. Cualquier versión de depuración o ad-hoc que haga dirá NO.

Puede ver la misma información en su binario o en cualquier aplicación de iPhone que haya comprado utilizando la herramienta de línea de comandos de otool.

Para sus propios binarios, busque el binario en su proyecto en p. Ej. construir/Debug-iphoneos/MyApp.app y ejecutar (desde la Terminal)

otool -l MyApp | más

Examine para cryptid en la sección LC_ENCRYPTION_INFO. Como se trata de una compilación de depuración, será 0. Si ha sincronizado su teléfono con su computadora, verifique en ~/Music/iTunes/Mobile Applications y seleccione un archivo .ipa. Descomprímalo y prueba el otool contra el binario del .ipa y debería tener 1 para el cryptid.

3

un mejor dominio otool para ver si un archivo está cifrado o no, es:

otool -arch armv7 -l YourAppName | grep crypt 
4

Este código no funcionará correctamente en un dispositivo de 64 bits como los 5s iPhone. El encabezado se ha cambiado de mach_header a mach_header_64 y el ID del comando ahora es LC_ENCRYPTION_INFO_64.

Lo que hice fue leer el encabezado y luego ver cuál era el número mágico. Si es MH_MAGIC_64, entonces está en un dispositivo de 64 bits y necesita usar la estructura mach_header_64 y buscar LC_ENCRYPTION_INFO_64 (definido como 0x2C) en lugar de LC_ENCRYPTION_INFO.

Cuestiones relacionadas