Rinoceronte dentro un gatto: esegui il firmware nell'emulatore Kopycat

Rinoceronte dentro un gatto: esegui il firmware nell'emulatore Kopycat

Nell'ambito della riunione 0x0A DC7831 DEF CON Nižnij Novgorod Il 16 febbraio abbiamo presentato un rapporto sui principi di base dell'emulazione del codice binario e sul nostro sviluppo: un emulatore di piattaforma hardware Copione.

In questo articolo descriveremo come eseguire il firmware del dispositivo nell'emulatore, dimostrare l'interazione con il debugger ed eseguire una piccola analisi dinamica del firmware.

Sfondo

Tanto tempo fa in una galassia molto lontana

Un paio di anni fa nel nostro laboratorio si è presentata la necessità di indagare sul firmware di un dispositivo. Il firmware è stato compresso e decompresso con un bootloader. Lo ha fatto in un modo molto complicato, spostando più volte i dati in memoria. E il firmware stesso ha quindi interagito attivamente con le periferiche. E tutto questo sul core MIPS.

Per ragioni oggettive, gli emulatori disponibili non erano adatti a noi, ma volevamo comunque eseguire il codice. Quindi abbiamo deciso di creare il nostro emulatore, che avrebbe fatto il minimo e ci avrebbe permesso di decomprimere il firmware principale. L'abbiamo provato e ha funzionato. Abbiamo pensato: e se aggiungessimo periferiche per eseguire anche il firmware principale? Non ha fatto molto male e ha anche funzionato. Ci abbiamo ripensato e abbiamo deciso di creare un emulatore a tutti gli effetti.

Il risultato è stato un emulatore di sistemi informatici Copione.

Rinoceronte dentro un gatto: esegui il firmware nell'emulatore Kopycat
Perché Kopycat?

C'è un gioco di parole.

  1. copione (inglese, sostantivo [ˈkɒpɪkæt]) - imitatore, imitatore
  2. gatto (inglese, sostantivo [ˈkæt]) - gatto, gatto - l'animale preferito di uno dei creatori del progetto
  3. La lettera "K" deriva dal linguaggio di programmazione Kotlin

Copione

Durante la creazione dell'emulatore sono stati fissati obiettivi molto specifici:

  • la capacità di creare rapidamente nuove periferiche, moduli, core del processore;
  • la possibilità di assemblare un dispositivo virtuale da vari moduli;
  • la possibilità di caricare qualsiasi dato binario (firmware) nella memoria di un dispositivo virtuale;
  • capacità di lavorare con istantanee (istantanee dello stato del sistema);
  • la possibilità di interagire con l'emulatore tramite il debugger integrato;
  • bel linguaggio moderno per lo sviluppo.

Di conseguenza, per l'implementazione è stato scelto Kotlin, un'architettura bus (ovvero quando i moduli comunicano tra loro tramite bus dati virtuali), JSON come formato di descrizione del dispositivo e GDB RSP come protocollo per l'interazione con il debugger.

Lo sviluppo è in corso da poco più di due anni ed è attivamente in corso. Durante questo periodo sono stati implementati i core del processore MIPS, x86, V850ES, ARM e PowerPC.

Il progetto sta crescendo ed è giunto il momento di presentarlo al grande pubblico. Faremo una descrizione dettagliata del progetto in seguito, ma per ora ci concentreremo sull'utilizzo di Kopycat.

Per i più impazienti è possibile scaricare una versione promo dell'emulatore da collegamento.

Rhino nell'emulatore

Ricordiamo che in precedenza, per la conferenza SMARTRHINO-2018, è stato creato un dispositivo di prova "Rhinoceros" per insegnare abilità di reverse engineering. Il processo di analisi statica del firmware è stato descritto in questo articolo.

Ora proviamo ad aggiungere "altoparlanti" ed eseguire il firmware nell'emulatore.

Abbiamo bisogno di:
1) Java1.8
2) Python e modulo jep per usare Python all'interno dell'emulatore. Puoi creare il modulo WHL Jep per Windows scarica qui.

Per Windows:
1) com0com
2) PuTTY

Per Linux:
1) socat

Puoi utilizzare Eclipse, IDA Pro o radare2 come client GDB.

Come funziona?

Per eseguire il firmware nell'emulatore, è necessario "assemblare" un dispositivo virtuale, che è un analogo di un dispositivo reale.

Il dispositivo reale (“rinoceronte”) può essere mostrato nello schema a blocchi:

Rinoceronte dentro un gatto: esegui il firmware nell'emulatore Kopycat

L'emulatore ha una struttura modulare e il dispositivo virtuale finale può essere descritto in un file JSON.

JSON 105 righe

{
  "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"]
  ]
}

Prestare attenzione al parametro firmware sezione params è il nome di un file che può essere caricato in un dispositivo virtuale come firmware.

Il dispositivo virtuale e la sua interazione con il sistema operativo principale possono essere rappresentati dal seguente diagramma:

Rinoceronte dentro un gatto: esegui il firmware nell'emulatore Kopycat

L'attuale istanza di test dell'emulatore prevede l'interazione con le porte COM del sistema operativo principale (debug UART e UART per il modulo Bluetooth). Queste possono essere porte reali a cui sono collegati i dispositivi o porte COM virtuali (per questo è sufficiente com0com/socat).

Attualmente esistono due modalità principali per interagire con l'emulatore dall'esterno:

  • Protocollo GDB RSP (di conseguenza, gli strumenti che supportano questo protocollo sono Eclipse / IDA / radare2);
  • riga di comando dell'emulatore interno (Argparse o Python).

Porte COM virtuali

Per interagire con l'UART di un dispositivo virtuale sulla macchina locale tramite un terminale, è necessario creare una coppia di porte COM virtuali associate. Nel nostro caso, una porta viene utilizzata dall'emulatore e la seconda da un programma terminale (PuTTY o schermo):

Rinoceronte dentro un gatto: esegui il firmware nell'emulatore Kopycat

Utilizzando com0com

Le porte COM virtuali vengono configurate utilizzando l'utilità di configurazione del kit com0com (versione console - C:Programmi (x86)com0comsetupс.exe, o versione GUI - C:Programmi (x86)com0comsetupg.exe):

Rinoceronte dentro un gatto: esegui il firmware nell'emulatore Kopycat

Seleziona le caselle abilitare il sovraccarico del buffer per tutte le porte virtuali create, altrimenti l'emulatore attenderà una risposta dalla porta COM.

Utilizzando socat

Sui sistemi UNIX le porte COM virtuali vengono create automaticamente dall'emulatore tramite l'utility socat; per fare ciò basta specificare il prefisso nel nome della porta all'avvio dell'emulatore socat:.

Interfaccia a riga di comando interna (Argparse o Python)

Poiché Kopycat è un'applicazione console, l'emulatore fornisce due opzioni di interfaccia a riga di comando per interagire con i suoi oggetti e variabili: Argparse e Python.

Argparse è una CLI integrata in Kopycat ed è sempre disponibile per tutti.

Una CLI alternativa è l'interprete Python. Per usarlo, è necessario installare il modulo Jep Python e configurare l'emulatore per funzionare con Python (verrà utilizzato l'interprete Python installato sul sistema principale dell'utente).

Installazione del modulo Python Jep

Sotto Linux Jep può essere installato tramite pip:

pip install jep

Per installare Jep su Windows è necessario prima installare Windows SDK e il corrispondente Microsoft Visual Studio. Abbiamo reso le cose un po' più facili per te e WHL costruisce JEP per le versioni attuali di Python per Windows, quindi il modulo può essere installato dal file:

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

Per verificare l'installazione di Jep è necessario eseguire da riga di comando:

python -c "import jep"

In risposta si dovrebbe ricevere il seguente messaggio:

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

Nel file batch dell'emulatore per il tuo sistema (copycat.bat - per Windows, copione - per Linux) all'elenco dei parametri DEFAULT_JVM_OPTS aggiungere un ulteriore parametro Djava.library.path — deve contenere il percorso del modulo Jep installato.

Il risultato per Windows dovrebbe essere una riga come questa:

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

Avvio di Kopycat

L'emulatore è un'applicazione JVM console. L'avvio viene effettuato tramite lo script della riga di comando del sistema operativo (sh/cmd).

Comando da eseguire in Windows:

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

Comando da eseguire sotto Linux utilizzando l'utilità 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 — Porta TCP che sarà aperta per l'accesso al server GDB;
  • -n rhino — nome del modulo principale del sistema (dispositivo assemblato);
  • -l user — nome della libreria in cui ricercare il modulo principale;
  • -y library — percorso per la ricerca dei moduli presenti nel dispositivo;
  • firmwarerhino_pass.bin — percorso del file del firmware;
  • COM26 e COM28 sono porte COM virtuali.

Di conseguenza, verrà visualizzato un messaggio Python > (o 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 >

Interazione con IDA Pro

Per semplificare i test, utilizziamo il firmware Rhino come file sorgente per l'analisi in IDA nel modulo File ELF (le meta informazioni sono memorizzate lì).

È inoltre possibile utilizzare il firmware principale senza metainformazioni.

Dopo aver avviato Kopycat in IDA Pro, nel menu Debugger vai alla voce “Cambia debugger..." e seleziona "Debugger GDB remoto". Successivamente, imposta la connessione: menu Debugger - Opzioni di processo…

Imposta i valori:

  • Applicazione: qualsiasi valore
  • Nome host: 127.0.0.1 (o l'indirizzo IP del computer remoto su cui è in esecuzione Kopycat)
  • Porto: 23946

Rinoceronte dentro un gatto: esegui il firmware nell'emulatore Kopycat

Ora il pulsante di debug diventa disponibile (tasto F9):

Rinoceronte dentro un gatto: esegui il firmware nell'emulatore Kopycat

Fare clic per connettersi al modulo debugger nell'emulatore. IDA entra in modalità debug, diventano disponibili finestre aggiuntive: informazioni sui registri, sullo stack.

Ora possiamo utilizzare tutte le funzionalità standard del debugger:

  • esecuzione passo passo delle istruzioni (Entra и Scavalcare — rispettivamente i tasti F7 e F8);
  • avviare e sospendere l'esecuzione;
  • creazione di punti di interruzione sia per il codice che per i dati (tasto F2).

La connessione a un debugger non significa eseguire il codice del firmware. La posizione di esecuzione corrente deve essere l'indirizzo 0x08006A74 — inizio della funzione Reset_Handler. Se scorri l'elenco verso il basso, puoi vedere la chiamata alla funzione principale. È possibile posizionare il cursore su questa riga (indirizzo 0x08006ABE) ed eseguire l'operazione Esegui fino al cursore (tasto F4).

Rinoceronte dentro un gatto: esegui il firmware nell'emulatore Kopycat

Successivamente, puoi premere F7 per accedere alla funzione principale.

Se esegui il comando Continua il processo (tasto F9), quindi verrà visualizzata la finestra "Attendere" con un solo pulsante Sospendere:

Rinoceronte dentro un gatto: esegui il firmware nell'emulatore Kopycat

Quando premuto Sospendere l'esecuzione del codice firmware è sospesa e può essere ripresa dallo stesso indirizzo presente nel codice dove è stata interrotta.

Se prosegui nell'esecuzione del codice, nei terminali collegati alle porte COM virtuali vedrai le seguenti righe:

Rinoceronte dentro un gatto: esegui il firmware nell'emulatore Kopycat

Rinoceronte dentro un gatto: esegui il firmware nell'emulatore Kopycat

La presenza della linea "state bypass" indica che il modulo Bluetooth virtuale è passato alla modalità di ricezione dati dalla porta COM dell'utente.

Ora nel terminale Bluetooth (COM29 nella foto) puoi inserire comandi secondo il protocollo Rhino. Ad esempio, il comando “MEOW” restituirà la stringa “mur-mur” al terminale Bluetooth:

Rinoceronte dentro un gatto: esegui il firmware nell'emulatore Kopycat

Emulami non del tutto

Quando crei un emulatore, puoi scegliere il livello di dettaglio/emulazione di un particolare dispositivo. Ad esempio, il modulo Bluetooth può essere emulato in diversi modi:

  • il dispositivo è completamente emulato con un set completo di comandi;
  • I comandi AT vengono emulati e il flusso di dati viene ricevuto dalla porta COM del sistema principale;
  • il dispositivo virtuale fornisce il reindirizzamento completo dei dati al dispositivo reale;
  • come un semplice stub che restituisce sempre "OK".

La versione attuale dell'emulatore utilizza il secondo approccio: il modulo Bluetooth virtuale esegue la configurazione, dopodiché passa alla modalità di "proxying" dei dati dalla porta COM del sistema principale alla porta UART dell'emulatore.

Rinoceronte dentro un gatto: esegui il firmware nell'emulatore Kopycat

Consideriamo la possibilità di una semplice strumentazione del codice nel caso in cui qualche parte della periferia non sia implementata. Ad esempio, se non è stato creato un timer responsabile del controllo del trasferimento dei dati al DMA (il controllo viene eseguito nella funzione ws2812b_aspettasituato in 0x08006840), il firmware attenderà sempre il ripristino del flag occupatosituato in 0x200004C4che mostra l'occupazione della linea dati DMA:

Rinoceronte dentro un gatto: esegui il firmware nell'emulatore Kopycat

Possiamo aggirare questa situazione reimpostando manualmente il flag occupato subito dopo averlo installato. In IDA Pro, puoi creare una funzione Python e chiamarla in un punto di interruzione e inserire il punto di interruzione stesso nel codice dopo aver scritto il valore 1 nel flag occupato.

Gestore del punto di interruzione

Innanzitutto, creiamo una funzione Python in IDA. Menù File - Comando script...

Aggiungi un nuovo snippet nell'elenco a sinistra, dagli un nome (ad esempio, BPT),
Nel campo di testo a destra, inserisci il codice funzione:

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

Rinoceronte dentro un gatto: esegui il firmware nell'emulatore Kopycat

Dopodiché premiamo Correre e chiudi la finestra dello script.

Ora passiamo al codice su 0x0800688A, imposta un punto di interruzione (tasto F2), modificalo (menu contestuale Modifica punto di interruzione...), non dimenticare di impostare il tipo di script su Python:

Rinoceronte dentro un gatto: esegui il firmware nell'emulatore Kopycat
Rinoceronte dentro un gatto: esegui il firmware nell'emulatore Kopycat

Se il valore del flag corrente occupato è uguale a 1, allora dovresti eseguire la funzione skip_dma nella riga di script:

Rinoceronte dentro un gatto: esegui il firmware nell'emulatore Kopycat

Se si esegue il firmware per l'esecuzione, l'attivazione del codice del gestore del breakpoint può essere vista nella finestra IDA Uscita per linea Skipping wait ws2812.... Ora il firmware non attenderà il ripristino del flag occupato.

Interazione con l'emulatore

È improbabile che l'emulazione fine a se stessa provochi gioia e gioia. È molto più interessante se l'emulatore aiuta il ricercatore a vedere i dati in memoria o a stabilire l'interazione dei thread.

Ti mostreremo come stabilire dinamicamente l'interazione tra le attività RTOS. Dovresti prima mettere in pausa l'esecuzione del codice se è in esecuzione. Se vai alla funzione voce_attività_bluetooth al ramo di elaborazione del comando “LED” (indirizzo 0x080057B8), allora potrai vedere cosa viene prima creato e poi inviato alla coda di sistema ledControlQueueHandle qualche messaggio.

Rinoceronte dentro un gatto: esegui il firmware nell'emulatore Kopycat

Dovresti impostare un punto di interruzione per accedere alla variabile ledControlQueueHandlesituato in 0x20000624 e continua con l'esecuzione del codice:

Rinoceronte dentro un gatto: esegui il firmware nell'emulatore Kopycat

Di conseguenza, la fermata avverrà prima all'indirizzo 0x080057CA prima di chiamare la funzione osMailAlloc, poi all'indirizzo 0x08005806 prima di chiamare la funzione osMailPut, poi dopo un po '- all'indirizzo 0x08005BD4 (prima di chiamare la funzione osMailGet), che appartiene alla funzione leds_task_entry (attività LED), ovvero le attività sono cambiate e ora l'attività LED ha ricevuto il controllo.

Rinoceronte dentro un gatto: esegui il firmware nell'emulatore Kopycat

In questo modo semplice puoi stabilire come i task RTOS interagiscono tra loro.

Naturalmente, in realtà, l'interazione delle attività può essere più complicata, ma utilizzando un emulatore, tracciare questa interazione diventa meno laborioso.

Qui Puoi guardare un breve video dell'avvio dell'emulatore e dell'interazione con IDA Pro.

Avvia con Radare2

Non puoi ignorare uno strumento così universale come Radare2.

Per connettersi all'emulatore utilizzando r2, il comando sarebbe simile al seguente:

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

Lancio disponibile ora (dc) e sospendere l'esecuzione (Ctrl+C).

Purtroppo al momento r2 ha problemi nel lavorare con il server hardware gdb e il layout della memoria; per questo motivo i breakpoint e gli Step non funzionano (comando ds). Ci auguriamo che questo venga risolto presto.

Correre con Eclipse

Una delle opzioni per utilizzare l'emulatore è eseguire il debug del firmware del dispositivo in fase di sviluppo. Per chiarezza utilizzeremo anche il firmware Rhino. È possibile scaricare i sorgenti del firmware quindi.

Utilizzeremo Eclipse dal set come IDE Workbench di sistema per STM32.

Affinché l'emulatore possa caricare il firmware compilato direttamente in Eclipse, è necessario aggiungere il parametro firmware=null al comando di avvio dell'emulatore:

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

Impostazione della configurazione di debug

In Eclipse, seleziona il menu Esegui - Debug configurazioni... Nella finestra che si apre, nella sezione Debug hardware GDB è necessario aggiungere una nuova configurazione, quindi nella scheda "Principale" specificare il progetto corrente e l'applicazione per il debug:

Rinoceronte dentro un gatto: esegui il firmware nell'emulatore Kopycat

Nella scheda "Debugger" è necessario specificare il comando GDB:
${openstm32_compiler_path}arm-none-eabi-gdb

E inserisci anche i parametri per la connessione al server GDB (host e porta):

Rinoceronte dentro un gatto: esegui il firmware nell'emulatore Kopycat

Nella scheda “Avvio”, è necessario specificare i seguenti parametri:

  • abilita la casella di controllo Carica immagine (in modo che l'immagine del firmware assemblato venga caricata nell'emulatore);
  • abilita la casella di controllo Carica simboli;
  • aggiungi il comando di avvio: set $pc = *0x08000004 (impostare il registro PC sul valore dalla memoria all'indirizzo 0x08000004 - L'indirizzo è memorizzato lì ResetHandler).

Nota, se non desideri scaricare il file del firmware da Eclipse, le opzioni Carica immagine и Esegui comandi non c'è bisogno di indicarlo.

Rinoceronte dentro un gatto: esegui il firmware nell'emulatore Kopycat

Dopo aver fatto clic su Debug, puoi lavorare in modalità debugger:

  • esecuzione del codice passo dopo passo
    Rinoceronte dentro un gatto: esegui il firmware nell'emulatore Kopycat
  • interagire con i punti di interruzione
    Rinoceronte dentro un gatto: esegui il firmware nell'emulatore Kopycat

Nota. Eclipse ha, hmm... alcune stranezze... e devi conviverci. Ad esempio, se all'avvio del debugger appare il messaggio “Nessuna sorgente disponibile per “0x0″”, allora eseguire il comando Step (F5)

Rinoceronte dentro un gatto: esegui il firmware nell'emulatore Kopycat

Invece di una conclusione

Emulare il codice nativo è una cosa molto interessante. Diventa possibile per uno sviluppatore di dispositivi eseguire il debug del firmware senza un dispositivo reale. Per un ricercatore è un'opportunità per condurre analisi dinamiche del codice, cosa che non sempre è possibile nemmeno con un dispositivo.

Vogliamo fornire agli specialisti uno strumento che sia conveniente, moderatamente semplice e che non richieda molto tempo e impegno per la configurazione e l'esecuzione.

Scrivi nei commenti la tua esperienza con gli emulatori hardware. Vi invitiamo a discutere e saremo felici di rispondere alle domande.

Solo gli utenti registrati possono partecipare al sondaggio. AccediPer favore.

Per cosa stai usando l'emulatore?

  • Sviluppo (debug) firmware

  • Sto ricercando il firmware

  • Lancio giochi (Dendi, Sega, PSP)

  • qualcos'altro (scrivi nei commenti)

7 utenti hanno votato. 2 utenti si sono astenuti.

Quale software usi per emulare il codice nativo?

  • QEMU

  • Motore dell'unicorno

  • Proteus

  • qualcos'altro (scrivi nei commenti)

6 utenti hanno votato. 2 utenti si sono astenuti.

Cosa vorresti migliorare nell'emulatore che stai utilizzando?

  • Voglio velocità

  • Voglio facilità di installazione/avvio

  • Voglio più opzioni per interagire con l'emulatore (API, hook)

  • Sono felice di tutto

  • qualcos'altro (scrivi nei commenti)

8 utenti hanno votato. 1 utente si è astenuto.

Fonte: habr.com

Aggiungi un commento