Respuestas:
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.
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.
nm -u
Esto mostrará una lista de todos los símbolos vinculados. Esto puede detectar
UITouch._phase
(que podría ser la causa del rechazo de las aplicaciones basadas en Three20 en los últimos meses).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
-valueForKey:
; object_getInstanceVariable, object_getIvar, etc.para obtener esas bibliotecas, clases, métodos y ivars privados. )
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/,$_))))))'
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.
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.
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.
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.
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.
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!
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