¿Cómo sabe Apple que estás usando una API privada?

109

Envié un archivo binario a Apple sin ningún código fuente.

Además de verificar manualmente el código fuente, ¿cómo sabe Apple qué se usó y qué API ha llamado?

Tattat
fuente
título cambiado - supongo que quisiste decir "¿Cómo sabe Apple ...?"
Anurag

Respuestas:

173

Hay 3 formas en las que lo sé. Estas son solo algunas especulaciones, ya que no trabajo en el equipo de revisión de Apple.

1. otool -L

Esto mostrará una lista de todas las bibliotecas a las que se ha vinculado la aplicación. Algo que claramente no debe usar, como IOKit y WebKit puede ser detectado por esto.

2. nm -u

Esto mostrará una lista de todos los símbolos vinculados. Esto puede detectar

3. Listado de selectores de Objective-C, o strings

Los selectores de Objective-C se almacenan en una región especial del binario y, por lo tanto, Apple podría extraer el contenido de allí y verificar si ha utilizado algunos métodos de Objective-C no documentados, como -[UIDevice setOrientation:].

Dado que los selectores son independientes de la clase a la que está enviando mensajes, incluso si su clase personalizada se define como -setOrientation:irrelevante para UIDevice, existe la posibilidad de que sean rechazados.


Puede usar el APIKit de Erica Sadun para detectar un posible rechazo debido a (falsas alarmas de) API privadas.


(Si realmente realmente desea solucionar estas comprobaciones, puede usar funciones de tiempo de ejecución como

  • dlopen, dlsym
  • objc_getClass, sel_registerName, objc_msgSend
  • -valueForKey:; object_getInstanceVariable, object_getIvar, etc.

para obtener esas bibliotecas, clases, métodos y ivars privados. )

Kennytm
fuente
Gran respuesta. Solo agregaré que si su aplicación está haciendo algo que es extremadamente difícil de hacer sin usar una API privada, estoy seguro de que su aplicación recibe un escrutinio adicional.
Matthew Frederick
Tengo curiosidad sobre la solución alternativa de llamar a métodos privados. Creo que el compilador generará una llamada a objc_msgSend (foo, @selector (privateMethod)) para [foo privateMethod], por lo que si Apple puede detectar la llamada directa de privateMethod, también pueden detectar la llamada indirecta a través de objc_msgSend (o performSelector :).
an0
Me pregunto por qué dice que no debería vincular contra IOKit y WebKit.
hjaltij
2
¿En qué ejecutas otool? ¿El archivo .app?
Rob
1
@Eric, podrían , aunque una versión instrumentada de este tipo probablemente afectaría el rendimiento. Independientemente, al ver que las API privadas ingresan a la App Store repetidamente, está claro que no hacen esto, o al menos no lo hacen todo el tiempo.
Nate
26

Puede enumerar los selectores en un programa Mach-O usando la siguiente línea en Terminal:

otool -s __TEXT __objc_methname "$1" |expand -8 | cut -c17- | sed -n '3,$p' | perl -n -e 'print join("\n",split(/\x00/,scalar reverse (reverse unpack("(a4)*",pack("(H8)*",split(/\s/,$_))))))'
Robert Diamond
fuente
+1, @Robert Diamond, ¿puedes describir más de lo mismo? Necesito verificar que Google Analytics use llamadas UDID o no. Gracias
Mangesh
13

Digamos que quiere usar alguna API privada; El objetivo C le permite construir cualquier SEL a partir de una cadena:

   SEL my_sel = NSSelectorFromString([NSString stringWithFormat:\
@"%@%@%@", "se","tOr","ientation:"]);
    [UIDevice performSelector:my_sel ...];

¿Cómo podría un robot o un escaneo de biblioteca detectar esto? Tendrían que detectar esto utilizando alguna herramienta que supervise los accesos privados en tiempo de ejecución. Incluso si construyeron una herramienta de tiempo de ejecución de este tipo, es difícil de detectar porque esta llamada puede estar oculta en alguna ruta que rara vez se ejercita.

Chris McLuvin
fuente
user1203764 comenta que este tipo de llamadas realmente se pueden detectar
Rup
@Rup quiere dar una opinión sobre mi pregunta aquí sobre el uso de valueForKey, ¿por favor? stackoverflow.com/questions/11923597/…
Dan Rosenstark
1
@Yar pregunta interesante! Pero no soy lo suficientemente experto para comentar lo siento. Lo que dijo Farcaller me parece razonable
Rup
Gracias @Rup, aparentemente nadie es lo suficientemente experto en este campo :)
Dan Rosenstark
Alguien que conozco dice que acaba de recibir una llamada como esta en la App Store.
bugloaf
7

Me imagino que miran todos los símbolos que su binario está tratando de importar (información sin duda disponible para ellos en la tabla de símbolos) y le avisan si alguno de esos símbolos se encuentra en su "lista de API privada". De hecho, es bastante fácil de automatizar.

Alex Martelli
fuente
1
De hecho, puedo decir con certeza que este no es el caso (al menos no es todo lo que hacen), basado en el uso de API privadas que sé que se ha logrado. Si esto es todo lo que se necesitaba, el uso de la API privada no se filtraría . Mi experiencia sugiere que la respuesta de KennyTM es casi con certeza correcta. Esta es un área donde Objective-C es fundamentalmente diferente a otros idiomas, como C.
Nate
1

Un ejecutable no es exactamente una caja negra. Si llama a una biblioteca, es fácil de encontrar. Es por eso que lamento la pérdida de los lenguajes ensambladores en la educación informática moderna. =] Herramientas como ldd te dirán lo que has vinculado, aunque no recuerdo qué encarnación de ldd llegó al kit de desarrollo de Mac iPhone.

Sniggerfardimungus
fuente
1
Con frecuencia me he preguntado: si escribiera su binario para auto-modificarlo, solo generando el código para importar una API privada después de que se hayan cumplido algunos criterios (por ejemplo, después de la fecha de publicación de su aplicación) si Apple lo detectaría. Ciertamente, nos informan sobre algunas estadísticas interesantes, como el número de nuestros juegos que se ejecutan en teléfonos con jailbreak.
Sniggerfardimungus
@ user30997, Es probable que solo se pueda acceder al código privilegiado mediante una llamada al sistema; el hilo de ejecución cambia a un privilegio superior y comprueba si el privilegio anterior tiene permisos para ejecutar el código o no. Sin embargo, eso es solo un ejemplo, hay otras formas de hacerlo, pero dudo mucho que los desarrolladores fueran lo suficientemente ingenuos como para dejar de lado un mecanismo básico de verificación de privilegios en tiempo de ejecución como este, definitivamente ya se habría publicitado.
L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳
1
otool -L somebinary
dvenema
fuente
1

aparte de la investigación de símbolos ...

Apple podría tener muy fácilmente una versión del sdk que verifica cada una de las pilas de métodos privados cuando se llama para asegurarse de que se ingresa desde uno de los métodos designados.

Grady Player
fuente
Eso no será suficiente, porque el programa solo puede llamar a esta llamada privada en un momento arbitrario en el futuro, dependiendo de otra lógica. Para hacer este escrutinio, Apple debe bloquear las API privadas por completo, o hacer que los marcos informen las llamadas API privadas a Apple automáticamente, lo que perjudica significativamente el rendimiento.
Motti Shneor
0

Incluso si está vinculando estáticamente, en el peor de los casos, podrían tomar muestras del código de las API privadas en su lista y buscar su binario con ellas (también relativamente fácil de automatizar).

Conociendo a Apple, apostaría a que tienen un sistema completo y automatizado, y cualquier duda probablemente se niega o se revisa manualmente.

Al final del día, creo que probablemente no valga la pena el esfuerzo de intentar engañar a Apple.

lavar
fuente
4
Conocer a Apple sobre su proceso de revisión al encontrarse con cualquier incertidumbre implica romper una serie de dados para obtener el máximo capricho.
SOLO MI OPINIÓN correcta
0

Esta aplicación de escritorio, App Scanner , puede escanear archivos .app para el uso de una API privada al separar el archivo binario Mach-O. Si puede, ¡Apple también puede hacerlo!

Andrés
fuente
0

Hay muchas herramientas para la ingeniería inversa que permiten inspeccionar un código.

  • nm - enumera los símbolos de archivos de objeto
  • objdump - mostrar información de archivos de objetos.
  • otool- ver el contenido de los ejecutables Mach-O [Acerca de]
  • strings - esto te dará todas las cuerdas.

Puede encontrar ejemplos / representaciones del uso de estos comandos en gists para Objective-C y Swift

yoAlex5
fuente