Nashorn in einer Katze – Führen Sie die Firmware im Kopycat-Emulator aus

Nashorn in einer Katze – Führen Sie die Firmware im Kopycat-Emulator aus

Im Rahmen des Treffens 0x0A DC7831 DEF CON Nischni Nowgorod Am 16. Februar präsentierten wir einen Bericht über die Grundprinzipien der Binärcode-Emulation und unsere eigene Entwicklung – einen Hardware-Plattform-Emulator Nachahmer.

In diesem Artikel beschreiben wir, wie Sie die Geräte-Firmware im Emulator ausführen, demonstrieren die Interaktion mit dem Debugger und führen eine kurze dynamische Analyse der Firmware durch.

Vorgeschichte

Vor langer Zeit in einer weit entfernten Galaxie

Vor ein paar Jahren bestand in unserem Labor die Notwendigkeit, die Firmware eines Geräts zu untersuchen. Die Firmware wurde mit einem Bootloader komprimiert und entpackt. Er tat dies auf sehr komplizierte Weise, indem er die Daten im Speicher mehrmals verschob. Und die Firmware selbst interagierte dann aktiv mit den Peripheriegeräten. Und das alles auf dem MIPS-Kern.

Aus objektiven Gründen passten uns die verfügbaren Emulatoren nicht, wir wollten den Code aber trotzdem ausführen. Dann beschlossen wir, einen eigenen Emulator zu erstellen, der das Minimum tun und es uns ermöglichen würde, die Haupt-Firmware zu entpacken. Wir haben es versucht und es hat funktioniert. Wir dachten, was wäre, wenn wir Peripheriegeräte hinzufügen würden, um auch die Haupt-Firmware auszuführen? Es tat nicht sehr weh – und es hat auch geklappt. Wir dachten noch einmal darüber nach und beschlossen, einen vollwertigen Emulator zu entwickeln.

Das Ergebnis war ein Computersystem-Emulator Nachahmer.

Nashorn in einer Katze – Führen Sie die Firmware im Kopycat-Emulator aus
Warum Kopycat?

Es gibt ein Wortspiel.

  1. Nachahmer (Englisch, Substantiv [ˈkɒpɪkæt]) – Nachahmer, Nachahmer
  2. Katze (Englisch, Substantiv [ˈkæt]) – Katze, Katze – das Lieblingstier eines der Schöpfer des Projekts
  3. Der Buchstabe „K“ stammt aus der Programmiersprache Kotlin

Nachahmer

Bei der Erstellung des Emulators wurden ganz konkrete Ziele festgelegt:

  • die Fähigkeit, schnell neue Peripheriegeräte, Module und Prozessorkerne zu erstellen;
  • die Fähigkeit, ein virtuelles Gerät aus verschiedenen Modulen zusammenzustellen;
  • die Möglichkeit, beliebige Binärdaten (Firmware) in den Speicher eines virtuellen Geräts zu laden;
  • Fähigkeit, mit Snapshots (Momentaufnahmen des Systemzustands) zu arbeiten;
  • die Möglichkeit, über den integrierten Debugger mit dem Emulator zu interagieren;
  • schöne moderne Sprache für die Entwicklung.

Als Ergebnis wurden Kotlin für die Implementierung, die Busarchitektur (d. h. Module kommunizieren untereinander über virtuelle Datenbusse), JSON als Gerätebeschreibungsformat und GDB RSP als Protokoll für die Interaktion mit dem Debugger ausgewählt.

Die Entwicklung läuft seit etwas mehr als zwei Jahren und wird aktiv fortgesetzt. In dieser Zeit wurden MIPS-, x86-, V850ES-, ARM- und PowerPC-Prozessorkerne implementiert.

Das Projekt wächst und es ist Zeit, es der breiten Öffentlichkeit vorzustellen. Wir werden das Projekt später noch ausführlicher beschreiben, konzentrieren uns aber vorerst auf die Verwendung von Kopycat.

Für die Ungeduldigsten kann eine Promo-Version des Emulators heruntergeladen werden Link.

Rhino im Emulator

Erinnern wir uns daran, dass früher für die SMARTRHINO-2018-Konferenz ein Testgerät „Rhinoceros“ zur Vermittlung von Reverse-Engineering-Fähigkeiten entwickelt wurde. Der Prozess der statischen Firmware-Analyse wurde in beschrieben Dieser Artikel.

Versuchen wir nun, „Lautsprecher“ hinzuzufügen und die Firmware im Emulator auszuführen.

Wir brauchen:
1) Java 1.8
2) Python und Modul Jepp um Python im Emulator zu verwenden. Sie können das WHL-Modul Jep für Windows erstellen hier herunterladen.

Für Windows:
1) com0com
2) PuTTY

Für Linux:
1) sokat

Als GDB-Client können Sie Eclipse, IDA Pro oder Radare2 verwenden.

Wie funktioniert es?

Um Firmware im Emulator auszuführen, muss ein virtuelles Gerät „zusammengebaut“ werden, das ein Analogon eines realen Geräts ist.

Das reale Gerät („Rhino“) kann im Blockdiagramm dargestellt werden:

Nashorn in einer Katze – Führen Sie die Firmware im Kopycat-Emulator aus

Der Emulator ist modular aufgebaut und das endgültige virtuelle Gerät kann in einer JSON-Datei beschrieben werden.

JSON 105 Zeilen

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

Achten Sie auf den Parameter Firmware in Abschnitt params ist der Name einer Datei, die als Firmware in ein virtuelles Gerät geladen werden kann.

Das virtuelle Gerät und seine Interaktion mit dem Hauptbetriebssystem können durch das folgende Diagramm dargestellt werden:

Nashorn in einer Katze – Führen Sie die Firmware im Kopycat-Emulator aus

Die aktuelle Testinstanz des Emulators beinhaltet die Interaktion mit den COM-Ports des Hauptbetriebssystems (Debug-UART und UART für das Bluetooth-Modul). Dies können reale Ports sein, an die Geräte angeschlossen sind, oder virtuelle COM-Ports (dafür benötigen Sie lediglich com0com/socat).

Derzeit gibt es hauptsächlich zwei Möglichkeiten, von außen mit dem Emulator zu interagieren:

  • GDB RSP-Protokoll (entsprechend sind die Tools, die dieses Protokoll unterstützen, Eclipse / IDA / Radare2);
  • Interne Emulator-Befehlszeile (Argparse oder Python).

Virtuelle COM-Ports

Um über ein Terminal mit dem UART eines virtuellen Geräts auf der lokalen Maschine zu interagieren, müssen Sie ein Paar zugehöriger virtueller COM-Ports erstellen. In unserem Fall wird ein Port vom Emulator und der zweite von einem Terminalprogramm (PuTTY oder Screen) verwendet:

Nashorn in einer Katze – Führen Sie die Firmware im Kopycat-Emulator aus

Mit com0com

Virtuelle COM-Ports werden mit dem Setup-Dienstprogramm aus dem com0com-Kit (Konsolenversion - C:Programme (x86)com0comsetupс.exe, oder GUI-Version - C:Programme (x86)com0comsetupg.exe):

Nashorn in einer Katze – Führen Sie die Firmware im Kopycat-Emulator aus

Markiere das Feld Pufferüberlauf aktivieren für alle erstellten virtuellen Ports, andernfalls wartet der Emulator auf eine Antwort vom COM-Port.

Mit socat

Auf UNIX-Systemen werden virtuelle COM-Ports automatisch vom Emulator mit dem Dienstprogramm socat erstellt; dazu reicht es aus, beim Starten des Emulators das Präfix im Portnamen anzugeben socat:.

Interne Befehlszeilenschnittstelle (Argparse oder Python)

Da es sich bei Kopycat um eine Konsolenanwendung handelt, bietet der Emulator zwei Befehlszeilenschnittstellenoptionen für die Interaktion mit seinen Objekten und Variablen: Argparse und Python.

Argparse ist eine in Kopycat integrierte CLI und steht jederzeit allen zur Verfügung.

Eine alternative CLI ist der Python-Interpreter. Um es zu verwenden, müssen Sie das Jep-Python-Modul installieren und den Emulator für die Arbeit mit Python konfigurieren (es wird der auf dem Hauptsystem des Benutzers installierte Python-Interpreter verwendet).

Installation des Python-Moduls Jep

Unter Linux kann Jep per pip installiert werden:

pip install jep

Um Jep unter Windows zu installieren, müssen Sie zunächst das Windows SDK und das entsprechende Microsoft Visual Studio installieren. Wir haben es für Sie etwas einfacher gemacht und WHL baut JEP für aktuelle Versionen von Python für Windows, daher kann das Modul aus der Datei installiert werden:

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

Um die Installation von Jep zu überprüfen, müssen Sie Folgendes in der Befehlszeile ausführen:

python -c "import jep"

Als Antwort sollte die folgende Nachricht eingehen:

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

In der Emulator-Batchdatei für Ihr System (copycat.bat - für Windows, Nachahmer - für Linux) zur Liste der Parameter hinzufügen DEFAULT_JVM_OPTS Fügen Sie einen zusätzlichen Parameter hinzu Djava.library.path — Es muss den Pfad zum installierten Jep-Modul enthalten.

Das Ergebnis für Windows sollte eine Zeile wie diese sein:

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

Kopycat starten

Der Emulator ist eine Konsolen-JVM-Anwendung. Der Start erfolgt über das Betriebssystem-Befehlszeilenskript (sh/cmd).

Befehl zur Ausführung unter Windows:

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

Befehl zur Ausführung unter Linux mit dem Dienstprogramm 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 — TCP-Port, der für den Zugriff auf den GDB-Server geöffnet ist;
  • -n rhino — Name des Hauptsystemmoduls (zusammengebautes Gerät);
  • -l user — Name der Bibliothek, in der nach dem Hauptmodul gesucht werden soll;
  • -y library – Pfad zur Suche nach im Gerät enthaltenen Modulen;
  • firmwarerhino_pass.bin — Pfad zur Firmware-Datei;
  • COM26 und COM28 sind virtuelle COM-Ports.

Als Ergebnis wird eine Eingabeaufforderung angezeigt Python > (oder 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 >

Interaktion mit IDA Pro

Um das Testen zu vereinfachen, verwenden wir die Rhino-Firmware als Quelldatei für die Analyse in IDA im Formular ELF-Datei (Dort werden Metainformationen gespeichert).

Sie können die Hauptfirmware auch ohne Metainformationen verwenden.

Nachdem Sie Kopycat in IDA Pro gestartet haben, gehen Sie im Debugger-Menü auf den Punkt „Debugger wechseln…" und wählen Sie "Remote-GDB-Debugger". Als nächstes richten Sie die Verbindung ein: Menü Debugger – Prozessoptionen…

Legen Sie die Werte fest:

  • Anwendung – beliebiger Wert
  • Hostname: 127.0.0.1 (oder die IP-Adresse des Remote-Computers, auf dem Kopycat ausgeführt wird)
  • Hafen: 23946

Nashorn in einer Katze – Führen Sie die Firmware im Kopycat-Emulator aus

Jetzt ist die Debugging-Schaltfläche verfügbar (F9-Taste):

Nashorn in einer Katze – Führen Sie die Firmware im Kopycat-Emulator aus

Klicken Sie darauf, um eine Verbindung zum Debugger-Modul im Emulator herzustellen. IDA geht in den Debugging-Modus, zusätzliche Fenster werden verfügbar: Informationen zu Registern, zum Stack.

Jetzt können wir alle Standardfunktionen des Debuggers nutzen:

  • Schritt-für-Schritt-Ausführung der Anweisungen (Hineinsteigen и Schritt über — Tasten F7 bzw. F8);
  • Starten und Anhalten der Ausführung;
  • Erstellen von Haltepunkten für Code und Daten (F2-Taste).

Das Herstellen einer Verbindung zu einem Debugger bedeutet nicht, dass der Firmware-Code ausgeführt wird. Die aktuelle Ausführungsposition muss die Adresse sein 0x08006A74 — Funktionsbeginn Reset_Handler. Wenn Sie in der Liste nach unten scrollen, können Sie den Funktionsaufruf sehen Haupt-. Sie können den Cursor auf diese Zeile (Adresse) setzen 0x08006ABE) und führen Sie den Vorgang aus Laufen bis zum Cursor (Taste F4).

Nashorn in einer Katze – Führen Sie die Firmware im Kopycat-Emulator aus

Als nächstes können Sie F7 drücken, um die Funktion aufzurufen Haupt-.

Wenn Sie den Befehl ausführen Vorgang fortsetzen (Taste F9), dann erscheint das Fenster „Bitte warten“ mit einer einzigen Schaltfläche Aussetzen:

Nashorn in einer Katze – Führen Sie die Firmware im Kopycat-Emulator aus

Wenn Sie drücken Aussetzen Die Ausführung des Firmware-Codes wird ausgesetzt und kann an derselben Adresse im Code fortgesetzt werden, an der sie unterbrochen wurde.

Wenn Sie den Code weiter ausführen, sehen Sie in den Terminals, die mit den virtuellen COM-Ports verbunden sind, die folgenden Zeilen:

Nashorn in einer Katze – Führen Sie die Firmware im Kopycat-Emulator aus

Nashorn in einer Katze – Führen Sie die Firmware im Kopycat-Emulator aus

Das Vorhandensein der Zeile „State Bypass“ zeigt an, dass das virtuelle Bluetooth-Modul in den Modus zum Empfangen von Daten vom COM-Port des Benutzers gewechselt ist.

Nun können Sie im Bluetooth-Terminal (COM29 im Bild) Befehle gemäß dem Rhino-Protokoll eingeben. Der Befehl „MEOW“ gibt beispielsweise die Zeichenfolge „mur-mur“ an das Bluetooth-Terminal zurück:

Nashorn in einer Katze – Führen Sie die Firmware im Kopycat-Emulator aus

Eifere mir nicht ganz nach

Beim Erstellen eines Emulators können Sie den Detaillierungsgrad/die Emulation eines bestimmten Geräts auswählen. Beispielsweise kann das Bluetooth-Modul auf verschiedene Arten emuliert werden:

  • Das Gerät ist vollständig emuliert und verfügt über einen vollständigen Befehlssatz.
  • AT-Befehle werden emuliert und der Datenstrom wird vom COM-Port des Hauptsystems empfangen;
  • das virtuelle Gerät bietet eine vollständige Datenumleitung zum realen Gerät;
  • als einfacher Stub, der immer „OK“ zurückgibt.

Die aktuelle Version des Emulators verwendet den zweiten Ansatz: Das virtuelle Bluetooth-Modul führt die Konfiguration durch und wechselt anschließend in den Modus zum „Proxy“ von Daten vom COM-Port des Hauptsystems zum UART-Port des Emulators.

Nashorn in einer Katze – Führen Sie die Firmware im Kopycat-Emulator aus

Betrachten wir die Möglichkeit einer einfachen Instrumentierung des Codes für den Fall, dass ein Teil der Peripherie nicht implementiert ist. Wenn beispielsweise kein Timer erstellt wurde, der für die Steuerung der Datenübertragung an DMA verantwortlich ist, wird die Prüfung in der Funktion durchgeführt ws2812b_waitbefindet sich 0x08006840), dann wartet die Firmware immer auf das Zurücksetzen des Flags beschäftigtbefindet sich 0x200004C4was die Belegung der DMA-Datenleitung zeigt:

Nashorn in einer Katze – Führen Sie die Firmware im Kopycat-Emulator aus

Wir können diese Situation umgehen, indem wir die Flagge manuell zurücksetzen beschäftigt direkt nach der Installation. In IDA Pro können Sie eine Python-Funktion erstellen und diese an einem Haltepunkt aufrufen und den Haltepunkt selbst in den Code einfügen, nachdem Sie den Wert 1 in das Flag geschrieben haben beschäftigt.

Haltepunkthandler

Erstellen wir zunächst eine Python-Funktion in IDA. Speisekarte Datei – Skriptbefehl...

Fügen Sie in der Liste links ein neues Snippet hinzu und geben Sie ihm einen Namen (z. B. BPT),
Geben Sie im Textfeld rechts den Funktionscode ein:

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

Nashorn in einer Katze – Führen Sie die Firmware im Kopycat-Emulator aus

Danach drücken wir Führen Sie und schließen Sie das Skriptfenster.

Kommen wir nun zum Code unter 0x0800688A, einen Haltepunkt setzen (F2-Taste), ihn bearbeiten (Kontextmenü). Haltepunkt bearbeiten...), vergessen Sie nicht, den Skripttyp auf Python zu setzen:

Nashorn in einer Katze – Führen Sie die Firmware im Kopycat-Emulator aus
Nashorn in einer Katze – Führen Sie die Firmware im Kopycat-Emulator aus

Wenn der aktuelle Flag-Wert beschäftigt gleich 1 ist, dann sollten Sie die Funktion ausführen überspringen_dma in der Skriptzeile:

Nashorn in einer Katze – Führen Sie die Firmware im Kopycat-Emulator aus

Wenn Sie die Firmware zur Ausführung ausführen, ist die Auslösung des Breakpoint-Handler-Codes im IDA-Fenster zu sehen Output nach Zeile Skipping wait ws2812.... Jetzt wartet die Firmware nicht mehr auf das Zurücksetzen des Flags beschäftigt.

Interaktion mit dem Emulator

Es ist unwahrscheinlich, dass Nachahmung um der Nachahmung willen Freude und Freude hervorruft. Viel interessanter ist es, wenn der Emulator dem Forscher hilft, die Daten im Speicher anzuzeigen oder die Interaktion von Threads festzustellen.

Wir zeigen Ihnen, wie Sie die Interaktion zwischen RTOS-Aufgaben dynamisch herstellen. Sie sollten zunächst die Ausführung des Codes anhalten, falls er ausgeführt wird. Wenn Sie zur Funktion gehen bluetooth_task_entry zum Verarbeitungszweig des Befehls „LED“ (Adresse 0x080057B8), dann können Sie sehen, was zuerst erstellt und dann an die Systemwarteschlange gesendet wird ledControlQueueHandle eine Nachricht.

Nashorn in einer Katze – Führen Sie die Firmware im Kopycat-Emulator aus

Sie sollten einen Haltepunkt festlegen, um auf die Variable zuzugreifen ledControlQueueHandlebefindet sich 0x20000624 und fahren Sie mit der Ausführung des Codes fort:

Nashorn in einer Katze – Führen Sie die Firmware im Kopycat-Emulator aus

Dadurch erfolgt der Stopp zunächst an der Adresse 0x080057CA bevor Sie die Funktion aufrufen osMailAlloc, dann an der Adresse 0x08005806 bevor Sie die Funktion aufrufen osMailPut, dann nach einer Weile - zur Adresse 0x08005BD4 (vor dem Aufruf der Funktion osMailGet), die zur Funktion gehört leds_task_entry (LED-Aufgabe), das heißt, die Aufgaben wurden umgeschaltet, und nun erhielt die LED-Aufgabe die Kontrolle.

Nashorn in einer Katze – Führen Sie die Firmware im Kopycat-Emulator aus

Auf diese einfache Weise können Sie feststellen, wie RTOS-Aufgaben miteinander interagieren.

Natürlich kann die Interaktion von Aufgaben in der Realität komplizierter sein, aber mit einem Emulator wird die Verfolgung dieser Interaktion weniger mühsam.

Hier Sie können sich ein kurzes Video ansehen, wie der Emulator startet und mit IDA Pro interagiert.

Starten Sie mit Radare2

Sie können ein so universelles Tool wie Radare2 nicht ignorieren.

Um mit r2 eine Verbindung zum Emulator herzustellen, würde der Befehl wie folgt aussehen:

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

Start jetzt verfügbar (dc) und die Ausführung anhalten (Strg+C).

Leider hat r2 derzeit Probleme mit dem Hardware-GDB-Server und dem Speicherlayout; daher funktionieren Haltepunkte und Schritte nicht (Befehl ds). Wir hoffen, dass dies bald behoben wird.

Laufen mit Eclipse

Eine der Möglichkeiten zur Verwendung des Emulators besteht darin, die Firmware des zu entwickelnden Geräts zu debuggen. Aus Gründen der Übersichtlichkeit verwenden wir auch die Rhino-Firmware. Sie können die Firmware-Quellen herunterladen daher.

Wir werden Eclipse aus dem Set als IDE verwenden System Workbench für STM32.

Damit der Emulator direkt in Eclipse kompilierte Firmware laden kann, müssen Sie den Parameter hinzufügen firmware=null zum Emulator-Startbefehl:

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

Debug-Konfiguration einrichten

Wählen Sie in Eclipse das Menü aus Ausführen – Konfigurationen debuggen... Im sich öffnenden Fenster im Abschnitt GDB-Hardware-Debugging Sie müssen eine neue Konfiguration hinzufügen und dann auf der Registerkarte „Haupt“ das aktuelle Projekt und die aktuelle Anwendung zum Debuggen angeben:

Nashorn in einer Katze – Führen Sie die Firmware im Kopycat-Emulator aus

Auf der Registerkarte „Debugger“ müssen Sie den GDB-Befehl angeben:
${openstm32_compiler_path}arm-none-eabi-gdb

Geben Sie außerdem die Parameter für die Verbindung zum GDB-Server (Host und Port) ein:

Nashorn in einer Katze – Führen Sie die Firmware im Kopycat-Emulator aus

Auf der Registerkarte „Startup“ müssen Sie folgende Parameter angeben:

  • Kontrollkästchen aktivieren Bild laden (damit das zusammengestellte Firmware-Image in den Emulator geladen wird);
  • Kontrollkästchen aktivieren Symbole laden;
  • Startbefehl hinzufügen: set $pc = *0x08000004 (Setzen Sie das PC-Register auf den Wert aus dem Speicher unter Adresse 0x08000004 - Die Adresse wird dort gespeichert ResetHandler).

Beachten, wenn Sie die Firmware-Datei nicht von Eclipse herunterladen möchten, dann die Optionen Bild laden и Befehle ausführen keine Angabe erforderlich.

Nashorn in einer Katze – Führen Sie die Firmware im Kopycat-Emulator aus

Nachdem Sie auf Debug geklickt haben, können Sie im Debugger-Modus arbeiten:

  • Schritt-für-Schritt-Codeausführung
    Nashorn in einer Katze – Führen Sie die Firmware im Kopycat-Emulator aus
  • Interaktion mit Haltepunkten
    Nashorn in einer Katze – Führen Sie die Firmware im Kopycat-Emulator aus

Beachten. Eclipse hat, hmm... einige Macken... und mit denen muss man leben. Wenn beispielsweise beim Starten des Debuggers die Meldung „Keine Quelle für „0x0“ verfügbar“ erscheint, dann führen Sie den Schrittbefehl (F5) aus.

Nashorn in einer Katze – Führen Sie die Firmware im Kopycat-Emulator aus

Statt einer Schlussfolgerung

Die Emulation von nativem Code ist eine sehr interessante Sache. Für einen Geräteentwickler wird es möglich, die Firmware ohne ein echtes Gerät zu debuggen. Für einen Forscher ist es eine Möglichkeit, dynamische Codeanalysen durchzuführen, was selbst mit einem Gerät nicht immer möglich ist.

Wir möchten Spezialisten ein Tool zur Verfügung stellen, das praktisch und einigermaßen einfach ist und dessen Einrichtung und Betrieb nicht viel Aufwand und Zeit erfordert.

Schreiben Sie in den Kommentaren über Ihre Erfahrungen mit Hardware-Emulatoren. Wir laden Sie zur Diskussion ein und beantworten gerne Ihre Fragen.

An der Umfrage können nur registrierte Benutzer teilnehmen. Einloggenbitte.

Wofür verwenden Sie den Emulator?

  • Ich entwickle (Debug-)Firmware

  • Ich recherchiere nach Firmware

  • Ich starte Spiele (Dendi, Sega, PSP)

  • etwas anderes (schreibe in die Kommentare)

7 Benutzer haben abgestimmt. 2 Benutzer enthielten sich der Stimme.

Welche Software verwenden Sie, um nativen Code zu emulieren?

  • QEMU

  • Einhornmotor

  • Proteus

  • etwas anderes (schreibe in die Kommentare)

6 Benutzer haben abgestimmt. 2 Benutzer enthielten sich der Stimme.

Was möchten Sie an dem von Ihnen verwendeten Emulator verbessern?

  • Ich will Geschwindigkeit

  • Ich möchte eine einfache Einrichtung/einfachen Start

  • Ich möchte mehr Optionen für die Interaktion mit dem Emulator (API, Hooks)

  • Mir passt alles

  • etwas anderes (schreibe in die Kommentare)

8 Benutzer haben abgestimmt. 1 Nutzer enthielten sich der Stimme.

Source: habr.com

Kommentar hinzufügen