Ρινόκερος μέσα σε γάτα - εκτελέστε το υλικολογισμικό στον εξομοιωτή Kopycat

Ρινόκερος μέσα σε γάτα - εκτελέστε το υλικολογισμικό στον εξομοιωτή Kopycat

Ως μέρος της συνάντησης 0x0A DC7831 DEF CON Νίζνι Νόβγκοροντ Στις 16 Φεβρουαρίου, παρουσιάσαμε μια έκθεση σχετικά με τις βασικές αρχές της εξομοίωσης δυαδικού κώδικα και τη δική μας ανάπτυξη - έναν εξομοιωτή πλατφόρμας υλικού Αντιγραφή.

Σε αυτό το άρθρο θα περιγράψουμε τον τρόπο εκτέλεσης του υλικολογισμικού της συσκευής στον εξομοιωτή, την επίδειξη αλληλεπίδρασης με το πρόγραμμα εντοπισμού σφαλμάτων και την εκτέλεση μιας μικρής δυναμικής ανάλυσης του υλικολογισμικού.

Ιστορικό

Πριν από πολύ καιρό σε έναν γαλαξία πολύ μακριά

Πριν από μερικά χρόνια στο εργαστήριό μας χρειάστηκε να διερευνηθεί το υλικολογισμικό μιας συσκευής. Το υλικολογισμικό συμπιέστηκε και αποσυσκευάστηκε με ένα bootloader. Αυτό το έκανε με πολύ περίπλοκο τρόπο, μετατοπίζοντας τα δεδομένα στη μνήμη αρκετές φορές. Και το ίδιο το υλικολογισμικό αλληλεπιδρούσε ενεργά με τα περιφερειακά. Και όλα αυτά στον πυρήνα MIPS.

Για αντικειμενικούς λόγους, οι διαθέσιμοι εξομοιωτές δεν μας ταιριάζουν, αλλά θέλαμε να εκτελέσουμε τον κώδικα. Στη συνέχεια αποφασίσαμε να φτιάξουμε τον δικό μας εξομοιωτή, ο οποίος θα έκανε το ελάχιστο και θα μας επέτρεπε να αποσυσκευάσουμε το κύριο υλικολογισμικό. Το δοκιμάσαμε και δούλεψε. Σκεφτήκαμε, τι θα συμβεί αν προσθέσουμε περιφερειακά για να εκτελέσουμε επίσης το κύριο υλικολογισμικό. Δεν πόνεσε πολύ - και λειτούργησε επίσης. Σκεφτήκαμε ξανά και αποφασίσαμε να φτιάξουμε έναν ολοκληρωμένο εξομοιωτή.

Το αποτέλεσμα ήταν ένας εξομοιωτής συστημάτων υπολογιστών Αντιγραφή.

Ρινόκερος μέσα σε γάτα - εκτελέστε το υλικολογισμικό στον εξομοιωτή Kopycat
Γιατί Kopycat;

Γίνεται παιχνίδι με τις λέξεις.

  1. copycat (Αγγλικά, ουσιαστικό [ˈkɒpɪkæt]) - μιμητής, μιμητής
  2. πως (Αγγλικά, ουσιαστικό [ˈkæt]) - γάτα, γάτα - το αγαπημένο ζώο ενός από τους δημιουργούς του έργου
  3. Το γράμμα "K" προέρχεται από τη γλώσσα προγραμματισμού Kotlin

Αντιγραφή

Κατά τη δημιουργία του εξομοιωτή, τέθηκαν πολύ συγκεκριμένοι στόχοι:

  • τη δυνατότητα γρήγορης δημιουργίας νέων περιφερειακών, μονάδων, πυρήνων επεξεργαστή.
  • η δυνατότητα συναρμολόγησης μιας εικονικής συσκευής από διάφορες ενότητες.
  • τη δυνατότητα φόρτωσης οποιωνδήποτε δυαδικών δεδομένων (υλικολογισμικό) στη μνήμη μιας εικονικής συσκευής.
  • ικανότητα εργασίας με στιγμιότυπα (στιγμιότυπα της κατάστασης του συστήματος).
  • τη δυνατότητα αλληλεπίδρασης με τον εξομοιωτή μέσω του ενσωματωμένου προγράμματος εντοπισμού σφαλμάτων.
  • ωραία σύγχρονη γλώσσα για ανάπτυξη.

Ως αποτέλεσμα, επιλέχθηκε το Kotlin για υλοποίηση, η αρχιτεκτονική διαύλου (αυτό συμβαίνει όταν οι μονάδες επικοινωνούν μεταξύ τους μέσω εικονικών διαύλων δεδομένων), το JSON ως μορφή περιγραφής συσκευής και το GDB RSP ως πρωτόκολλο για αλληλεπίδραση με τον εντοπισμό σφαλμάτων.

Η ανάπτυξη συνεχίζεται για λίγο περισσότερο από δύο χρόνια και είναι ενεργά σε εξέλιξη. Κατά τη διάρκεια αυτής της περιόδου, υλοποιήθηκαν πυρήνες επεξεργαστών MIPS, x86, V850ES, ARM και PowerPC.

Το έργο μεγαλώνει και ήρθε η ώρα να το παρουσιάσουμε στο ευρύτερο κοινό. Θα κάνουμε μια λεπτομερή περιγραφή του έργου αργότερα, αλλά προς το παρόν θα επικεντρωθούμε στη χρήση του Kopycat.

Για τους πιο ανυπόμονους, μπορείτε να κάνετε λήψη μιας έκδοσης προώθησης του εξομοιωτή από σύνδεσμος.

Ρινόκερος στον εξομοιωτή

Ας θυμηθούμε ότι νωρίτερα για το συνέδριο SMARTRHINO-2018, δημιουργήθηκε μια δοκιμαστική συσκευή «Rhinoceros» για τη διδασκαλία δεξιοτήτων αντίστροφης μηχανικής. Η διαδικασία της στατικής ανάλυσης υλικολογισμικού περιγράφηκε στο Αυτό το άρθρο.

Τώρα ας προσπαθήσουμε να προσθέσουμε "ηχεία" και να εκτελέσουμε το υλικολογισμικό στον εξομοιωτή.

Χρειαζόμαστε:
1) Java 1.8
2) Python και module Τζαπ για να χρησιμοποιήσετε την Python μέσα στον εξομοιωτή. Μπορείτε να δημιουργήσετε τη λειτουργική μονάδα WHL Jep για Windows κατέβασε εδώ.

Για Windows:
1) com0com
2) PuTTY

Για Linux:
1) σωκατ

Μπορείτε να χρησιμοποιήσετε το Eclipse, το IDA Pro ή το radare2 ως πελάτη GDB.

Πώς λειτουργεί;

Για να εκτελέσετε υλικολογισμικό στον εξομοιωτή, είναι απαραίτητο να "συναρμολογήσετε" μια εικονική συσκευή, η οποία είναι ανάλογο μιας πραγματικής συσκευής.

Η πραγματική συσκευή ("rhino") μπορεί να εμφανιστεί στο μπλοκ διάγραμμα:

Ρινόκερος μέσα σε γάτα - εκτελέστε το υλικολογισμικό στον εξομοιωτή Kopycat

Ο εξομοιωτής έχει μια αρθρωτή δομή και η τελική εικονική συσκευή μπορεί να περιγραφεί σε ένα αρχείο JSON.

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

Δώστε προσοχή στην παράμετρο firmware τμήμα params είναι το όνομα ενός αρχείου που μπορεί να φορτωθεί σε μια εικονική συσκευή ως υλικολογισμικό.

Η εικονική συσκευή και η αλληλεπίδρασή της με το κύριο λειτουργικό σύστημα μπορεί να αναπαρασταθεί από το ακόλουθο διάγραμμα:

Ρινόκερος μέσα σε γάτα - εκτελέστε το υλικολογισμικό στον εξομοιωτή Kopycat

Η τρέχουσα παρουσία δοκιμής του εξομοιωτή περιλαμβάνει αλληλεπίδραση με τις θύρες COM του κύριου λειτουργικού συστήματος (εντοπισμός σφαλμάτων UART και UART για τη μονάδα Bluetooth). Αυτές μπορεί να είναι πραγματικές θύρες στις οποίες είναι συνδεδεμένες οι συσκευές ή εικονικές θύρες COM (για αυτό χρειάζεστε απλώς com0com/socat).

Υπάρχουν επί του παρόντος δύο κύριοι τρόποι αλληλεπίδρασης με τον εξομοιωτή από έξω:

  • Πρωτόκολλο GDB RSP (κατά συνέπεια, τα εργαλεία που υποστηρίζουν αυτό το πρωτόκολλο είναι το Eclipse / IDA / radare2).
  • εσωτερική γραμμή εντολών εξομοιωτή (Argparse ή Python).

Εικονικές θύρες COM

Για να αλληλεπιδράσετε με το UART μιας εικονικής συσκευής στον τοπικό υπολογιστή μέσω ενός τερματικού, πρέπει να δημιουργήσετε ένα ζεύγος σχετικών εικονικών θυρών COM. Στην περίπτωσή μας, μια θύρα χρησιμοποιείται από τον εξομοιωτή και η δεύτερη από ένα τερματικό πρόγραμμα (PuTTY ή οθόνη):

Ρινόκερος μέσα σε γάτα - εκτελέστε το υλικολογισμικό στον εξομοιωτή Kopycat

Χρησιμοποιώντας com0com

Οι εικονικές θύρες COM διαμορφώνονται χρησιμοποιώντας το βοηθητικό πρόγραμμα εγκατάστασης από το κιτ com0com (έκδοση κονσόλας - C:Program Files (x86)com0comsetupс.exe, ή έκδοση GUI - C:Program Files (x86)com0comsetupg.exe):

Ρινόκερος μέσα σε γάτα - εκτελέστε το υλικολογισμικό στον εξομοιωτή Kopycat

Επιλέξτε τα πλαίσια ενεργοποίηση υπέρβασης buffer για όλες τις εικονικές θύρες που δημιουργήθηκαν, διαφορετικά ο εξομοιωτής θα περιμένει απάντηση από τη θύρα COM.

Χρησιμοποιώντας το socat

Στα συστήματα UNIX, οι εικονικές θύρες COM δημιουργούνται αυτόματα από τον εξομοιωτή χρησιμοποιώντας το βοηθητικό πρόγραμμα socat· για να το κάνετε αυτό, απλώς καθορίστε το πρόθεμα στο όνομα της θύρας κατά την εκκίνηση του εξομοιωτή socat:.

Εσωτερική διεπαφή γραμμής εντολών (Argparse ή Python)

Δεδομένου ότι το Kopycat είναι μια εφαρμογή κονσόλας, ο εξομοιωτής παρέχει δύο επιλογές διεπαφής γραμμής εντολών για αλληλεπίδραση με τα αντικείμενα και τις μεταβλητές του: Argparse και Python.

Το Argparse είναι ένα CLI ενσωματωμένο στο Kopycat και είναι πάντα διαθέσιμο σε όλους.

Ένα εναλλακτικό CLI είναι ο διερμηνέας Python. Για να το χρησιμοποιήσετε, πρέπει να εγκαταστήσετε τη λειτουργική μονάδα Jep Python και να διαμορφώσετε τον εξομοιωτή ώστε να λειτουργεί με την Python (θα χρησιμοποιηθεί ο διερμηνέας Python που είναι εγκατεστημένος στο κύριο σύστημα του χρήστη).

Εγκατάσταση της λειτουργικής μονάδας Python Jep

Στο Linux, το Jep μπορεί να εγκατασταθεί μέσω pip:

pip install jep

Για να εγκαταστήσετε το Jep στα Windows, πρέπει πρώτα να εγκαταστήσετε το Windows SDK και το αντίστοιχο Microsoft Visual Studio. Σας το κάναμε λίγο πιο εύκολο και Κατασκευάζει WHL JEP για τις τρέχουσες εκδόσεις της Python για Windows, ώστε η μονάδα να μπορεί να εγκατασταθεί από το αρχείο:

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

Για να ελέγξετε την εγκατάσταση του Jep, πρέπει να εκτελέσετε στη γραμμή εντολών:

python -c "import jep"

Ως απάντηση θα πρέπει να ληφθεί το ακόλουθο μήνυμα:

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

Στο αρχείο δέσμης εξομοιωτή για το σύστημά σας (copycat.bat - για Windows, αντιγραφή - για Linux) στη λίστα παραμέτρων DEFAULT_JVM_OPTS προσθέστε μια επιπλέον παράμετρο Djava.library.path — πρέπει να περιέχει τη διαδρομή προς την εγκατεστημένη μονάδα Jep.

Το αποτέλεσμα για τα Windows θα πρέπει να είναι μια γραμμή όπως αυτή:

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

Εκκίνηση του Kopycat

Ο εξομοιωτής είναι μια εφαρμογή JVM κονσόλας. Η εκκίνηση πραγματοποιείται μέσω του σεναρίου γραμμής εντολών του λειτουργικού συστήματος (sh/cmd).

Εντολή για εκτέλεση στα Windows:

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

Εντολή για εκτέλεση στο Linux χρησιμοποιώντας το βοηθητικό πρόγραμμα 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 που θα είναι ανοιχτή για πρόσβαση στον διακομιστή GDB.
  • -n rhino — όνομα της κύριας μονάδας συστήματος (συναρμολογημένη συσκευή)·
  • -l user — όνομα της βιβλιοθήκης για αναζήτηση της κύριας ενότητας.
  • -y library — διαδρομή για αναζήτηση μονάδων που περιλαμβάνονται στη συσκευή.
  • firmwarerhino_pass.bin — διαδρομή προς το αρχείο υλικολογισμικού.
  • Οι COM26 και COM28 είναι εικονικές θύρες COM.

Ως αποτέλεσμα, θα εμφανιστεί μια προτροπή Python >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 >

Αλληλεπίδραση με το IDA Pro

Για να απλοποιήσουμε τη δοκιμή, χρησιμοποιούμε το υλικολογισμικό Rhino ως αρχείο προέλευσης για ανάλυση στο IDA στη φόρμα Αρχείο ELF (εκεί αποθηκεύονται οι μετα-πληροφορίες).

Μπορείτε επίσης να χρησιμοποιήσετε το κύριο υλικολογισμικό χωρίς μετα-πληροφορίες.

Μετά την εκκίνηση του Kopycat στο IDA Pro, στο μενού Debugger μεταβείτε στο στοιχείο "Εναλλαγή προγράμματος εντοπισμού σφαλμάτων…"και επιλέξτε"Απομακρυσμένο πρόγραμμα εντοπισμού σφαλμάτων GDB". Στη συνέχεια, ρυθμίστε το μενού σύνδεσης: Εντοπιστής σφαλμάτων - Επιλογές επεξεργασίας…

Ορίστε τις τιμές:

  • Εφαρμογή - οποιαδήποτε τιμή
  • Όνομα κεντρικού υπολογιστή: 127.0.0.1 (ή η διεύθυνση IP του απομακρυσμένου μηχανήματος όπου εκτελείται το Kopycat)
  • Λιμάνι: 23946

Ρινόκερος μέσα σε γάτα - εκτελέστε το υλικολογισμικό στον εξομοιωτή Kopycat

Τώρα το κουμπί εντοπισμού σφαλμάτων είναι διαθέσιμο (κλειδί F9):

Ρινόκερος μέσα σε γάτα - εκτελέστε το υλικολογισμικό στον εξομοιωτή Kopycat

Κάντε κλικ σε αυτό για να συνδεθείτε στη μονάδα εντοπισμού σφαλμάτων στον εξομοιωτή. Το IDA μπαίνει σε λειτουργία εντοπισμού σφαλμάτων, γίνονται διαθέσιμα πρόσθετα παράθυρα: πληροφορίες σχετικά με μητρώα, σχετικά με τη στοίβα.

Τώρα μπορούμε να χρησιμοποιήσουμε όλες τις τυπικές δυνατότητες του προγράμματος εντοπισμού σφαλμάτων:

  • βήμα προς βήμα εκτέλεση εντολών (Είσοδος и Προχωρήστε — πλήκτρα F7 και F8, αντίστοιχα).
  • έναρξη και παύση της εκτέλεσης.
  • δημιουργία σημείων διακοπής τόσο για τον κώδικα όσο και για τα δεδομένα (κλειδί F2).

Η σύνδεση σε πρόγραμμα εντοπισμού σφαλμάτων δεν σημαίνει εκτέλεση του κώδικα υλικολογισμικού. Η τρέχουσα θέση εκτέλεσης πρέπει να είναι η διεύθυνση 0x08006A74 — έναρξη λειτουργίας Reset_Handler. Εάν κάνετε κύλιση προς τα κάτω στην καταχώριση, μπορείτε να δείτε την κλήση λειτουργίας κύριος. Μπορείτε να τοποθετήσετε τον κέρσορα σε αυτή τη γραμμή (διεύθυνση 0x08006ABE) και εκτελέστε τη λειτουργία Εκτέλεση μέχρι τον κέρσορα (πλήκτρο F4).

Ρινόκερος μέσα σε γάτα - εκτελέστε το υλικολογισμικό στον εξομοιωτή Kopycat

Στη συνέχεια, μπορείτε να πατήσετε το F7 για να εισέλθετε στη λειτουργία κύριος.

Εάν εκτελέσετε την εντολή Συνεχίστε τη διαδικασία (πλήκτρο F9), τότε θα εμφανιστεί το παράθυρο «Παρακαλώ περιμένετε» με ένα μόνο κουμπί Αναστολή:

Ρινόκερος μέσα σε γάτα - εκτελέστε το υλικολογισμικό στον εξομοιωτή Kopycat

Όταν πατάτε Αναστολή Η εκτέλεση του κωδικού υλικολογισμικού αναστέλλεται και μπορεί να συνεχιστεί από την ίδια διεύθυνση στον κωδικό όπου διακόπηκε.

Εάν συνεχίσετε να εκτελείτε τον κώδικα, θα δείτε τις ακόλουθες γραμμές στα τερματικά που είναι συνδεδεμένα στις εικονικές θύρες COM:

Ρινόκερος μέσα σε γάτα - εκτελέστε το υλικολογισμικό στον εξομοιωτή Kopycat

Ρινόκερος μέσα σε γάτα - εκτελέστε το υλικολογισμικό στον εξομοιωτή Kopycat

Η παρουσία της γραμμής "bypass κατάστασης" υποδηλώνει ότι η εικονική μονάδα Bluetooth έχει μεταβεί στη λειτουργία λήψης δεδομένων από τη θύρα COM του χρήστη.

Τώρα στο τερματικό Bluetooth (COM29 στην εικόνα) μπορείτε να εισάγετε εντολές σύμφωνα με το πρωτόκολλο Rhino. Για παράδειγμα, η εντολή "MEOW" θα επιστρέψει τη συμβολοσειρά "mur-mur" στο τερματικό Bluetooth:

Ρινόκερος μέσα σε γάτα - εκτελέστε το υλικολογισμικό στον εξομοιωτή Kopycat

Μιμηθείτε με όχι εντελώς

Κατά την κατασκευή ενός εξομοιωτή, μπορείτε να επιλέξετε το επίπεδο λεπτομέρειας/εξομοίωσης μιας συγκεκριμένης συσκευής. Για παράδειγμα, η μονάδα Bluetooth μπορεί να προσομοιωθεί με διάφορους τρόπους:

  • η συσκευή προσομοιώνεται πλήρως με ένα πλήρες σύνολο εντολών.
  • Οι εντολές AT προσομοιώνονται και η ροή δεδομένων λαμβάνεται από τη θύρα COM του κύριου συστήματος.
  • η εικονική συσκευή παρέχει πλήρη ανακατεύθυνση δεδομένων στην πραγματική συσκευή.
  • ως απλό στέλεχος που πάντα επιστρέφει "ΟΚ".

Η τρέχουσα έκδοση του εξομοιωτή χρησιμοποιεί τη δεύτερη προσέγγιση - η εικονική μονάδα Bluetooth εκτελεί διαμόρφωση, μετά την οποία μεταβαίνει στη λειτουργία "διαμεσολάβησης" δεδομένων από τη θύρα COM του κύριου συστήματος στη θύρα UART του εξομοιωτή.

Ρινόκερος μέσα σε γάτα - εκτελέστε το υλικολογισμικό στον εξομοιωτή Kopycat

Ας εξετάσουμε τη δυνατότητα απλής ενορχήστρωσης του κώδικα σε περίπτωση που κάποιο τμήμα της περιφέρειας δεν υλοποιηθεί. Για παράδειγμα, εάν δεν έχει δημιουργηθεί ένας χρονοδιακόπτης υπεύθυνος για τον έλεγχο της μεταφοράς δεδομένων στο DMA (ο έλεγχος εκτελείται στη συνάρτηση ws2812b_waitπου βρίσκεται στο 0x08006840), τότε το υλικολογισμικό θα περιμένει πάντα την επαναφορά της σημαίας απασχολημένοςπου βρίσκεται στο 0x200004C4που δείχνει την κατάληψη της γραμμής δεδομένων DMA:

Ρινόκερος μέσα σε γάτα - εκτελέστε το υλικολογισμικό στον εξομοιωτή Kopycat

Μπορούμε να ξεπεράσουμε αυτήν την κατάσταση επαναφέροντας μη αυτόματα τη σημαία απασχολημένος αμέσως μετά την τοποθέτησή του. Στο IDA Pro, μπορείτε να δημιουργήσετε μια συνάρτηση Python και να την καλέσετε σε σημείο διακοπής και να βάλετε το ίδιο το σημείο διακοπής στον κώδικα αφού γράψετε την τιμή 1 στη σημαία απασχολημένος.

Χειριστής σημείου διακοπής

Αρχικά, ας δημιουργήσουμε μια συνάρτηση Python στο IDA. Μενού Αρχείο - Εντολή σεναρίου...

Προσθέστε ένα νέο απόσπασμα στη λίστα στα αριστερά, δώστε του ένα όνομα (για παράδειγμα, BPT),
Στο πεδίο κειμένου στα δεξιά, εισαγάγετε τον κωδικό λειτουργίας:

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

Ρινόκερος μέσα σε γάτα - εκτελέστε το υλικολογισμικό στον εξομοιωτή Kopycat

Μετά από αυτό πιέζουμε τρέξιμο και κλείστε το παράθυρο του σεναρίου.

Τώρα ας πάμε στον κωδικό στο 0x0800688A, ορίστε ένα σημείο διακοπής (πλήκτρο F2), επεξεργαστείτε το (μενού περιβάλλοντος Επεξεργασία σημείου διακοπής...), μην ξεχάσετε να ορίσετε τον τύπο σεναρίου σε Python:

Ρινόκερος μέσα σε γάτα - εκτελέστε το υλικολογισμικό στον εξομοιωτή Kopycat
Ρινόκερος μέσα σε γάτα - εκτελέστε το υλικολογισμικό στον εξομοιωτή Kopycat

Εάν η τρέχουσα τιμή σημαίας απασχολημένος ισούται με 1, τότε θα πρέπει να εκτελέσετε τη συνάρτηση skip_dma στη γραμμή του σεναρίου:

Ρινόκερος μέσα σε γάτα - εκτελέστε το υλικολογισμικό στον εξομοιωτή Kopycat

Εάν εκτελέσετε το υλικολογισμικό για εκτέλεση, η ενεργοποίηση του κώδικα χειριστή σημείου διακοπής μπορεί να φανεί στο παράθυρο IDA Παραγωγή κατά γραμμή Skipping wait ws2812.... Τώρα το υλικολογισμικό δεν θα περιμένει την επαναφορά της σημαίας απασχολημένος.

Αλληλεπίδραση με τον εξομοιωτή

Η εξομοίωση για χάρη της μίμησης είναι απίθανο να προκαλέσει απόλαυση και χαρά. Είναι πολύ πιο ενδιαφέρον εάν ο εξομοιωτής βοηθά τον ερευνητή να δει τα δεδομένα στη μνήμη ή να καθορίσει την αλληλεπίδραση των νημάτων.

Θα σας δείξουμε πώς να δημιουργείτε δυναμικά την αλληλεπίδραση μεταξύ των εργασιών RTOS. Θα πρέπει πρώτα να διακόψετε την εκτέλεση του κώδικα εάν εκτελείται. Αν πάτε στη συνάρτηση bluetooth_task_entry στον κλάδο επεξεργασίας της εντολής "LED" (διεύθυνση 0x080057B8), τότε μπορείτε να δείτε τι δημιουργείται πρώτα και στη συνέχεια στέλνεται στην ουρά του συστήματος ledControlQueueHandle κάποιο μήνυμα.

Ρινόκερος μέσα σε γάτα - εκτελέστε το υλικολογισμικό στον εξομοιωτή Kopycat

Θα πρέπει να ορίσετε ένα σημείο διακοπής για πρόσβαση στη μεταβλητή ledControlQueueHandleπου βρίσκεται στο 0x20000624 και συνεχίστε να εκτελείτε τον κώδικα:

Ρινόκερος μέσα σε γάτα - εκτελέστε το υλικολογισμικό στον εξομοιωτή Kopycat

Ως αποτέλεσμα, η στάση θα γίνει πρώτα στη διεύθυνση 0x080057CA πριν καλέσετε τη συνάρτηση osMailAlloc, στη συνέχεια στη διεύθυνση 0x08005806 πριν καλέσετε τη συνάρτηση osMailPut, μετά από λίγο - στη διεύθυνση 0x08005BD4 (πριν καλέσετε τη συνάρτηση osMailGet), που ανήκει στη συνάρτηση leds_task_entry (LED-task), δηλαδή, οι εργασίες άλλαξαν και τώρα η εργασία LED έλαβε έλεγχο.

Ρινόκερος μέσα σε γάτα - εκτελέστε το υλικολογισμικό στον εξομοιωτή Kopycat

Με αυτόν τον απλό τρόπο μπορείτε να καθορίσετε πώς αλληλεπιδρούν οι εργασίες RTOS μεταξύ τους.

Φυσικά, στην πραγματικότητα, η αλληλεπίδραση των εργασιών μπορεί να είναι πιο περίπλοκη, αλλά χρησιμοποιώντας έναν εξομοιωτή, η παρακολούθηση αυτής της αλληλεπίδρασης γίνεται λιγότερο επίπονη.

Εδώ Μπορείτε να παρακολουθήσετε ένα σύντομο βίντεο της εκκίνησης του εξομοιωτή και της αλληλεπίδρασης με το IDA Pro.

Εκκίνηση με το Radare2

Δεν μπορείτε να αγνοήσετε ένα τέτοιο καθολικό εργαλείο όπως το Radare2.

Για να συνδεθείτε στον εξομοιωτή χρησιμοποιώντας το r2, η εντολή θα μοιάζει με αυτό:

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

Η κυκλοφορία είναι διαθέσιμη τώρα (dc) και παύση εκτέλεσης (Ctrl+C).

Δυστυχώς, αυτή τη στιγμή, το r2 έχει προβλήματα κατά την εργασία με τον διακομιστή υλικού gdb και τη διάταξη μνήμης· εξαιτίας αυτού, τα σημεία διακοπής και τα βήματα δεν λειτουργούν (εντολή ds). Ελπίζουμε ότι αυτό θα διορθωθεί σύντομα.

Τρέξιμο με το Eclipse

Μία από τις επιλογές για τη χρήση του εξομοιωτή είναι ο εντοπισμός σφαλμάτων στο υλικολογισμικό της συσκευής που αναπτύσσεται. Για λόγους σαφήνειας, θα χρησιμοποιήσουμε επίσης το υλικολογισμικό Rhino. Μπορείτε να κάνετε λήψη των πηγών υλικολογισμικού ως εκ τούτου,.

Θα χρησιμοποιήσουμε το Eclipse από το σύνολο ως IDE Πάγκος εργασίας συστήματος για STM32.

Για να φορτώσει ο εξομοιωτής υλικολογισμικό απευθείας μεταγλωττισμένο στο Eclipse, πρέπει να προσθέσετε την παράμετρο firmware=null στην εντολή εκκίνησης του εξομοιωτή:

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

Ρύθμιση διαμόρφωσης εντοπισμού σφαλμάτων

Στο Eclipse, επιλέξτε το μενού Εκτέλεση - Διαμορφώσεις εντοπισμού σφαλμάτων... Στο παράθυρο που ανοίγει, στην ενότητα Εντοπισμός σφαλμάτων υλικού GDB πρέπει να προσθέσετε μια νέα διαμόρφωση και, στη συνέχεια, στην καρτέλα "Κύρια" καθορίστε το τρέχον έργο και την εφαρμογή για εντοπισμό σφαλμάτων:

Ρινόκερος μέσα σε γάτα - εκτελέστε το υλικολογισμικό στον εξομοιωτή Kopycat

Στην καρτέλα "Debugger" πρέπει να καθορίσετε την εντολή GDB:
${openstm32_compiler_path}arm-none-eabi-gdb

Και επίσης εισαγάγετε τις παραμέτρους για τη σύνδεση στον διακομιστή GDB (κεντρικός υπολογιστής και θύρα):

Ρινόκερος μέσα σε γάτα - εκτελέστε το υλικολογισμικό στον εξομοιωτή Kopycat

Στην καρτέλα "Εκκίνηση", πρέπει να καθορίσετε τις ακόλουθες παραμέτρους:

  • ενεργοποίηση πλαισίου ελέγχου Φόρτωση εικόνας (έτσι ώστε η συναρμολογημένη εικόνα υλικολογισμικού φορτώνεται στον εξομοιωτή).
  • ενεργοποίηση πλαισίου ελέγχου Φόρτωση συμβόλων;
  • προσθήκη εντολής εκκίνησης: set $pc = *0x08000004 (ρυθμίστε τον καταχωρητή υπολογιστή στην τιμή από τη μνήμη στη διεύθυνση 0x08000004 - η διεύθυνση αποθηκεύεται εκεί ResetHandler).

Обратите внимание, εάν δεν θέλετε να κάνετε λήψη του αρχείου υλικολογισμικού από το Eclipse, τότε οι επιλογές Φόρτωση εικόνας и Εκτέλεση εντολών δεν χρειάζεται να υποδείξω.

Ρινόκερος μέσα σε γάτα - εκτελέστε το υλικολογισμικό στον εξομοιωτή Kopycat

Αφού κάνετε κλικ στο Εντοπισμός σφαλμάτων, μπορείτε να εργαστείτε σε λειτουργία εντοπισμού σφαλμάτων:

  • βήμα προς βήμα εκτέλεση κώδικα
    Ρινόκερος μέσα σε γάτα - εκτελέστε το υλικολογισμικό στον εξομοιωτή Kopycat
  • αλληλεπίδραση με σημεία διακοπής
    Ρινόκερος μέσα σε γάτα - εκτελέστε το υλικολογισμικό στον εξομοιωτή Kopycat

Σημείωση. Το Eclipse έχει, χμ... κάποιες ιδιορρυθμίες... και πρέπει να ζήσεις με αυτές. Για παράδειγμα, εάν κατά την εκκίνηση του προγράμματος εντοπισμού σφαλμάτων εμφανιστεί το μήνυμα "No source available for "0x0", τότε εκτελέστε την εντολή Step (F5)

Ρινόκερος μέσα σε γάτα - εκτελέστε το υλικολογισμικό στον εξομοιωτή Kopycat

Αντί για ένα συμπέρασμα

Η εξομοίωση εγγενούς κώδικα είναι ένα πολύ ενδιαφέρον πράγμα. Καθίσταται δυνατό για έναν προγραμματιστή συσκευών να διορθώσει το υλικολογισμικό χωρίς μια πραγματική συσκευή. Για έναν ερευνητή, είναι μια ευκαιρία να πραγματοποιήσει δυναμική ανάλυση κώδικα, κάτι που δεν είναι πάντα δυνατό ακόμη και με μια συσκευή.

Θέλουμε να παρέχουμε στους ειδικούς ένα εργαλείο που είναι βολικό, μετρίως απλό και δεν απαιτεί πολλή προσπάθεια και χρόνο για να εγκατασταθεί και να λειτουργήσει.

Γράψτε στα σχόλια για την εμπειρία σας χρησιμοποιώντας εξομοιωτές υλικού. Σας προσκαλούμε να συζητήσουμε και θα χαρούμε να απαντήσουμε σε ερωτήσεις.

Μόνο εγγεγραμμένοι χρήστες μπορούν να συμμετάσχουν στην έρευνα. Συνδεθείτε, Σας παρακαλούμε.

Σε τι χρησιμοποιείτε τον εξομοιωτή;

  • Αναπτύσσω (debug) firmware

  • Ερευνώ το firmware

  • Ξεκινάω παιχνίδια (Dendi, Sega, PSP)

  • κάτι άλλο (γράψτε στα σχόλια)

Ψήφισαν 7 χρήστες. 2 χρήστες απείχαν.

Τι λογισμικό χρησιμοποιείτε για την εξομοίωση εγγενούς κώδικα;

  • QEMU

  • Μονόκερος κινητήρας

  • Πρωτεύς

  • κάτι άλλο (γράψτε στα σχόλια)

Ψήφισαν 6 χρήστες. 2 χρήστες απείχαν.

Τι θα θέλατε να βελτιώσετε στον εξομοιωτή που χρησιμοποιείτε;

  • Θέλω ταχύτητα

  • Θέλω ευκολία εγκατάστασης/εκκίνησης

  • Θέλω περισσότερες επιλογές για αλληλεπίδραση με τον εξομοιωτή (API, άγκιστρα)

  • Είμαι ευχαριστημένος με όλα

  • κάτι άλλο (γράψτε στα σχόλια)

Ψήφισαν 8 χρήστες. 1 χρήστης απείχε.

Πηγή: www.habr.com

Προσθέστε ένα σχόλιο