Rhinoceros inside a cat: executa o firmware no emulador Kopycat

Rhinoceros inside a cat: executa o firmware no emulador Kopycat

Como parte da reunión 0x0A DC7831 DEF CON Nizhny Novgorod O 16 de febreiro presentamos un informe sobre os principios básicos da emulación de código binario e o noso propio desenvolvemento: un emulador de plataforma de hardware Copycat.

Neste artigo describiremos como executar o firmware do dispositivo no emulador, demostrar a interacción co depurador e realizar unha pequena análise dinámica do firmware.

prehistoria

Hai moito tempo nunha galaxia moi lonxe

Hai un par de anos, no noso laboratorio había a necesidade de investigar o firmware dun dispositivo. O firmware foi comprimido e desempaquetado cun cargador de arranque. Fíxoo dun xeito moi complicado, cambiando os datos da memoria varias veces. E entón o propio firmware interactuou activamente cos periféricos. E todo isto no núcleo MIPS.

Por razóns obxectivas, os emuladores dispoñibles non nos conviñan, pero aínda así queriamos executar o código. Entón decidimos facer o noso propio emulador, que faría o mínimo e permitiría desempaquetar o firmware principal. Probamos e funcionou. Pensamos, que pasaría se engadimos periféricos para realizar tamén o firmware principal. Non doeu moito, e tamén funcionou. Pensámolo de novo e decidimos facer un emulador completo.

O resultado foi un emulador de sistemas informáticos Copycat.

Rhinoceros inside a cat: executa o firmware no emulador Kopycat
Por que Kopycat?

Hai un xogo de palabras.

  1. copycat (Inglés, substantivo [ˈkɒpɪkæt]) - imitador, imitador
  2. gato (Inglés, substantivo [ˈkæt]) - gato, gato - o animal favorito dun dos creadores do proxecto
  3. A letra "K" é da linguaxe de programación Kotlin

Copycat

Ao crear o emulador, fixéronse obxectivos moi específicos:

  • a capacidade de crear rapidamente novos periféricos, módulos, núcleos de procesador;
  • a capacidade de montar un dispositivo virtual a partir de varios módulos;
  • a capacidade de cargar calquera dato binario (firmware) na memoria dun dispositivo virtual;
  • capacidade de traballar con instantáneas (instantáneas do estado do sistema);
  • a capacidade de interactuar co emulador a través do depurador incorporado;
  • boa linguaxe moderna para o desenvolvemento.

Como resultado, escolleuse Kotlin para a implementación, a arquitectura de bus (isto é cando os módulos se comunican entre si a través de buses de datos virtuais), JSON como formato de descrición do dispositivo e GDB RSP como protocolo de interacción co depurador.

O desenvolvemento leva algo máis de dous anos e está en marcha activamente. Durante este tempo, implementáronse núcleos de procesadores MIPS, x86, V850ES, ARM e PowerPC.

O proxecto crece e é hora de presentalo ao público máis amplo. Máis adiante faremos unha descrición detallada do proxecto, pero polo de agora centrarémonos no uso de Kopycat.

Para os máis impacientes, pódese descargar unha versión promocional do emulador Ligazón.

Rhino no emulador

Lembremos que anteriormente para a conferencia SMARTRHINO-2018, creouse un dispositivo de proba "Rhinoceros" para ensinar habilidades de enxeñaría inversa. O proceso de análise de firmware estático foi descrito en Este artigo.

Agora imos tentar engadir "altofalantes" e executar o firmware no emulador.

Necesitaremos:
1) Java 1.8
2) Python e módulo jep para usar Python dentro do emulador. Podes construír o módulo WHL Jep para Windows descargar aquí.

Para Windows:
1) com0com
2) MANTÍA

Para Linux:
1) socat

Podes usar Eclipse, IDA Pro ou radare2 como cliente GDB.

Como funciona isto?

Para realizar o firmware no emulador, é necesario "ensamblar" un dispositivo virtual, que é un análogo dun dispositivo real.

O dispositivo real ("rinoceronte") pódese mostrar no diagrama de bloques:

Rhinoceros inside a cat: executa o firmware no emulador Kopycat

O emulador ten unha estrutura modular e o dispositivo virtual final pódese describir nun ficheiro JSON.

JSON 105 liñas

{
  "top": true,

  // Plugin name should be the same as file name (or full path from library start)
  "plugin": "rhino",

  // Directory where plugin places
  "library": "user",

  // Plugin parameters (constructor parameters if jar-plugin version)
  "params": [
    { "name": "tty_dbg", "type": "String"},
    { "name": "tty_bt", "type": "String"},
    { "name": "firmware", "type": "String", "default": "NUL"}
  ],

  // Plugin outer ports
  "ports": [  ],

  // Plugin internal buses
  "buses": [
    { "name": "mem", "size": "BUS30" },
    { "name": "nand", "size": "4" },
    { "name": "gpio", "size": "BUS32" }
  ],

  // Plugin internal components
  "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" }
  ],

  // Plugin connection between components
  "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"]
  ]
}

Preste atención ao parámetro firmware No capítulo parámetros é o nome dun ficheiro que se pode cargar nun dispositivo virtual como firmware.

O dispositivo virtual e a súa interacción co sistema operativo principal pódense representar no seguinte diagrama:

Rhinoceros inside a cat: executa o firmware no emulador Kopycat

A instancia de proba actual do emulador implica a interacción cos portos COM do sistema operativo principal (depurar UART e UART para o módulo Bluetooth). Estes poden ser portos reais aos que están conectados os dispositivos ou portos COM virtuais (para iso só precisas com0com/socat).

Para interactuar co emulador desde fóra, actualmente hai dúas formas principais:

  • Protocolo GDB RSP (en consecuencia, as ferramentas que admiten este protocolo son Eclipse / IDA / radare2);
  • liña de comandos do emulador interno (Argparse ou Python).

Portos COM virtuais

Para interactuar co UART dun dispositivo virtual na máquina local a través dun terminal, cómpre crear un par de portos COM virtuais asociados. No noso caso, un porto é usado polo emulador e o segundo por un programa de terminal (PuTTY ou pantalla):

Rhinoceros inside a cat: executa o firmware no emulador Kopycat

Usando com0com

Os portos COM virtuais configúranse mediante a utilidade de configuración do kit com0com (versión de consola - C:Arquivos de programas (x86)com0comsetupс.exe, ou versión GUI - C:Arquivos de programas (x86)com0comsetupg.exe):

Rhinoceros inside a cat: executa o firmware no emulador Kopycat

Marque as caixas habilitar a superación do búfer para todos os portos virtuais creados, se non, o emulador agardará unha resposta do porto COM.

Usando socat

Nos sistemas UNIX, os portos COM virtuais son creados automaticamente polo emulador mediante a utilidade socat; para facelo, só tes que especificar o prefixo no nome do porto ao iniciar o emulador. socat:.

Interface de liña de comandos interna (Argparse ou Python)

Dado que Kopycat é unha aplicación de consola, o emulador ofrece dúas opcións de interface de liña de comandos para interactuar cos seus obxectos e variables: Argparse e Python.

Argparse é unha CLI integrada en Kopycat e sempre está dispoñible para todos.

Unha CLI alternativa é o intérprete de Python. Para usalo, cómpre instalar o módulo Jep Python e configurar o emulador para que funcione con Python (utilizarase o intérprete de Python instalado no sistema principal do usuario).

Instalación do módulo Python Jep

En Linux, Jep pódese instalar a través de pip:

pip install jep

Para instalar Jep en Windows, primeiro debes instalar o Windows SDK e o Microsoft Visual Studio correspondente. Fixémosche un pouco máis fácil e WHL constrúe JEP para as versións actuais de Python para Windows, polo que o módulo pódese instalar desde o ficheiro:

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

Para comprobar a instalación de Jep, cómpre executar na liña de comandos:

python -c "import jep"

Debe recibirse a seguinte mensaxe como resposta:

ImportError: Jep is not supported in standalone Python, it must be embedded in Java.

No ficheiro por lotes do emulador para o seu sistema (copycat.bat - para Windows, imitador - para Linux) á lista de parámetros DEFAULT_JVM_OPTS engadir un parámetro adicional Djava.library.path — debe conter a ruta ao módulo Jep instalado.

O resultado para Windows debería ser unha liña como esta:

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

Lanzamento de Kopycat

O emulador é unha aplicación JVM de consola. O lanzamento realízase a través do script de liña de comandos do sistema operativo (sh/cmd).

Comando para executar en Windows:

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

Comando para executar en Linux usando a utilidade 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 — Porto TCP que estará aberto para acceder ao servidor GDB;
  • -n rhino — nome do módulo do sistema principal (dispositivo ensamblado);
  • -l user — nome da biblioteca para buscar o módulo principal;
  • -y library — camiño para buscar módulos incluídos no dispositivo;
  • firmwarerhino_pass.bin — ruta ao ficheiro de firmware;
  • COM26 e COM28 son portos COM virtuais.

Como resultado, amosarase un aviso Python > (Ou Argparse >):

18:07:59 INFO [eFactoryBuilder.create ]: Module top successfully created as top
18:07:59 INFO [ Module.initializeAndRes]: Setup core to top.u1_stm32.cortexm0.arm for top
18:07:59 INFO [ Module.initializeAndRes]: Setup debugger to top.u1_stm32.dbg for top
18:07:59 WARN [ Module.initializeAndRes]: Tracer wasn't found in top...
18:07:59 INFO [ Module.initializeAndRes]: Initializing ports and buses...
18:07:59 WARN [ Module.initializePortsA]: ATTENTION: Some ports has warning use printModulesPortsWarnings to see it...
18:07:59 FINE [ ARMv6CPU.reset ]: Set entry point address to 08006A75
18:07:59 INFO [ Module.initializeAndRes]: Module top is successfully initialized and reset as a top cell!
18:07:59 INFO [ Kopycat.open ]: Starting virtualization of board top[rhino] with arm[ARMv6Core]
18:07:59 INFO [ GDBServer.debuggerModule ]: Set new debugger module top.u1_stm32.dbg for GDB_SERVER(port=23946,alive=true)
Python >

Interacción con IDA Pro

Para simplificar as probas, usamos o firmware Rhino como ficheiro fonte para a análise en IDA no formulario Ficheiro ELF (a meta información almacénase alí).

Tamén pode usar o firmware principal sen metainformación.

Despois de iniciar Kopycat en IDA Pro, no menú Depurador vai ao elemento "Cambiar depurador..."E escolle"Depurador remoto GDB". A continuación, configure a conexión: menú Depurador: opcións de proceso...

Establece os valores:

  • Aplicación - calquera valor
  • Nome de host: 127.0.0.1 (ou o enderezo IP da máquina remota onde se está a executar Kopycat)
  • Porto: 23946

Rhinoceros inside a cat: executa o firmware no emulador Kopycat

Agora o botón de depuración está dispoñible (tecla F9):

Rhinoceros inside a cat: executa o firmware no emulador Kopycat

Fai clic nel para conectarte ao módulo depurador do emulador. IDA entra en modo de depuración, xanelas adicionais están dispoñibles: información sobre rexistros, sobre a pila.

Agora podemos usar todas as funcións estándar do depurador:

  • execución paso a paso de instrucións (Paso en и Paso por riba — teclas F7 e F8, respectivamente);
  • iniciar e deter a execución;
  • creando puntos de interrupción tanto para código como para datos (tecla F2).

Conectarse a un depurador non significa executar o código do firmware. A posición de execución actual debe ser o enderezo 0x08006A74 - inicio da función Reset_Handler. Se te desprazas cara abaixo na listaxe, podes ver a chamada de función Inicio. Pode situar o cursor nesta liña (enderezo 0x08006ABE) e realizar a operación Executar ata o cursor (tecla F4).

Rhinoceros inside a cat: executa o firmware no emulador Kopycat

A continuación, pode premer F7 para entrar na función Inicio.

Se executa o comando Continuar proceso (tecla F9), entón aparecerá a xanela "Espere" cun só botón suspender:

Rhinoceros inside a cat: executa o firmware no emulador Kopycat

Cando preme suspender Suspéndese a execución do código do firmware e pódese continuar dende o mesmo enderezo do código onde foi interrompido.

Se continúas executando o código, verás as seguintes liñas nos terminais conectados aos portos COM virtuais:

Rhinoceros inside a cat: executa o firmware no emulador Kopycat

Rhinoceros inside a cat: executa o firmware no emulador Kopycat

A presenza da liña de "omisión de estado" indica que o módulo Bluetooth virtual cambiou ao modo de recepción de datos do porto COM do usuario.

Agora no terminal Bluetooth (COM29 na imaxe) podes introducir comandos de acordo co protocolo Rhino. Por exemplo, o comando "MEOW" devolverá a cadea "mur-mur" ao terminal Bluetooth:

Rhinoceros inside a cat: executa o firmware no emulador Kopycat

Non me emule completamente

Ao construír un emulador, podes escoller o nivel de detalle/emulación dun dispositivo en particular. Por exemplo, o módulo Bluetooth pódese emular de diferentes xeitos:

  • o dispositivo está totalmente emulado cun conxunto completo de comandos;
  • Os comandos AT son emulados e o fluxo de datos recíbese dende o porto COM do sistema principal;
  • o dispositivo virtual proporciona redirección completa de datos ao dispositivo real;
  • como un simple talón que sempre devolve "OK".

A versión actual do emulador usa o segundo enfoque: o módulo Bluetooth virtual realiza a configuración, despois de que cambia ao modo de "proxy" de datos desde o porto COM do sistema principal ata o porto UART do emulador.

Rhinoceros inside a cat: executa o firmware no emulador Kopycat

Consideremos a posibilidade dunha instrumentación sinxela do código no caso de que non se implemente algunha parte da periferia. Por exemplo, se non se creou un temporizador responsable de controlar a transferencia de datos a DMA (a comprobación realízase na función ws2812b_esperarsituado en 0x08006840), entón o firmware sempre agardará a que se restableza a bandeira ocupadosituado en 0x200004C4que mostra a ocupación da liña de datos DMA:

Rhinoceros inside a cat: executa o firmware no emulador Kopycat

Podemos sortear esta situación restablecendo manualmente a bandeira ocupado inmediatamente despois de instalalo. En IDA Pro, podes crear unha función de Python e chamala nun punto de interrupción e poñer o propio punto de interrupción no código despois de escribir o valor 1 na bandeira ocupado.

Manexador de puntos de interrupción

Primeiro, imos crear unha función Python en IDA. Menú Ficheiro - Comando de script...

Engade un novo fragmento na lista da esquerda, ponlle un nome (por exemplo, BPT),
No campo de texto da dereita, introduza o código da función:

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

Rhinoceros inside a cat: executa o firmware no emulador Kopycat

Despois diso pulsamos Correr e pecha a xanela do script.

Agora imos ao código en 0x0800688A, establece un punto de interrupción (tecla F2), edítao (menú contextual Editar punto de interrupción...), non esquezas establecer o tipo de script en Python:

Rhinoceros inside a cat: executa o firmware no emulador Kopycat
Rhinoceros inside a cat: executa o firmware no emulador Kopycat

Se o valor da bandeira actual ocupado é igual a 1, entón debes executar a función skip_dma na liña de guión:

Rhinoceros inside a cat: executa o firmware no emulador Kopycat

Se executa o firmware para a súa execución, a activación do código do controlador do punto de interrupción pódese ver na xanela IDA Saída por liña Skipping wait ws2812.... Agora o firmware non agardará a que se restableza a bandeira ocupado.

Interacción co emulador

É improbable que a emulación por motivos de emulación cause deleite e alegría. É moito máis interesante se o emulador axuda ao investigador a ver os datos na memoria ou a establecer a interacción dos fíos.

Imos amosarche como establecer dinámicamente a interacción entre as tarefas RTOS. Primeiro debes pausar a execución do código se se está a executar. Se vas á función entrada_tarefa_bluetooth á rama de procesamento do comando "LED" (enderezo 0x080057B8), entón podes ver o que se crea primeiro e despois se envía á cola do sistema ledControlQueueHandle algunha mensaxe.

Rhinoceros inside a cat: executa o firmware no emulador Kopycat

Debe establecer un punto de interrupción para acceder á variable ledControlQueueHandlesituado en 0x20000624 e continúa executando o código:

Rhinoceros inside a cat: executa o firmware no emulador Kopycat

Como resultado, a parada producirase primeiro no enderezo 0x080057CA antes de chamar á función osMailAlloc, despois no enderezo 0x08005806 antes de chamar á función osMailPut, despois dun tempo - ao enderezo 0x08005BD4 (antes de chamar á función osMailGet), que pertence á función entrada_tarefa_leds (tarefa LED), é dicir, as tarefas cambiaron e agora a tarefa LED recibiu o control.

Rhinoceros inside a cat: executa o firmware no emulador Kopycat

Deste xeito sinxelo podes establecer como interactúan as tarefas RTOS entre si.

Por suposto, en realidade, a interacción das tarefas pode ser máis complicada, pero usando un emulador, o seguimento desta interacción faise menos laborioso.

Aquí Podes ver un pequeno vídeo do lanzamento do emulador e da interacción con IDA Pro.

Iniciar con Radare2

Non pode ignorar unha ferramenta tan universal como Radare2.

Para conectarse ao emulador usando r2, o comando sería así:

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

Lanzamento dispoñible agora (dc) e pausar a execución (Ctrl+C).

Desafortunadamente, neste momento, r2 ten problemas ao traballar co servidor gdb de hardware e o deseño da memoria; por iso, os puntos de interrupción e os pasos non funcionan (comando ds). Agardamos que isto se solucione pronto.

Correndo con Eclipse

Unha das opcións para usar o emulador é depurar o firmware do dispositivo que se está a desenvolver. Para máis claridade, tamén usaremos o firmware de Rhino. Podes descargar as fontes do firmware por iso.

Usaremos Eclipse do conxunto como IDE Workbench do sistema para STM32.

Para que o emulador cargue o firmware compilado directamente en Eclipse, cómpre engadir o parámetro firmware=null ao comando de inicio do emulador:

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

Configurando a configuración de depuración

En Eclipse, selecciona o menú Executar - Depurar configuracións... Na xanela que se abre, na sección Depuración de hardware GDB cómpre engadir unha nova configuración e, a continuación, na pestana "Principal" especifique o proxecto e a aplicación actual para a depuración:

Rhinoceros inside a cat: executa o firmware no emulador Kopycat

Na pestana "Depurador" debes especificar o comando GDB:
${openstm32_compiler_path}arm-none-eabi-gdb

E introduza tamén os parámetros para conectarse ao servidor GDB (anfitrión e porto):

Rhinoceros inside a cat: executa o firmware no emulador Kopycat

Na pestana "Inicio", debes especificar os seguintes parámetros:

  • activar a caixa de verificación Cargar imaxe (para que a imaxe do firmware montada se cargue no emulador);
  • activar a caixa de verificación Símbolos de carga;
  • engadir comando de inicio: set $pc = *0x08000004 (configure o rexistro da PC co valor da memoria no enderezo 0x08000004 - o enderezo está almacenado alí ResetHandler).

Preste atención, se non queres descargar o ficheiro de firmware de Eclipse, entón as opcións Cargar imaxe и Executar comandos sen necesidade de indicalo.

Rhinoceros inside a cat: executa o firmware no emulador Kopycat

Despois de facer clic en Depurar, pode traballar no modo depurador:

  • execución de código paso a paso
    Rhinoceros inside a cat: executa o firmware no emulador Kopycat
  • interactuando con puntos de interrupción
    Rhinoceros inside a cat: executa o firmware no emulador Kopycat

Nota. Eclipse ten, hmm... algunhas peculiaridades... e tes que vivir con elas. Por exemplo, se ao iniciar o depurador aparece a mensaxe "Non hai fonte dispoñible para "0x0"", executa o comando Step (F5).

Rhinoceros inside a cat: executa o firmware no emulador Kopycat

En vez de unha conclusión

Emular código nativo é algo moi interesante. É posible que un desenvolvedor de dispositivos depure o firmware sen un dispositivo real. Para un investigador, é unha oportunidade de realizar análise de código dinámico, que non sempre é posible mesmo cun dispositivo.

Queremos ofrecer aos especialistas unha ferramenta cómoda, moderadamente sinxela e que non require moito esforzo e tempo para configurar e executar.

Escribe nos comentarios sobre a túa experiencia usando emuladores de hardware. Convidámoste a discutir e estaremos encantados de responder preguntas.

Só os usuarios rexistrados poden participar na enquisa. Rexístrate, por favor.

Para que estás usando o emulador?

  • Desenvolvo (depuro) firmware

  • Estou investigando o firmware

  • Lanzo xogos (Dendi, Sega, PSP)

  • outra cousa (escribe nos comentarios)

Votaron 7 usuarios. 2 usuarios abstivéronse.

Que software usas para emular código nativo?

  • QEMU

  • Motor unicornio

  • Proteu

  • outra cousa (escribe nos comentarios)

Votaron 6 usuarios. 2 usuarios abstivéronse.

Que che gustaría mellorar no emulador que estás a usar?

  • Quero velocidade

  • Quero facilidade de configuración/lanzamento

  • Quero máis opcións para interactuar co emulador (API, ganchos)

  • Estou feliz con todo

  • outra cousa (escribe nos comentarios)

Votaron 8 usuarios. 1 usuario abstívose.

Fonte: www.habr.com

Engadir un comentario