
Un kit de herramientas de IDA para analizar kernelcaches de iOS.
ida_kernelcache es un módulo de IDAPython para IDA Pro que facilita el trabajo con kernelcaches de iOS. El módulo proporciona funciones para:
__PRELINK_INFO del kernel y convertirlo en un diccionario de Python.__got y las funciones stub en las secciones __stubs.La función de procesamiento principal está diseñada para ejecutarse antes de cualquier análisis manual o ingeniería inversa. Con la configuración predeterminada, IDA tiende a pasar por alto mucha información útil en el kernelcache. Estos scripts ayudan a IDA aprovechando la estructura conocida del kernelcache para propagar automáticamente información útil.
Además de la funcionalidad estándar del módulo, ida_kernelcache contiene varios scripts para facilitar el análisis del kernelcache de iOS. Por ejemplo, puedes usar los scripts para autogenerar estructuras C utilizadas por una función.
Muchas de las técnicas utilizadas en ida_kernelcache fueron desarrolladas para memctl y tomadas directamente de él.
ida_kernelcache ha sido probado con IDA Pro 6.95 en kernelcaches para las versiones de iOS 10.1.1, 11.0, 11.2, 11.3.1 y 12.0 beta. Actualmente solo se admiten kernelcaches Arm64 de iOS 10 y posteriores.
Ya necesitas tener un archivo de kernelcache descomprimido cargado en IDA. Puedes encontrar la URL para descargar un IPSW concreto de Apple en línea, y hay una serie de herramientas públicas (incluido memctl) capaces de descomprimir el kernelcache.
En IDA, selecciona "File" -> "Script file..." en la barra de menú y luego elige el script
ida_kernelcache.py en el directorio principal. Esto cargará el módulo ida_kernelcache en el
intérprete de IDAPython con los nombres ida_kernelcache y kc. En el indicador de IDAPython, escribe
kc.kernelcache_process() y pulsa Enter para comenzar a analizar el kernelcache. Esta función realiza
todos los análisis principales que admite ida_kernelcache. La función se ejecutará durante varios
minutos mientras IDA identifica y analiza nuevas funciones.
ida_kernelcache intentará no sobrescribir los nombres de usuario de las direcciones. Esto significa que
si el kernelcache ha sido analizado manualmente antes de la inicialización con kernelcache_process,
los resultados pueden no ser tan exhaustivos porque los nombres especificados por el usuario pueden
bloquear la propagación automática de nombres. Sin embargo, tampoco hay garantía de que ida_kernelcache
no estropee un análisis previo, así que si decides ejecutar kernelcache_process en un archivo de
kernelcache que ya has analizado, haz una copia de seguridad primero.
ida_kernelcache está pensado para cargarse mediante ida_kernelcache.py; los submódulos del directorio
ida_kernelcache no están pensados para cargarse directamente. Sin embargo, ida_kernelcache expone la
funcionalidad de muchos de estos submódulos. Esto es lo que hace cada uno de ellos:
ida_utilities:
Este módulo envuelve algunas de las funciones de IDA para proporcionar una API más fácil de usar.
Particularmente útiles son is_mapped, read_word, read_struct, force_function y ReadWords.
is_mapped comprueba si una dirección está mapeada y, opcionalmente, si contiene un valor conocido.
read_word lee una palabra de tamaño variable desde una dirección. read_struct lee un tipo de
estructura en un diccionario de Python o en un objeto de acceso de Python, lo que facilita mucho el
análisis de estructuras de datos. force_function intenta varios trucos para convertir una dirección
en el inicio de una función en IDA. ReadWords es un generador para iterar sobre las palabras de datos
y sus direcciones en un rango.
build_struct: Este módulo interno contiene utilidades para rellenar automáticamente una estructura de IDA basándose en una secuencia de accesos a la estructura.
class_struct:
Este módulo proporciona funciones para generar estructuras de IDA que representan tablas de métodos
virtuales y clases de C++. initialize_vtable_structs escanea las tablas de métodos virtuales
(simbolizadas) y crea estructuras de IDA para contener los punteros a métodos virtuales.
initialize_class_structs realiza un análisis de flujo de datos en los métodos virtuales para
identificar los accesos a los campos de cada clase y luego construye estructuras de IDA para representar
las clases. Las instrucciones que parecen hacer referencia a un campo también se convierten en
referencias de desplazamiento de estructura. Consulta la cadena de documentación del módulo para más
detalles.
classes:
Este módulo define el tipo ClassInfo que contiene información sobre las clases de C++ en el
kernelcache y proporciona la función collect_class_info para escanear el kernelcache en busca de
clases y rellenar el diccionario global class_info con un mapa de nombres de clase a objetos
ClassInfo. El tipo ClassInfo registra el nombre de la clase, la instancia de OSMetaClass, la tabla
de métodos virtuales y el nombre de la superclase de cada clase de C++. Además, cada objeto ClassInfo
almacena referencias al ClassInfo de la superclase y al ClassInfo de todas las subclases directas,
lo que facilita examinar y recorrer la jerarquía de clases. collect_class_info también almacena el
conjunto de todas las tablas de métodos virtuales en el conjunto global vtables.
data_flow: Este módulo interno contiene operaciones de flujo de datos utilizadas por el resto de ida_kernelcache.
kernel:
Este módulo proporciona las variables globales base y prelink_info. base es la dirección base de
la imagen del kernel (el inicio del encabezado Mach-O del kernel). prelink_info es el diccionario
analizado de __PRELINK_INFO.
kplist:
Este módulo proporciona la función kplist_parse para analizar plists con formato de kernel.
metaclass:
Este módulo proporciona la función initialize_metaclass_symbols, que añade un símbolo para cada
instancia de OSMetaClass conocida.
offset:
Este módulo proporciona las funciones initialize_data_offsets e initialize_offset_symbols. La
primera escanea los segmentos en busca de punteros que puedan convertirse en desplazamientos. La segunda
simboliza los desplazamientos en la sección __got de cada kext si el destino del desplazamiento tiene
un símbolo.