Rinoceronte dentro de un gato: iniciando el firmware en el emulador Kopycat

Rinoceronte dentro de un gato: iniciando el firmware en el emulador Kopycat

En el marco de la reunión 0x0A DC7831 DEF CON Nizhni Nóvgorod El 16 de febrero presentamos una charla sobre los principios básicos de la emulación de código binario y nuestro desarrollo propio: un emulador de plataformas de hardware. Kopycat.

En este artículo, proporcionaremos una descripción de cómo lanzar el firmware del dispositivo en el emulador, demostraremos la interacción con el depurador y realizaremos un pequeño análisis dinámico del firmware.

Antecedentes

Hace mucho tiempo, en una galaxia muy, muy lejana

Hace un par de años, en nuestro laboratorio, surgió la necesidad de investigar el firmware de un dispositivo. El firmware estaba comprimido y era descomprimido por el bootloader. Lo hacía de una manera bastante complicada, moviendo los datos varias veces en la memoria. Además, el firmware interactuaba activamente con la periferia. Y todo esto sobre una arquitectura MIPS.

Los emuladores existentes no nos satisfacían por razones objetivas, pero queríamos ejecutar el código. Así que decidimos crear nuestro propio emulador que hiciera lo mínimo y permitiera descomprimir el firmware principal. Lo intentamos: tuvimos éxito. Pensamos, ¿y si añadimos la periferia para también ejecutar el firmware principal? No fue demasiado doloroso, y también funcionó. Pensamos de nuevo y decidimos desarrollar un emulador completo.

Al final, obtuvimos un emulador de sistemas computacionales. Kopycat.

Rinoceronte dentro de un gato: iniciando el firmware en el emulador Kopycat
¿Por qué Kopycat?

Es un juego de palabras.

  1. copycat (inglés, sust. [ˈkɒpɪkæt]) — imitador, copiador.
  2. cat (inglés, sust. [ˈkæt]) — gato, felino — la mascota favorita de uno de los creadores del proyecto.
  3. La letra 'K' proviene del lenguaje de programación Kotlin.

Kopycat

Al crear el emulador, se establecieron objetivos muy concretos:

  • la capacidad de crear rápidamente nuevos periféricos, módulos y núcleos de procesador;
  • la posibilidad de construir un dispositivo virtual a partir de varios módulos;
  • la capacidad de cargar en la memoria del dispositivo virtual cualquier dato binario (firmware);
  • la posibilidad de trabajar con instantáneas (capturas de estado del sistema);
  • la capacidad de interactuar con el emulador a través de un depurador integrado;
  • un lenguaje de desarrollo agradable y moderno.

Al final, se eligió Kotlin para la implementación, una arquitectura de bus (esto es cuando los módulos se conectan entre sí a través de buses de datos virtuales), JSON como formato para la descripción del dispositivo, y GDB RSP como protocolo para la interacción con el depurador.

El desarrollo ha estado en curso durante poco más de dos años y continúa activamente. Durante este tiempo, se han implementado núcleos de procesadores MIPS, x86, V850ES, ARM y PowerPC.

El proyecto está creciendo y ha llegado el momento de presentarlo al público en general. Haremos una descripción detallada del proyecto más adelante, pero ahora nos concentraremos en el uso de Kopycat.

Para los más impacientes, la versión promocional del emulador se puede descargar en el enlace.

Rhinoceros en el emulador

Recordemos que anteriormente se creó un dispositivo de prueba llamado 'Rhinoceros' para la conferencia SMARTRHINO-2018 con el fin de enseñar habilidades de ingeniería inversa. El proceso de análisis estático del firmware se describió en este artículo.

Ahora intentaremos agregar 'dinámica' y ejecutaremos el firmware en el emulador.

Necesitaremos:
1) Java 1.8
2) Python y el módulo Jep para utilizar Python dentro del emulador. La versión WHL del módulo Jep para Windows se puede descargar aquí.

Para Windows:
1) com0com
2) PuTTY

Para Linux:
1) socat

Como cliente GDB, se puede usar Eclipse, IDA Pro o radare2.

¿Cómo funciona?

Para poder ejecutar el firmware en el emulador, es necesario 'construir' un dispositivo virtual que representa un análogo del dispositivo real.

El dispositivo real ('rhinoceros') se puede mostrar en un esquema estructural:

Rinoceronte dentro de un gato: iniciando el firmware en el emulador Kopycat

El emulador tiene una estructura modular y el dispositivo virtual final se puede describir en un archivo JSON.

JSON de 105 líneas

{
  "top": true,

  // El nombre del plugin debe ser el mismo que el nombre del archivo (o la ruta completa desde el inicio de la biblioteca)
  "plugin": "rhino",

  // Directorio donde se coloca el plugin
  "library": "user",

  // Parámetros del plugin (parámetros del constructor si es versión jar-plugin)
  "params": [
    { "name": "tty_dbg", "type": "String"},
    { "name": "tty_bt", "type": "String"},
    { "name": "firmware", "type": "String", "default": "NUL"}
  ],

  // Puertos externos del plugin
  "ports": [  ],

  // Buses internos del plugin
  "buses": [
    { "name": "mem", "size": "BUS30" },
    { "name": "nand", "size": "4" },
    { "name": "gpio", "size": "BUS32" }
  ],

  // Componentes internos del plugin
  "modules": [
    {
      "name": "u1_stm32",
      "plugin": "STM32F042",
      "library": "mcu",
      "params": {
        "firmware:String": "params.firmware"
      }
    },
    {
      "name": "usart_debug",
      "plugin": "UartSerialTerminal",
      "library": "terminals",
      "params": {
        "tty": "params.tty_dbg"
      }
    },
    {
      "name": "term_bt",
      "plugin": "UartSerialTerminal",
      "library": "terminals",
      "params": {
        "tty": "params.tty_bt"
      }
    },
    {
      "name": "bluetooth",
      "plugin": "BT",
      "library": "mcu"
    },

    { "name": "led_0",  "plugin": "LED", "library": "mcu" },
    { "name": "led_1",  "plugin": "LED", "library": "mcu" },
    { "name": "led_2",  "plugin": "LED", "library": "mcu" },
    { "name": "led_3",  "plugin": "LED", "library": "mcu" },
    { "name": "led_4",  "plugin": "LED", "library": "mcu" },
    { "name": "led_5",  "plugin": "LED", "library": "mcu" },
    { "name": "led_6",  "plugin": "LED", "library": "mcu" },
    { "name": "led_7",  "plugin": "LED", "library": "mcu" },
    { "name": "led_8",  "plugin": "LED", "library": "mcu" },
    { "name": "led_9",  "plugin": "LED", "library": "mcu" },
    { "name": "led_10", "plugin": "LED", "library": "mcu" },
    { "name": "led_11", "plugin": "LED", "library": "mcu" },
    { "name": "led_12", "plugin": "LED", "library": "mcu" },
    { "name": "led_13", "plugin": "LED", "library": "mcu" },
    { "name": "led_14", "plugin": "LED", "library": "mcu" },
    { "name": "led_15", "plugin": "LED", "library": "mcu" }
  ],

  // Conexiones del plugin entre componentes
  "connections": [
    [ "u1_stm32.ports.usart1_m", "usart_debug.ports.term_s"],
    [ "u1_stm32.ports.usart1_s", "usart_debug.ports.term_m"],

    [ "u1_stm32.ports.usart2_m", "bluetooth.ports.usart_m"],
    [ "u1_stm32.ports.usart2_s", "bluetooth.ports.usart_s"],

    [ "bluetooth.ports.bt_s", "term_bt.ports.term_m"],
    [ "bluetooth.ports.bt_m", "term_bt.ports.term_s"],

    [ "led_0.ports.pin",  "u1_stm32.buses.pin_output_a", "0x00"],
    [ "led_1.ports.pin",  "u1_stm32.buses.pin_output_a", "0x01"],
    [ "led_2.ports.pin",  "u1_stm32.buses.pin_output_a", "0x02"],
    [ "led_3.ports.pin",  "u1_stm32.buses.pin_output_a", "0x03"],
    [ "led_4.ports.pin",  "u1_stm32.buses.pin_output_a", "0x04"],
    [ "led_5.ports.pin",  "u1_stm32.buses.pin_output_a", "0x05"],
    [ "led_6.ports.pin",  "u1_stm32.buses.pin_output_a", "0x06"],
    [ "led_7.ports.pin",  "u1_stm32.buses.pin_output_a", "0x07"],
    [ "led_8.ports.pin",  "u1_stm32.buses.pin_output_a", "0x08"],
    [ "led_9.ports.pin",  "u1_stm32.buses.pin_output_a", "0x09"],
    [ "led_10.ports.pin", "u1_stm32.buses.pin_output_a", "0x0A"],
    [ "led_11.ports.pin", "u1_stm32.buses.pin_output_a", "0x0B"],
    [ "led_12.ports.pin", "u1_stm32.buses.pin_output_a", "0x0C"],
    [ "led_13.ports.pin", "u1_stm32.buses.pin_output_a", "0x0D"],
    [ "led_14.ports.pin", "u1_stm32.buses.pin_output_a", "0x0E"],
    [ "led_15.ports.pin", "u1_stm32.buses.pin_output_a", "0x0F"]
  ]
}

Presta atención al parámetro firmware en la sección params — este es el nombre del archivo que se puede cargar en el dispositivo virtual como firmware.

El dispositivo virtual y su interacción con el sistema operativo principal se puede representar con el siguiente esquema:

Rinoceronte dentro de un gato: iniciando el firmware en el emulador Kopycat

La versión actual del emulador implica la interacción con los puertos COM del sistema operativo principal (UART de depuración y UART para el módulo Bluetooth). Estos pueden ser puertos reales a los que están conectados dispositivos o puertos COM virtuales (para esto se necesita exactamente com0com / socat).

Para interactuar con el emulador desde el exterior, actualmente existen dos métodos principales:

  • el protocolo GDB RSP (por lo tanto, las herramientas que soportan este protocolo son — Eclipse / IDA / radare2);
  • la línea de comandos interna del emulador (Argparse o Python).

Puertos COM virtuales

Para interactuar con el UART del dispositivo virtual en la máquina local a través de un terminal, es necesario crear un par de puertos COM virtuales vinculados. En nuestro caso, un puerto es utilizado por el emulador, y el segundo — por el programa terminal (PuTTY o screen):

Rinoceronte dentro de un gato: iniciando el firmware en el emulador Kopycat

Uso de com0com

Los puertos COM virtuales se configuran con la utilidad setup del paquete com0com (versión consola — C:Program Files (x86)com0comsetupс.exe, o versión GUI — C:Program Files (x86)com0comsetupg.exe):

Rinoceronte dentro de un gato: iniciando el firmware en el emulador Kopycat

Se deben marcar las casillas enable buffer overrun para todos los puertos virtuales creados, de lo contrario el emulador esperará una respuesta del puerto COM.

Uso de socat

En sistemas UNIX, los puertos COM virtuales se crean automáticamente por el emulador utilizando la utilidad socat, para esto basta con especificar el prefijo socat:.

Interfaz interna de línea de comandos (Argparse o Python)

Dado que Kopycat es una aplicación de consola, para interactuar con sus objetos y variables, el emulador proporciona dos opciones de interfaz de línea de comandos: Argparse y Python.

Argparse es el CLI integrado en Kopycat, está disponible siempre y para todos.

El CLI alternativo es el intérprete de Python. Para su uso, se debe instalar el módulo de Python Jep y configurar el emulador para trabajar con Python (se usará el intérprete de Python instalado en el sistema principal del usuario).

Instalación del módulo de Python Jep

En Linux, Jep se puede instalar a través de pip:

pip install jep

Para instalar Jep en Windows, primero se debe instalar Windows SDK y Microsoft Visual Studio correspondiente. Hemos simplificado un poco su tarea y hemos hecho compilaciones WHL JEP para las versiones actuales de Python para Windows, por lo que el módulo se puede instalar desde el archivo:

pip install jep-3.8.2-cp27-cp27m-win_amd64.whl

Para verificar la instalación de Jep, se debe ejecutar en la línea de comandos:

python -c "import jep"

La respuesta debería ser:

ImportError: Jep no es compatible en Python independiente, debe estar integrado en Java.

En el archivo por lotes del emulador para su sistema (kopycat.bat — para Windows, kopycat — para Linux) añada el parámetro adicional a la lista de parámetros DEFAULT_JVM_OPTS añada el parámetro adicional Djava.library.path — debe contener la ruta al módulo Jep instalado.

Como resultado, para Windows, la cadena resultante debería ser de la siguiente forma:

set DEFAULT_JVM_OPTS="-XX:MaxMetaspaceSize=256m" "-XX:+UseParallelGC" "-XX:SurvivorRatio=6" "-XX:-UseGCOverheadLimit" "-Djava.library.path=C:/Python27/Lib/site-packages/jep"

Iniciar Kopycat

El emulador es una aplicación de consola JVM. La ejecución se realiza a través de un script de línea de comandos del sistema operativo (sh/cmd).

El comando para iniciar en Windows:

binkopycat -g 23946 -n rhino -l user -y library -p firmware=firmwarerhino_pass.bin,tty_dbg=COM26,tty_bt=COM28

El comando para iniciar en Linux usando la utilidad socat:

./bin/kopycat -g 23946 -n rhino -l user -y library -p firmware=./firmware/rhino_pass.bin, tty_dbg=socat:./COM26,tty_bt=socat:./COM28

  • -g 23646 — el puerto TCP que se abrirá para acceder al servidor GDB;
  • -n rhino — el nombre del módulo principal del sistema (dispositivo ensamblado);
  • -l user — el nombre de la biblioteca para buscar el módulo principal;
  • -y library — la ruta para buscar los módulos que forman parte del dispositivo;
  • firmwarerhino_pass.bin — la ruta al archivo de firmware;
  • COM26 y COM28 — puertos COM virtuales.

Como resultado, se mostrará un aviso Python > (o Argparse >):

18:07:59 INFO [eFactoryBuilder.create]: Módulo top creado con éxito como top
18:07:59 INFO [ Module.initializeAndRes]: Configurando núcleo a top.u1_stm32.cortexm0.arm para top
18:07:59 INFO [ Module.initializeAndRes]: Configurando depurador a top.u1_stm32.dbg para top
18:07:59 WARN [ Module.initializeAndRes]: Tracer no fue encontrado en top...
18:07:59 INFO [ Module.initializeAndRes]: Inicializando puertos y buses...
18:07:59 WARN [ Module.initializePortsA]: ATENCIÓN: Algunos puertos tienen advertencias, use printModulesPortsWarnings para verlas...
18:07:59 FINE [ ARMv6CPU.reset]: Establecer dirección de punto de entrada a 08006A75
18:07:59 INFO [ Module.initializeAndRes]: Módulo top se ha inicializado y reiniciado con éxito como una celda top!
18:07:59 INFO [ Kopycat.open]: Iniciando virtualización de la placa top[rhino] con arm[ARMv6Core]
18:07:59 INFO [ GDBServer.debuggerModule]: Establecer nuevo módulo de depurador top.u1_stm32.dbg para GDB_SERVER(port=23946,alive=true)
Python >

Interacción con IDA Pro

Como archivo fuente para análisis en IDA, utilizamos el firmware «Rhinoceros» en forma de archivo ELF (ahí se guarda la metainformación).

También puede usar el firmware principal sin metainformación.

Después de iniciar Kopycat en IDA Pro, en el menú Depurador vamos a la opción «Cambiar depurador…» y seleccionamos «Depurador GDB remoto«. A continuación, configuramos la conexión: menú Depurador — Opciones de proceso…

Establecemos los valores:

  • Aplicación — cualquier valor
  • Hostname: 127.0.0.1 (o la dirección IP de la máquina remota donde se ejecuta Kopycat)
  • Puerto: 23946

Rinoceronte dentro de un gato: iniciando el firmware en el emulador Kopycat

Ahora se habilita el botón para iniciar la depuración (tecla F9):

Rinoceronte dentro de un gato: iniciando el firmware en el emulador Kopycat

Hacemos clic en él — se conecta al módulo del depurador en el emulador. IDA entra en modo de depuración, se habilitan ventanas adicionales: información sobre registros y sobre la pila.

Ahora podemos utilizar todas las funciones estándar del depurador:

  • ejecución paso a paso de instrucciones (Entrar en y Saltar — teclas F7 y F8, respectivamente);
  • iniciar y pausar la ejecución;
  • crear puntos de interrupción tanto en el código como en los datos (tecla F2).

Conectarse al depurador no significa que el código del firmware se esté ejecutando. La posición actual para la ejecución debe ser la dirección 0x08006A74 — inicio de la función Reset_Handler. Si desplazamos el listado hacia abajo, podemos ver la llamada a la función main. Podemos establecer el cursor en esta línea (dirección 0x08006ABE) y realizar la operación Ejecutar hasta el cursor (tecla F4).

Rinoceronte dentro de un gato: iniciando el firmware en el emulador Kopycat

Luego, se puede presionar F7 para entrar en la función main.

Si ejecutamos el comando Continuar proceso (tecla F9), aparecerá una ventana «Por favor espera» con un único botón Suspender:

Rinoceronte dentro de un gato: iniciando el firmware en el emulador Kopycat

Al presionar Suspender la ejecución del código del firmware se pausa y puede continuar desde la misma dirección en el código, donde se detuvo.

Si se continúa la ejecución del código, se pueden ver las siguientes líneas en las terminales conectadas a los puertos COM virtuales:

Rinoceronte dentro de un gato: iniciando el firmware en el emulador Kopycat

Rinoceronte dentro de un gato: iniciando el firmware en el emulador Kopycat

La presencia de la línea «estado de bypass» indica que el módulo Bluetooth virtual ha cambiado a modo de recepción de datos desde el puerto COM del usuario.

Ahora en el terminal Bluetooth (en la imagen — COM29) se pueden ingresar comandos conforme al protocolo «Rinoceronte». Por ejemplo, al comando «MEOW» el terminal Bluetooth devuelve la línea «mur-mur»:

Rinoceronte dentro de un gato: iniciando el firmware en el emulador Kopycat

No me emules completamente

Al construir el emulador, se puede elegir el nivel de detalle/emulación de cada dispositivo. Por ejemplo, el módulo Bluetooth se puede emular de diversas maneras:

  • se emula completamente el dispositivo con un conjunto completo de comandos;
  • se emulan comandos AT, y el flujo de datos se recibe desde el puerto COM del sistema principal;
  • el dispositivo virtual proporciona un redireccionamiento completo de datos al dispositivo real;
  • en forma de un simple placeholder, que siempre devuelve «OK».

En la versión actual del emulador se utiliza un segundo enfoque: un módulo Bluetooth virtual realiza la configuración y después pasa al modo de "proxy" de datos desde el puerto COM del sistema principal hacia el puerto UART del emulador.

Rinoceronte dentro de un gato: iniciando el firmware en el emulador Kopycat

Consideremos la posibilidad de instrumentar el código fácilmente en caso de que no se implemente alguna parte del periférico. Por ejemplo, si no se ha creado un temporizador responsable de controlar la transmisión de datos en DMA (la verificación se realiza en la función ws2812b_wait, ubicada en la dirección 0x08006840), entonces el firmware siempre esperará la reinicialización de la bandera busy, ubicada en la dirección 0x200004C4, la cual indica la ocupación de la línea de datos DMA:

Rinoceronte dentro de un gato: iniciando el firmware en el emulador Kopycat

Podemos evitar esta situación mediante un reinicio "manual" de la bandera busy inmediatamente después de establecerla. En IDA Pro se puede crear una función de Python y llamarla en el breakpoint, colocando el breakpoint en el código después de escribir el valor 1 en la bandera busy.

Manejador de breakpoints

Primero creamos la función de Python en IDA. En el menú Archivo — Comando de script...

Agregamos un nuevo snippet en la lista de la izquierda, le damos un nombre (por ejemplo, BPT),
en el campo de texto a la derecha introducimos el código de la función:

def skip_dma():
    print "Saltando espera ws2812..."
    value = Byte(0x200004C4)
    if value == 1:
        PatchDbgByte(0x200004C4, 0)
return False

Rinoceronte dentro de un gato: iniciando el firmware en el emulador Kopycat

Después de esto hacemos clic en Ejecutar y cerramos la ventana de scripts.

Ahora veremos el código en la dirección 0x0800688A, establecemos el breakpoint (tecla F2), lo editamos (menú contextual Editar breakpoint...), no olvidemos establecer el tipo de script – Python:

Rinoceronte dentro de un gato: iniciando el firmware en el emulador Kopycat
Rinoceronte dentro de un gato: iniciando el firmware en el emulador Kopycat

Si el valor actual de la bandera busy es igual a 1, entonces se debe ejecutar la función skip_dma en la línea de scripts:

Rinoceronte dentro de un gato: iniciando el firmware en el emulador Kopycat

Si se inicia la ejecución del firmware, se puede observar la ejecución del código del manejador del breakpoint en IDA en la ventana Salida en la línea Saltando espera ws2812.... Ahora el firmware no esperará la reinicialización de la bandera. busy.

Interacción con el emulador

La emulación por la emulación difícilmente causará entusiasmo y alegría. Es mucho más interesante si el emulador ayuda al investigador a ver datos en la memoria o a establecer la interacción de hilos.

Mostraremos cómo establecer dinámicamente la interacción de tareas de RTOS. Previamente, se debe pausar la ejecución del código, si está en ejecución. Si se accede a la función bluetooth_task_entry en la rama de procesamiento del comando "LED" (dirección 0x080057B8), se puede ver que primero se crea y luego se envía a la cola del sistema ledControlQueueHandle un cierto mensaje.

Rinoceronte dentro de un gato: iniciando el firmware en el emulador Kopycat

Se debe establecer un breakpoint en la variable ledControlQueueHandle, ubicada en la dirección 0x20000624 y continuar la ejecución del código:

Rinoceronte dentro de un gato: iniciando el firmware en el emulador Kopycat

Como resultado, primero se detendrá en la dirección 0x080057CA antes de la llamada a la función osMailAlloc, luego — en la dirección 0x08005806 antes de la llamada a la función osMailPut, después de un tiempo — en la dirección 0x08005BD4 (antes de la llamada a la función osMailGet), que pertenece a la función leds_task_entry (tarea LED), es decir, ha habido un cambio de tareas, y ahora el control pertenece a la tarea LED.

Rinoceronte dentro de un gato: iniciando el firmware en el emulador Kopycat

De esta manera sencilla se puede establecer cómo las tareas del RTOS interactúan entre sí.

Por supuesto, en realidad la interacción de las tareas puede ser más compleja, pero usando un emulador, rastrear esta interacción se vuelve menos laborioso.

Aquí se puede ver un breve video sobre el inicio del emulador y la interacción con IDA Pro.

Inicio con Radare2

No se puede pasar por alto una herramienta tan versátil como Radare2.

Para conectarse al emulador usando r2, el comando sería:

radare2 -A -a arm -b 16 -d gdb://localhost:23946 rhino_fw42k6.elf

Ahora están disponibles el inicio (dc) y la pausa de la ejecución (Ctrl+C).

Desafortunadamente, actualmente hay problemas en r2 al trabajar con el servidor gdb de hardware y el mapeo de memoria, por lo que los puntos de interrupción y los pasos (comando ds) no funcionan. Esperamos que esto se solucione pronto.

Inicio con Eclipse

Una de las opciones para usar el emulador es depurar el firmware del dispositivo en desarrollo. Para mayor claridad, también usaremos el firmware 'Rinoceronte'. Se puede descargar el código fuente del firmware desde aquí.

Como IDE, utilizaremos Eclipse del conjunto System Workbench for STM32.

Para que el firmware construido en Eclipse se cargue directamente en el emulador, es necesario añadir el parámetro firmware=null al comando de inicio del emulador:

binkopycat -g 23946 -n rhino -l user -y modules -p firmware=null,tty_dbg=COM26,tty_bt=COM28

Configuración de la configuración de depuración

En Eclipse, seleccionamos el menú Ejecutar — Configuraciones de Depuración… En la ventana que aparece, en la sección Depuración de Hardware GDB es necesario añadir una nueva configuración, luego en la pestaña 'Principal', indicar el proyecto actual y la aplicación que se va a depurar:

Rinoceronte dentro de un gato: iniciando el firmware en el emulador Kopycat

En la pestaña 'Depurador', es necesario indicar el comando GDB:
${openstm32_compiler_path}arm-none-eabi-gdb

Y también ingresar los parámetros para la conexión al servidor GDB (host y puerto):

Rinoceronte dentro de un gato: iniciando el firmware en el emulador Kopycat

En la pestaña 'Inicio', es necesario especificar los siguientes parámetros:

  • marcar la casilla Cargar imagen (para que se cargue en el emulador la imagen del firmware compilada);
  • marcar la casilla Cargar símbolos;
  • añadir el comando de inicio: set $pc = *0x08000004 (establecer en el registro PC el valor de la memoria en la dirección 0x08000004 — allí se almacena la dirección ResetHandler).

Presta atención, si no quieres cargar el archivo de firmware desde Eclipse, entonces los parámetros Cargar imagen y Ejecutar comandos no es necesario especificar.

Rinoceronte dentro de un gato: iniciando el firmware en el emulador Kopycat

Después de presionar Debug, se puede trabajar en modo de depuración:

  • ejecución paso a paso del código
    Rinoceronte dentro de un gato: iniciando el firmware en el emulador Kopycat
  • interacción con los puntos de ruptura
    Rinoceronte dentro de un gato: iniciando el firmware en el emulador Kopycat

Nota. En Eclipse hay, hmm... algunas peculiaridades... y hay que vivir con ellas. Por ejemplo, si al iniciar el depurador aparece el mensaje "No source available for '0x0'", entonces ejecute el comando Step (F5)

Rinoceronte dentro de un gato: iniciando el firmware en el emulador Kopycat

En conclusión

La emulación de código nativo es algo muy interesante. Para los desarrolladores de dispositivos, brinda la oportunidad de depurar firmware sin un dispositivo real. Para los investigadores, ofrece la oportunidad de realizar análisis dinámico de código, lo que no siempre es posible incluso con el dispositivo presente.

Queremos proporcionar a los especialistas una herramienta que sea conveniente, relativamente simple y que no requiera mucho esfuerzo y tiempo para su configuración y puesta en marcha.

Comparta en los comentarios su experiencia con emuladores de hardware. Invitamos a la discusión y estaremos encantados de responder preguntas.

Solo los usuarios registrados pueden participar en la encuesta. Inicie sesión, por favor.

¿Para qué utilizas el emulador?

  • desarrollo (depuración) de firmware

  • investigación de firmware

  • ejecución de juegos (Dendi, Sega, PSP)

  • otra cosa (escriba en los comentarios)

Votaron 7 usuarios. 2 usuarios se abstuvieron.

¿Qué software utilizas para emular código nativo?

  • QEMU

  • Motor Unicorn

  • Proteus

  • otra cosa (escriba en los comentarios)

Votaron 6 usuarios. 2 usuarios se abstuvieron.

¿Qué te gustaría mejorar en el emulador que utilizas?

  • me gustaría velocidad

  • me gustaría comodidad en configuración/ejecución

  • me gustaría más opciones de interacción con el emulador (API, hooks)

  • estoy satisfecho con todo

  • otra cosa (escriba en los comentarios)

8 usuarios votaron. 1 usuario se abstuvo.

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster