Nosorożec w kocie - uruchom firmware w emulatorze Kopycat

Nosorożec w kocie - uruchom firmware w emulatorze Kopycat

W ramach spotkania 0x0A DC7831 DEF CON Niżny Nowogród 16 lutego zaprezentowaliśmy raport na temat podstawowych zasad emulacji kodu binarnego oraz nasz własny rozwój - emulator platformy sprzętowej Naśladowca.

W tym artykule opiszemy jak uruchomić firmware urządzenia w emulatorze, zademonstrujemy interakcję z debugerem oraz wykonamy małą analizę dynamiczną firmware.

prehistoria

Dawno temu w odległej galaktyce

Kilka lat temu w naszym laboratorium pojawiła się potrzeba zbadania oprogramowania sprzętowego urządzenia. Oprogramowanie sprzętowe zostało skompresowane i rozpakowane za pomocą programu ładującego. Zrobił to w bardzo skomplikowany sposób, kilkakrotnie przesuwając dane w pamięci. A samo oprogramowanie układowe aktywnie współdziałało z urządzeniami peryferyjnymi. A wszystko to na rdzeniu MIPS.

Z przyczyn obiektywnych istniejące emulatory nam nie odpowiadały, ale mimo to chcieliśmy uruchomić kod. Następnie postanowiliśmy stworzyć własny emulator, który wykonałby minimum i pozwolił nam rozpakować główne oprogramowanie. Próbowaliśmy tego i zadziałało. Pomyśleliśmy, co jeśli dodamy urządzenia peryferyjne, aby jednocześnie wykonywać główny firmware. Nie bolało bardzo - i też zadziałało. Pomyśleliśmy jeszcze raz i postanowiliśmy stworzyć pełnoprawny emulator.

Rezultatem był emulator systemów komputerowych Naśladowca.

Nosorożec w kocie - uruchom firmware w emulatorze Kopycat
Dlaczego Kopycat?

Jest gra słów.

  1. copycat (angielski, rzeczownik [ˈkɒpɪkæt]) - naśladowca, naśladowca
  2. jak (angielski, rzeczownik [ˈkæt]) - kot, kot - ulubione zwierzę jednego z twórców projektu
  3. Litera „K” pochodzi z języka programowania Kotlin

Naśladowca

Tworząc emulator postawiono sobie bardzo konkretne cele:

  • możliwość szybkiego tworzenia nowych urządzeń peryferyjnych, modułów, rdzeni procesorów;
  • możliwość złożenia urządzenia wirtualnego z różnych modułów;
  • możliwość wczytania dowolnych danych binarnych (firmware) do pamięci urządzenia wirtualnego;
  • możliwość pracy z migawkami (migawkami stanu systemu);
  • możliwość interakcji z emulatorem poprzez wbudowany debuger;
  • ładny, nowoczesny język dla rozwoju.

W efekcie do realizacji wybrano Kotlin, architekturę magistrali (w tym przypadku moduły komunikują się ze sobą za pośrednictwem wirtualnych magistrali danych), JSON jako format opisu urządzenia oraz GDB RSP jako protokół interakcji z debugerem.

Rozwój trwa już nieco ponad dwa lata i jest aktywnie kontynuowany. W tym czasie wdrożono rdzenie procesorów MIPS, x86, V850ES, ARM i PowerPC.

Projekt się rozwija i przyszedł czas na zaprezentowanie go szerszej publiczności. Szczegółowy opis projektu zrobimy później, ale na razie skupimy się na wykorzystaniu Kopycata.

Dla najbardziej niecierpliwych można pobrać promocyjną wersję emulatora powiązanie.

Nosorożec w emulatorze

Przypomnijmy, że wcześniej na konferencję SMARTRHINO-2018 powstało urządzenie testowe „Rhinoceros” służące do nauczania umiejętności inżynierii odwrotnej. Proces statycznej analizy oprogramowania sprzętowego został opisany w ten artykuł.

Spróbujmy teraz dodać „głośniki” i uruchomić firmware w emulatorze.

Potrzebujemy:
1) Java 1.8
2) Python i moduł jep aby używać Pythona w emulatorze. Możesz zbudować moduł WHL Jep dla Windows pobierz tutaj.

W systemie Windows:
1) com0com
2) PuTTY

Dla Linuksa:
1) sokat

Możesz używać Eclipse, IDA Pro lub radare2 jako klienta GDB.

Jak to działa?

Aby wykonać firmware w emulatorze, konieczne jest „złożenie” urządzenia wirtualnego, będącego odpowiednikiem urządzenia rzeczywistego.

Rzeczywiste urządzenie („nosorożec”) można przedstawić na schemacie blokowym:

Nosorożec w kocie - uruchom firmware w emulatorze Kopycat

Emulator ma budowę modułową, a finalne urządzenie wirtualne można opisać w pliku JSON.

Linie JSON 105

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

Zwróć uwagę na parametr firmware sekcja params to nazwa pliku, który można załadować do urządzenia wirtualnego jako oprogramowanie sprzętowe.

Urządzenie wirtualne i jego interakcję z głównym systemem operacyjnym można przedstawić na poniższym schemacie:

Nosorożec w kocie - uruchom firmware w emulatorze Kopycat

Obecna instancja testowa emulatora obejmuje interakcję z portami COM głównego systemu operacyjnego (debugowanie UART i UART dla modułu Bluetooth). Mogą to być rzeczywiste porty, do których podłączane są urządzenia lub wirtualne porty COM (w tym celu wystarczy com0com/socat).

Obecnie istnieją dwa główne sposoby interakcji z emulatorem z zewnątrz:

  • protokół GDB RSP (odpowiednio narzędzia obsługujące ten protokół to Eclipse / IDA / radare2);
  • wewnętrzna linia poleceń emulatora (Argparse lub Python).

Wirtualne porty COM

Aby móc współdziałać z UART urządzenia wirtualnego na maszynie lokalnej za pośrednictwem terminala, należy utworzyć parę powiązanych wirtualnych portów COM. W naszym przypadku jeden port jest wykorzystywany przez emulator, a drugi przez program terminalowy (PuTTY lub screen):

Nosorożec w kocie - uruchom firmware w emulatorze Kopycat

Korzystanie z com0com

Wirtualne porty COM konfiguruje się za pomocą narzędzia konfiguracyjnego z zestawu com0com (wersja konsolowa - C:Pliki programów (x86)com0comsetupс.exe, lub wersja GUI - C:Pliki programów (x86)com0comsetupg.exe):

Nosorożec w kocie - uruchom firmware w emulatorze Kopycat

Sprawdź pudełka włączyć przepełnienie bufora dla wszystkich utworzonych portów wirtualnych, w przeciwnym razie emulator będzie czekał na odpowiedź z portu COM.

Używając socata

W systemach UNIX wirtualne porty COM są automatycznie tworzone przez emulator za pomocą narzędzia socat; w tym celu wystarczy podać przedrostek w nazwie portu podczas uruchamiania emulatora socat:.

Wewnętrzny interfejs wiersza poleceń (Argparse lub Python)

Ponieważ Kopycat jest aplikacją konsolową, emulator udostępnia dwie opcje interfejsu wiersza poleceń umożliwiające interakcję z obiektami i zmiennymi: Argparse i Python.

Argparse to interfejs CLI wbudowany w Kopycat i jest zawsze dostępny dla każdego.

Alternatywnym interfejsem CLI jest interpreter języka Python. Aby z niego skorzystać należy zainstalować moduł Jep Python i skonfigurować emulator do współpracy z Pythonem (wykorzystany zostanie interpreter Pythona zainstalowany na głównym systemie użytkownika).

Instalowanie modułu Pythona Jep

Pod Linuksem Jep można zainstalować poprzez pip:

pip install jep

Aby zainstalować Jep w systemie Windows, musisz najpierw zainstalować Windows SDK i odpowiednie Microsoft Visual Studio. Ułatwiliśmy Ci to trochę i WHL buduje JEP dla aktualnych wersji Pythona dla Windows, więc moduł można zainstalować z pliku:

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

Aby sprawdzić instalację Jepa, musisz uruchomić w wierszu poleceń:

python -c "import jep"

W odpowiedzi powinien otrzymać następujący komunikat:

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

W pliku wsadowym emulatora dla twojego systemu (kopia.bat - dla Windowsa, naśladowca - dla systemu Linux) do listy parametrów DEFAULT_JVM_OPTS dodaj dodatkowy parametr Djava.library.path — musi zawierać ścieżkę do zainstalowanego modułu Jep.

Wynik dla systemu Windows powinien wyglądać następująco:

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

Uruchamianie Kopycata

Emulator jest konsolową aplikacją JVM. Uruchomienie odbywa się za pomocą skryptu wiersza poleceń systemu operacyjnego (sh/cmd).

Polecenie do uruchomienia w systemie Windows:

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

Polecenie do uruchomienia w systemie Linux przy użyciu narzędzia 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 — port TCP, który będzie otwarty dla dostępu do serwera GDB;
  • -n rhino — nazwa głównego modułu systemu (złożonego urządzenia);
  • -l user — nazwa biblioteki, w której będzie wyszukiwany moduł główny;
  • -y library — ścieżka wyszukiwania modułów wchodzących w skład urządzenia;
  • firmwarerhino_pass.bin — ścieżka do pliku oprogramowania sprzętowego;
  • COM26 i COM28 to wirtualne porty COM.

W rezultacie zostanie wyświetlony monit Python > (or 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 >

Interakcja z IDA Pro

Aby uprościć testowanie, używamy oprogramowania sprzętowego Rhino jako pliku źródłowego do analizy w IDA w formie plik ELF (metainformacje są tam przechowywane).

Można także używać głównego oprogramowania sprzętowego bez metainformacji.

Po uruchomieniu Kopycat w IDA Pro, w menu Debugger przejdź do pozycji „Przełącz debuger…" i wybierz "Zdalny debuger GDB„. Następnie skonfiguruj połączenie: menu Debuger — opcje procesu…

Ustaw wartości:

  • Zastosowanie - dowolna wartość
  • Nazwa hosta: 127.0.0.1 (lub adres IP zdalnej maszyny, na której działa Kopycat)
  • Port: 23946

Nosorożec w kocie - uruchom firmware w emulatorze Kopycat

Teraz dostępny będzie przycisk debugowania (klawisz F9):

Nosorożec w kocie - uruchom firmware w emulatorze Kopycat

Kliknij, aby połączyć się z modułem debugera w emulatorze. IDA przechodzi w tryb debugowania, pojawiają się dodatkowe okna: informacja o rejestrach, o stosie.

Teraz możemy korzystać ze wszystkich standardowych funkcji debugera:

  • wykonanie instrukcji krok po kroku (Wkroczyć и Krok nad — klawisze odpowiednio F7 i F8);
  • uruchamianie i wstrzymywanie wykonywania;
  • tworzenie punktów przerwania zarówno dla kodu, jak i danych (klawisz F2).

Podłączenie do debuggera nie oznacza uruchomienia kodu oprogramowania sprzętowego. Bieżąca pozycja wykonania musi być adresem 0x08006A74 — rozpoczęcie funkcji Reset_Handler. Jeśli przewiniesz listę w dół, zobaczysz wywołanie funkcji główny. Możesz umieścić kursor w tej linii (adres 0x08006ABE) i wykonaj operację Biegnij aż do kursora (klawisz F4).

Nosorożec w kocie - uruchom firmware w emulatorze Kopycat

Następnie możesz nacisnąć klawisz F7, aby wejść do funkcji główny.

Jeśli uruchomisz polecenie Kontynuuj proces (klawisz F9), po czym pojawi się okno „Proszę czekać” z jednym przyciskiem Zawiesić:

Nosorożec w kocie - uruchom firmware w emulatorze Kopycat

Kiedy naciskasz Zawiesić wykonywanie kodu oprogramowania sprzętowego zostaje zawieszone i można je kontynuować od tego samego adresu w kodzie, w którym zostało przerwane.

Jeśli będziesz kontynuować wykonywanie kodu, na terminalach podłączonych do wirtualnych portów COM zobaczysz następujące linie:

Nosorożec w kocie - uruchom firmware w emulatorze Kopycat

Nosorożec w kocie - uruchom firmware w emulatorze Kopycat

Obecność linii „pominięcie stanu” oznacza, że ​​wirtualny moduł Bluetooth przeszedł w tryb odbioru danych z portu COM użytkownika.

Teraz w terminalu Bluetooth (na zdjęciu COM29) możesz wprowadzać polecenia zgodnie z protokołem Rhino. Na przykład polecenie „MEOW” zwróci ciąg „mur-mur” do terminala Bluetooth:

Nosorożec w kocie - uruchom firmware w emulatorze Kopycat

Nie naśladuj mnie całkowicie

Budując emulator, możesz wybrać poziom szczegółowości/emulacji konkretnego urządzenia. Przykładowo moduł Bluetooth można emulować na różne sposoby:

  • urządzenie jest w pełni emulowane z pełnym zestawem poleceń;
  • Polecenia AT są emulowane, a strumień danych odbierany jest z portu COM systemu głównego;
  • urządzenie wirtualne zapewnia pełne przekierowanie danych do urządzenia rzeczywistego;
  • jako prosty kod pośredniczący, który zawsze zwraca „OK”.

Obecna wersja emulatora wykorzystuje drugie podejście - wirtualny moduł Bluetooth dokonuje konfiguracji, po czym przełącza się w tryb „proxowania” danych z portu COM systemu głównego do portu UART emulatora.

Nosorożec w kocie - uruchom firmware w emulatorze Kopycat

Rozważmy możliwość prostego instrumentacji kodu w przypadku, gdy jakaś część peryferii nie jest zaimplementowana. Przykładowo, jeśli nie utworzono timera odpowiedzialnego za kontrolę przesyłania danych do DMA (sprawdzanie odbywa się w funkcji ws2812b_waitzlokalizowany w 0x08006840), wtedy firmware będzie zawsze czekał na reset flagi zajętyzlokalizowany w 0x200004C4który pokazuje zajętość linii danych DMA:

Nosorożec w kocie - uruchom firmware w emulatorze Kopycat

Możemy obejść tę sytuację, ręcznie resetując flagę zajęty zaraz po jego zainstalowaniu. W IDA Pro możesz utworzyć funkcję w Pythonie i wywołać ją w punkcie przerwania, a sam punkt przerwania umieścić w kodzie po zapisaniu wartości 1 do flagi zajęty.

Obsługa punktu przerwania

Najpierw utwórzmy funkcję Pythona w IDA. Menu Plik — polecenie skryptu...

Dodaj nowy fragment do listy po lewej stronie, nadaj mu nazwę (np. BPT),
W polu tekstowym po prawej stronie wpisz kod funkcji:

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

Nosorożec w kocie - uruchom firmware w emulatorze Kopycat

Następnie naciskamy run i zamknij okno skryptu.

Przejdźmy teraz do kodu pod adresem 0x0800688A, ustaw punkt przerwania (klawisz F2), edytuj go (menu kontekstowe Edytuj punkt przerwania...), nie zapomnij ustawić typu skryptu na Python:

Nosorożec w kocie - uruchom firmware w emulatorze Kopycat
Nosorożec w kocie - uruchom firmware w emulatorze Kopycat

Jeśli bieżąca wartość flagi zajęty równa się 1, to powinieneś wykonać funkcję pominąć_dma w linii skryptu:

Nosorożec w kocie - uruchom firmware w emulatorze Kopycat

Jeśli uruchomisz oprogramowanie sprzętowe w celu wykonania, wyzwolenie kodu obsługi punktu przerwania będzie widoczne w oknie IDA Wydajność przez linię Skipping wait ws2812.... Teraz oprogramowanie nie będzie czekać na zresetowanie flagi zajęty.

Interakcja z emulatorem

Emulacja dla samej emulacji raczej nie wywoła zachwytu i radości. O wiele ciekawiej jest, jeśli emulator pomaga badaczowi zobaczyć dane w pamięci lub ustalić interakcję wątków.

Pokażemy Ci jak dynamicznie nawiązywać interakcję pomiędzy zadaniami RTOS. Najpierw powinieneś wstrzymać wykonywanie kodu, jeśli jest uruchomiony. Jeśli przejdziesz do funkcji wpis_zadania_bluetooth do gałęzi przetwarzającej polecenie „LED” (adres 0x080057B8), wtedy możesz zobaczyć, co jest najpierw tworzone, a następnie wysyłane do kolejki systemowej uchwyt ledControlQueue jakaś wiadomość.

Nosorożec w kocie - uruchom firmware w emulatorze Kopycat

Aby uzyskać dostęp do zmiennej, należy ustawić punkt przerwania uchwyt ledControlQueuezlokalizowany w 0x20000624 i kontynuuj wykonywanie kodu:

Nosorożec w kocie - uruchom firmware w emulatorze Kopycat

W rezultacie zatrzymanie nastąpi najpierw pod adresem 0x080057CA przed wywołaniem funkcji osMailAlloc, a następnie pod adresem 0x08005806 przed wywołaniem funkcji osMailPut, a po chwili - pod wskazany adres 0x08005BD4 (przed wywołaniem funkcji osMailGet), który należy do funkcji wpis_zadania leds (zadanie LED), czyli zadania zamienione, a teraz zadanie LED otrzymało kontrolę.

Nosorożec w kocie - uruchom firmware w emulatorze Kopycat

W ten prosty sposób możesz ustalić, w jaki sposób zadania RTOS współdziałają ze sobą.

Oczywiście w rzeczywistości interakcja zadań może być bardziej skomplikowana, ale przy użyciu emulatora śledzenie tej interakcji staje się mniej pracochłonne.

Tutaj Możesz obejrzeć krótki film przedstawiający uruchomienie emulatora i interakcję z IDA Pro.

Uruchom z Radare2

Nie można przejść obojętnie obok tak uniwersalnego narzędzia jak Radare2.

Aby połączyć się z emulatorem za pomocą r2, polecenie wyglądałoby następująco:

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

Uruchomienie już dostępne (dc) i wstrzymaj wykonywanie (Ctrl+C).

Niestety w tej chwili r2 ma problemy podczas pracy ze sprzętowym serwerem gdb i układem pamięci, z tego powodu punkty przerwania i kroki nie działają (polecenie ds). Mamy nadzieję, że zostanie to wkrótce naprawione.

Bieganie z Eclipse

Jedną z opcji wykorzystania emulatora jest debugowanie oprogramowania układowego opracowywanego urządzenia. Dla przejrzystości użyjemy również oprogramowania sprzętowego Rhino. Możesz pobrać źródła oprogramowania sprzętowego stąd.

Jako IDE użyjemy Eclipse z zestawu Systemowy stół warsztatowy dla STM32.

Aby emulator wczytał firmware bezpośrednio skompilowany w Eclipse należy dodać parametr firmware=null do polecenia uruchomienia emulatora:

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

Konfigurowanie konfiguracji debugowania

W Eclipse wybierz menu Uruchom — konfiguracje debugowania... W oknie, które się otworzy, w sekcji Debugowanie sprzętowe GDB musisz dodać nową konfigurację, następnie w zakładce „Główne” określ bieżący projekt i aplikację do debugowania:

Nosorożec w kocie - uruchom firmware w emulatorze Kopycat

W zakładce „Debugger” należy podać polecenie GDB:
${openstm32_compiler_path}arm-none-eabi-gdb

A także wprowadź parametry połączenia z serwerem GDB (host i port):

Nosorożec w kocie - uruchom firmware w emulatorze Kopycat

W zakładce „Uruchamianie” należy określić następujące parametry:

  • włącz pole wyboru Załaduj obraz (aby zmontowany obraz oprogramowania układowego został załadowany do emulatora);
  • włącz pole wyboru Załaduj symbole;
  • dodaj polecenie uruchomienia: set $pc = *0x08000004 (ustaw rejestr PC na wartość z pamięci pod adresem 0x08000004 - adres jest tam zapisany Resetowanie obsługi).

Zauważyć, jeśli nie chcesz pobierać pliku oprogramowania sprzętowego z Eclipse, wybierz options Załaduj obraz и Uruchom polecenia nie trzeba wskazywać.

Nosorożec w kocie - uruchom firmware w emulatorze Kopycat

Po kliknięciu Debuguj możesz pracować w trybie debugera:

  • wykonanie kodu krok po kroku
    Nosorożec w kocie - uruchom firmware w emulatorze Kopycat
  • interakcja z punktami przerwania
    Nosorożec w kocie - uruchom firmware w emulatorze Kopycat

Operacja. Eclipse ma, hmm... pewne dziwactwa... i trzeba z nimi żyć. Na przykład, jeśli podczas uruchamiania debugera pojawi się komunikat „Brak dostępnego źródła dla „0x0″”, wykonaj polecenie Krok (F5)

Nosorożec w kocie - uruchom firmware w emulatorze Kopycat

Zamiast zawierania

Emulowanie kodu natywnego jest bardzo interesującą rzeczą. Twórca urządzenia może debugować oprogramowanie sprzętowe bez prawdziwego urządzenia. Dla badacza jest to możliwość przeprowadzenia dynamicznej analizy kodu, co nie zawsze jest możliwe nawet przy pomocy urządzenia.

Chcemy zapewnić specjalistom narzędzie, które jest wygodne, w miarę proste, a jego konfiguracja i uruchomienie nie wymaga dużego wysiłku i czasu.

Napisz w komentarzach o swoich doświadczeniach z używaniem emulatorów sprzętowych. Zapraszamy do dyskusji i chętnie odpowiemy na pytania.

W ankiecie mogą brać udział tylko zarejestrowani użytkownicy. Zaloguj się, Proszę.

Do czego używasz emulatora?

  • Tworzę (debuguję) oprogramowanie sprzętowe

  • Badam oprogramowanie sprzętowe

  • Uruchamiam gry (Dendi, Sega, PSP)

  • coś innego (napisz w komentarzu)

Głosowało 7 użytkowników. 2 użytkowników wstrzymało się od głosu.

Jakiego oprogramowania używasz do emulacji kodu natywnego?

  • QEMU

  • Silnik jednorożca

  • Odmieniec

  • coś innego (napisz w komentarzu)

Głosowało 6 użytkowników. 2 użytkowników wstrzymało się od głosu.

Co chciałbyś poprawić w emulatorze, którego używasz?

  • Chcę prędkości

  • Chcę łatwości konfiguracji/uruchomienia

  • Chcę więcej opcji interakcji z emulatorem (API, hooki)

  • Jestem zadowolony ze wszystkiego

  • coś innego (napisz w komentarzu)

Głosowało 8 użytkowników. 1 użytkownik wstrzymał się od głosu.

Źródło: www.habr.com

Dodaj komentarz