
Lors de la rĂ©union 0x0A DC7831 Le 16 fĂ©vrier, nous avons prĂ©sentĂ© un rapport sur les principes de base de l'Ă©mulation de code binaire et notre dĂ©veloppement â un Ă©mulateur de plateformes matĂ©rielles. .
Dans cet article, nous décrirons le lancement du firmware d'un dispositif dans l'émulateur, démontrerons l'interaction avec le débogueur et réaliserons une petite analyse dynamique du firmware.
Contexte
Il y a longtemps, dans une galaxie lointaine, trĂšs lointaine
Il y a quelques années, notre laboratoire a eu besoin d'étudier le firmware d'un dispositif. Le firmware était compressé et décompressé par le bootloader. Il le faisait de maniÚre assez complexe, réorganisant plusieurs fois les données en mémoire. De plus, le firmware interagissait activement avec le matériel. Et tout cela sur un noyau MIPS.
Les Ă©mulateurs existants ne nous convenaient pas pour des raisons Ă©videntes, et nous voulions quand mĂȘme exĂ©cuter le code. Nous avons donc dĂ©cidĂ© de crĂ©er notre propre Ă©mulateur qui ferait le minimum et permettrait de dĂ©compresser le firmware principal. Nous avons essayĂ© â ça a marchĂ©. Nous avons rĂ©flĂ©chi, et si nous ajoutions du matĂ©riel pour exĂ©cuter Ă©galement le firmware principal. Cela n'a pas Ă©tĂ© trop douloureux â et ça a aussi marchĂ©. Nous avons encore rĂ©flĂ©chi et dĂ©cidĂ© de crĂ©er un Ă©mulateur complet.
Au final, un émulateur de systÚmes de calcul a été créé. .

Pourquoi Kopycat ?
Il s'agit d'un jeu de mots.
- copycat (anglais, nom [ËkÉpÉȘkĂŠt]) â imitateur, copieur
- cat (anglais, nom [ËkĂŠt]) â chat, le chat â animal de compagnie prĂ©fĂ©rĂ© d'un des crĂ©ateurs du projet
- La lettre « K » vient du langage de programmation Kotlin
Kopycat
Lors de la création de l'émulateur, des objectifs bien définis ont été fixés :
- capacitĂ© Ă crĂ©er rapidement un nouveau matĂ©riel, un module, un cĆur de processeur ;
- capacité à assembler un dispositif virtuel à partir de différents modules ;
- capacité à charger dans la mémoire de l'appareil virtuel n'importe quelle donnée binaire (firmware) ;
- capacité à travailler avec des snapshots (captures d'état du systÚme) ;
- capacité d'interaction avec l'émulateur via un débogueur intégré ;
- un langage de développement moderne et agréable.
Au final, Kotlin a Ă©tĂ© choisi pour les implĂ©mentations, une architecture de bus (c'est lorsque les modules sont reliĂ©s entre eux via des bus de donnĂ©es virtuels), JSON â comme format de description de l'appareil, et GDB RSP â comme protocole d'interaction avec le dĂ©bogueur.
Le dĂ©veloppement a lieu depuis un peu plus de deux ans et se poursuit activement. Au cours de cette pĂ©riode, des cĆurs de processeur MIPS, x86, V850ES, ARM et PowerPC ont Ă©tĂ© rĂ©alisĂ©s.
Le projet grandit, et il est temps de le présenter au grand public. Une description détaillée du projet sera faite plus tard, mais concentrons-nous maintenant sur l'utilisation de Kopycat.
Pour les plus impatients â la version promotionnelle de l'Ă©mulateur peut ĂȘtre tĂ©lĂ©chargĂ©e Ă .
Rhinocéros dans l'émulateur
Rappelons qu'un dispositif de test dénommé « Rhinocéros » a été créé pour la conférence SMARTRHINO-2018 afin d'apprendre des compétences en reverse engineering. Le processus d'analyse statique du firmware a été décrit dans .
Nous allons maintenant essayer d'ajouter un peu de « dynamique » et lancer le firmware dans l'émulateur.
Nous aurons besoin de :
1) Java 1.8
2) Python et le module pour utiliser Python Ă l'intĂ©rieur de l'Ă©mulateur. L'assemblage WHL du module Jep sous Windows peut ĂȘtre .
Pour Windows :
1)
2)
Pour Linux :
1) socat
Comme client GDB, vous pouvez utiliser Eclipse, IDA Pro ou radare2.
Comment cela fonctionne ?
Pour exécuter le firmware dans l'émulateur, il est nécessaire de « construire » un dispositif virtuel qui représente un équivalent du dispositif réel.
Le dispositif rĂ©el (« rhinocĂ©ros ») peut ĂȘtre illustrĂ© par le schĂ©ma structurel :

L'Ă©mulateur possĂšde une structure modulaire et le dispositif virtuel final peut ĂȘtre dĂ©crit dans un fichier JSON.
JSON de 105 lignes
{
"top": true,
// Le nom du plugin doit ĂȘtre le mĂȘme que le nom du fichier (ou le chemin complet depuis le dĂ©but de la bibliothĂšque)
"plugin": "rhino",
// RĂ©pertoire oĂč le plugin place
"library": "user",
// ParamĂštres du plugin (paramĂštres du constructeur si version jar-plugin)
"params": [
{ "name": "tty_dbg", "type": "String"},
{ "name": "tty_bt", "type": "String"},
{ "name": "firmware", "type": "String", "default": "NUL"}
],
// Ports externes du plugin
"ports": [ ],
// Bus internes du plugin
"buses": [
{ "name": "mem", "size": "BUS30" },
{ "name": "nand", "size": "4" },
{ "name": "gpio", "size": "BUS32" }
],
// Composants internes du plugin
"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" }
],
// Connexion du plugin entre les composants
"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"]
]
}Veuillez prĂȘter attention au paramĂštre firmware dans la section params â c'est le nom du fichier que vous pouvez tĂ©lĂ©charger sur l'appareil virtuel en tant que firmware.
Un appareil virtuel et son interaction avec le systĂšme d'exploitation principal peuvent ĂȘtre reprĂ©sentĂ©s par le schĂ©ma suivant :

L'instance actuelle de l'Ă©mulateur permet l'interaction avec les ports COM du systĂšme d'exploitation principal (UART de dĂ©bogage et UART pour le module Bluetooth). Cela peut ĂȘtre des ports rĂ©els auxquels des appareils sont connectĂ©s ou des ports COM virtuels (c'est exactement ce dont ont besoin com0com / socat).
Pour interagir avec l'émulateur depuis l'extérieur, il existe actuellement deux principales méthodes :
- le protocole GDB RSP (les outils qui prennent en charge ce protocole â Eclipse / IDA / radare2) ;
- l'interface de ligne de commande interne de l'émulateur (Argparse ou Python).
Ports COM virtuels
Pour interagir avec le UART de l'appareil virtuel sur la machine locale via un terminal, il est nĂ©cessaire de crĂ©er une paire de ports COM virtuels liĂ©s. Dans notre cas, un port est utilisĂ© par l'Ă©mulateur, et l'autre â par le programme terminal (PuTTY ou screen) :

Utilisation de com0com
Les ports COM virtuels sont configurĂ©s Ă l'aide de l'utilitaire setup du package com0com (version console â C:Program Files (x86)com0comsetupŃ.exe, ou version GUI â C:Program Files (x86)com0comsetupg.exe):

Il convient d'activer les options enable buffer overrun pour tous les ports virtuels créés, sinon l'émulateur attendra une réponse du port COM.
Utilisation de socat
Sur les systÚmes UNIX, les ports COM virtuels sont automatiquement créés par l'émulateur à l'aide de l'utilitaire socat, il suffit à cet effet, lors du lancement de l'émulateur, de spécifier le préfixe dans le nom du port socat :.
Interface interne de ligne de commande (Argparse ou Python)
Ătant donnĂ© que Kopycat est une application en ligne de commande, pour interagir avec ses objets et variables, l'Ă©mulateur propose deux options d'interface de ligne de commande : Argparse et Python.
Argparse est une interface CLI intégrée à Kopycat, elle est toujours accessible à tous.
L'alternative CLI est l'interpréteur Python. Pour l'utiliser, il est nécessaire d'installer le module Python Jep et de configurer l'émulateur pour travailler avec Python (l'interpréteur Python installé sur le systÚme principal de l'utilisateur sera utilisé).
Installation du module Python Jep
Sous Linux, Jep peut ĂȘtre installĂ© via pip :
pip install jepPour installer Jep sous Windows, il est nĂ©cessaire de prĂ©alablement installer Windows SDK et la version correspondante de Microsoft Visual Studio. Nous avons un peu simplifiĂ© votre tĂąche en fournissant JEP pour les versions actuelles de Python sous Windows, donc le module peut ĂȘtre installĂ© Ă partir du fichier :
pip install jep-3.8.2-cp27-cp27m-win_amd64.whlPour vérifier l'installation de Jep, il est nécessaire d'exécuter dans l'invite de commandes :
python -c "import jep"La rĂ©ponse doit ĂȘtre le message suivant :
ImportError : Jep n'est pas supportĂ© dans Python autonome, il doit ĂȘtre intĂ©grĂ© dans Java.Dans le fichier de commande de l'Ă©mulateur pour votre systĂšme (kopycat.bat â pour Windows, kopycat â pour Linux) ajoutez le paramĂštre supplĂ©mentaire Ă la liste de paramĂštres DEFAULT_JVM_OPTS ajoutez le paramĂštre supplĂ©mentaire Djava.library.path â il doit contenir le chemin vers le module Jep installĂ©.
Par conséquent, pour Windows, la chaßne devrait ressembler à ceci :
set DEFAULT_JVM_OPTS="-XX:MaxMetaspaceSize=256m" "-XX:+UseParallelGC" "-XX:SurvivorRatio=6" "-XX:-UseGCOverheadLimit" "-Djava.library.path=C:/Python27/Lib/site-packages/jep"Lancement de Kopycat
L'émulateur est une application JVM en ligne de commande. Le lancement se fait via un script de l'invite de commandes du systÚme d'exploitation (sh/cmd).
Commande pour lancer sous Windows :
binkopycat -g 23946 -n rhino -l user -y library -p firmware=firmwarerhino_pass.bin,tty_dbg=COM26,tty_bt=COM28Commande pour lancer sous Linux en utilisant l'outil 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â le port TCP qui sera ouvert pour accĂ©der au serveur GDB ;-n rhinoâ le nom du module principal du systĂšme (dispositif assemblĂ©) ;-l userâ le nom de la bibliothĂšque pour rechercher le module principal ;-y libraryâ le chemin pour rechercher les modules compris dans le dispositif ;firmwarerhino_pass.binâ chemin vers le fichier de firmware ;- COM26 et COM28 â ports COM virtuels.
En conséquence, une invite sera affichée Python > ou Argparse >):
18:07:59 INFO [eFactoryBuilder.create ]: Le module top a été créé avec succÚs comme top
18:07:59 INFO [ Module.initializeAndRes]: Configuration du cĆur pour top.u1_stm32.cortexm0.arm pour top
18:07:59 INFO [ Module.initializeAndRes]: Configuration du débogueur pour top.u1_stm32.dbg pour top
18:07:59 WARN [ Module.initializeAndRes]: Tracer non trouvé dans top...
18:07:59 INFO [ Module.initializeAndRes]: Initialisation des ports et bus...
18:07:59 WARN [ Module.initializePortsA]: ATTENTION : Certains ports ont un avertissement, utilisez printModulesPortsWarnings pour le voir...
18:07:59 FINE [ ARMv6CPU.reset ]: Définir l'adresse du point d'entrée sur 08006A75
18:07:59 INFO [ Module.initializeAndRes]: Le module top est initialisé et réinitialisé avec succÚs en tant que cellule toppen !
18:07:59 INFO [ Kopycat.open ]: Démarrage de la virtualisation de la carte top[rhino] avec arm[ARMv6Core]
18:07:59 INFO [ GDBServer.debuggerModule ]: Nouveau module de débogage set top.u1_stm32.dbg pour GDB_SERVER(port=23946,alive=true)
Python >Interaction avec IDA Pro
Comme fichier source pour l'analyse dans IDA pour faciliter le test, nous utilisons le firmware « Rhino » sous forme de (qui contient des métadonnées).
Vous pouvez également utiliser le firmware principal sans métadonnées.
AprĂšs le lancement de Kopycat dans IDA Pro, dans le menu DĂ©bogueur, allons Ă l'Ă©lĂ©ment «Switch debuggerâŠÂ» et choisissons «DĂ©bogueur GDB distant«. Ensuite, configurons la connexion : menu DĂ©bogueur â Options de processusâŠ
Nous définissons les valeurs :
- Application â n'importe quelle valeur
- Nom d'hĂŽte : 127.0.0.1 (ou l'adresse IP de la machine distante oĂč Kopycat est exĂ©cutĂ©)
- Port : 23946

Le bouton de démarrage du débogage (touche F9) devient maintenant disponible :
![]()
Nous cliquons dessus â cela connecte au module de dĂ©bogage sur l'Ă©mulateur. IDA passe en mode dĂ©bogage, et des fenĂȘtres supplĂ©mentaires deviennent accessibles : informations sur les registres, sur la pile.
Nous pouvons maintenant utiliser toutes les fonctionnalités standard du débogueur :
- exĂ©cution pas Ă pas des instructions (Entrer dans et Sauter â les touches F7 et F8, respectivement) ;
- lancer et suspendre l'exécution ;
- crĂ©er des points d'arrĂȘt Ă la fois sur le code et sur les donnĂ©es (touche F2).
Se connecter au dĂ©bogueur ne signifie pas dĂ©marrer le code du firmware. La position actuelle pour l'exĂ©cution doit ĂȘtre l'adresse 0x08006A74 â dĂ©but de la fonction Reset_Handler. Si nous faisons dĂ©filer le listing en dessous, nous pouvons voir l'appel de la fonction main. Nous pouvons placer le curseur sur cette ligne (adresse 0x08006ABE) et exĂ©cuter l'opĂ©ration ExĂ©cuter jusqu'au curseur (touche F4).

Ensuite, nous pouvons appuyer sur F7 pour entrer dans la fonction main.
Si nous exĂ©cutons la commande Continuer le processus (touche F9), une fenĂȘtre «Veuillez patienter» apparaĂźtra avec le seul bouton Suspendre:

En appuyant sur Suspendre l'exĂ©cution du code de firmware est suspendue et peut ĂȘtre reprise Ă la mĂȘme adresse dans le code oĂč elle a Ă©tĂ© interrompue.
Si nous continuons l'exécution du code, dans les terminaux connectés aux ports COM virtuels, nous pouvons voir les lignes suivantes :


La présence de la ligne «state bypass» indique que le module Bluetooth virtuel est passé en mode de réception de données depuis le port COM de l'utilisateur.
Nous pouvons maintenant entrer des commandes dans le terminal Bluetooth (sur l'image â COM29) conformĂ©ment au protocole «RhinocĂ©ros». Par exemple, pour la commande «MEOW», le terminal Bluetooth retournera la ligne «mur-mur» :

Ne m'émule pas complÚtement
Lors de la construction de l'Ă©mulateur, il est possible de choisir le degrĂ© de dĂ©tail/l'Ă©mulation de tel ou tel appareil. Par exemple, le module Bluetooth peut ĂȘtre Ă©mulĂ© de diffĂ©rentes maniĂšres :
- l'appareil est entiÚrement émulé avec un ensemble complet de commandes;
- les commandes AT sont émoulées, et le flux de données est reçu depuis le port COM du systÚme principal;
- l'appareil virtuel assure un redirectionnement complet des données vers l'appareil réel;
- sous la forme d'une simple prise qui renvoie toujours «OK».
Dans la version actuelle de l'émulateur, une deuxiÚme approche est utilisée : un module Bluetooth virtuel effectue la configuration, puis passe en mode de « proxy » des données du port COM du systÚme principal vers le port UART de l'émulateur.

ConsidĂ©rons la possibilitĂ© d'instrumenter facilement le code dans le cas oĂč une partie du matĂ©riel n'est pas implĂ©mentĂ©e. Par exemple, si un minuteur n'est pas créé pour contrĂŽler le transfert de donnĂ©es en DMA (la vĂ©rification se fait dans la fonction ws2812b_wait, situĂ©e Ă l'adresse 0x08006840), le firmware attendra toujours le rĂ©initialisation du drapeau busy, situĂ© Ă l'adresse 0x200004C4, qui indique si la ligne de donnĂ©es DMA est occupĂ©e :

Nous pouvons contourner cette situation par un rĂ©initialisation « manuelle » du drapeau busy immĂ©diatement aprĂšs son installation. Dans IDA Pro, vous pouvez crĂ©er une fonction Python et l'appeler dans un point d'arrĂȘt, en plaçant le point d'arrĂȘt dans le code aprĂšs avoir enregistrĂ© la valeur 1 dans le drapeau busy.
Gestionnaire de point d'arrĂȘt
Commençons par crĂ©er une fonction Python dans IDA. Menu Fichier â Commande de scriptâŠ
Ajoutons un nouveau snippet dans la liste de gauche, donnons-lui un nom (par exemple, BPT),
dans le champ de texte Ă droite, saisissons le code de la fonction :
def skip_dma():
print "Skipping wait ws2812..."
value = Byte(0x200004C4)
if value == 1:
PatchDbgByte(0x200004C4, 0)
return False 
AprĂšs cela, nous cliquons sur ExĂ©cution et fermons la fenĂȘtre des scripts.
Maintenant, allons dans le code Ă l'adresse 0x0800688A, plaçons un point d'arrĂȘt (touche F2), modifions-le (menu contextuel Modifier le point d'arrĂȘtâŠ), n'oubliez pas de dĂ©finir le type de script â Python :


Si la valeur actuelle du drapeau busy est Ă©gale Ă 1, alors la fonction skip_dma devrait ĂȘtre exĂ©cutĂ©e dans la ligne de scripts :

Si nous lançons le firmware pour l'exĂ©cution, nous pouvons voir l'exĂ©cution du code du gestionnaire de point d'arrĂȘt dans IDA dans la fenĂȘtre Sortie par la ligne Skipping wait ws2812.... Maintenant, le firmware ne devrait pas attendre la rĂ©initialisation du drapeau. busy.
Interaction avec l'émulateur
L'émulation juste pour le plaisir d'émuler ne suscitera probablement pas d'enthousiasme. Il est beaucoup plus intéressant si l'émulateur aide le chercheur à voir des données en mémoire ou à établir l'interaction des flux.
Voyons comment établir dynamiquement l'interaction des tùches RTOS. Au préalable, il faut suspendre l'exécution du code, si elle est en cours. Si vous accédez à la fonction bluetooth_task_entry dans la branche de traitement de la commande « LED » (adresse 0x080057B8), vous pouvez voir qu'un message est d'abord créé, puis envoyé dans la queue systÚme ledControlQueueHandle .

Il convient de placer un point d'arrĂȘt sur l'accĂšs Ă la variable ledControlQueueHandle, situĂ©e Ă l'adresse 0x20000624 et de continuer l'exĂ©cution du code :

En consĂ©quence, un arrĂȘt se produira d'abord Ă l'adresse 0x080057CA avant l'appel de la fonction osMailAlloc, ensuite, Ă l'adresse 0x08005806 avant l'appel de la fonction osMailPut, puis aprĂšs un certain temps, Ă l'adresse 0x08005BD4 (avant l'appel de la fonction osMailGet), qui appartient Ă la fonction leds_task_entry (tĂąche LED), c'est-Ă -dire qu'il y a eu un changement de tĂąche, et maintenant, la gestion est passĂ©e Ă la tĂąche LED.

Cette méthode simple permet d'établir comment les tùches RTOS interagissent les unes avec les autres.
Bien sĂ»r, en rĂ©alitĂ©, l'interaction des tĂąches peut ĂȘtre plus complexe, mais avec l'utilisation d'un Ă©mulateur, le suivi de cette interaction devient moins ardu.
On peut visionner une courte vidéo sur le lancement de l'émulateur et l'interaction avec IDA Pro.
Lancement avec Radare2
On ne peut pas ignorer un outil aussi polyvalent que Radare2.
Pour se connecter à l'émulateur en utilisant r2, la commande sera la suivante :
radare2 -A -a arm -b 16 -d gdb://localhost:23946 rhino_fw42k6.elfActuellement, le démarrage (dc) et la pause d'exécution (Ctrl+C) sont disponibles.
Malheureusement, pour le moment, r2 prĂ©sente des problĂšmes lors de l'utilisation du serveur gdb matĂ©riel et de la mise en page de la mĂ©moire, ce qui empĂȘche les points d'arrĂȘt et les Ă©tapes (commande ds). Nous espĂ©rons que cela sera corrigĂ© prochainement.
Lancement avec Eclipse
Une des façons d'utiliser l'émulateur est de déboguer le firmware de l'appareil en développement. Pour plus de clarté, nous allons également utiliser le firmware "Rhinocéros". Vous pouvez télécharger le code source du firmware .
Nous allons utiliser Eclipse comme IDE de l'ensemble .
Pour que le firmware, directement compilé dans Eclipse, soit chargé dans l'émulateur, il est nécessaire d'ajouter le paramÚtre firmware=null à la commande de lancement de l'émulateur :
binkopycat -g 23946 -n rhino -l user -y modules -p firmware=null,tty_dbg=COM26,tty_bt=COM28Configuration de debug
Dans Eclipse, choisissez le menu ExĂ©cuter â Configurations de debug⊠Dans la fenĂȘtre qui s'ouvre, sous la section GDB Hardware Debugging il est nĂ©cessaire d'ajouter une nouvelle configuration, aprĂšs quoi, dans l'onglet « Principal », indiquer le projet actuel et l'application Ă dĂ©boguer :

Dans l'onglet « Débogueur », il est nécessaire d'indiquer la commande GDB :
${openstm32_compiler_path}arm-none-eabi-gdb
Et également d'entrer les paramÚtres pour se connecter au serveur GDB (hÎte et port) :

Dans l'onglet « Démarrage », il est nécessaire d'indiquer les paramÚtres suivants :
- cocher la case Load image (pour que le chargement de l'image compilée du firmware soit effectué dans l'émulateur) ;
- cocher la case Load symbols;
- ajouter la commande de lancement :
set $pc = *0x08000004(dĂ©finir la valeur PC Ă partir de la mĂ©moire Ă l'adresse0x08000004â lĂ oĂč l'adresse est stockĂ©e ResetHandler).
Veuillez noter, si vous ne souhaitez pas charger le fichier de firmware depuis Eclipse, alors les paramÚtres Load image et Exécutez les commandes ne sont pas nécessaires.

AprÚs avoir cliqué sur Debug, vous pouvez travailler en mode débogage :
- exécution pas à pas du code

- interactions avec les points d'arrĂȘt

Remarque. Dans Eclipse, il y a, euh⊠certaines spécificités⊠et il faut vivre avec. Par exemple, si un message « No source available for «0x0Ⳡ» apparaßt au lancement du débogueur, exécutez la commande Step (F5)

En conclusion
L'Ă©mulation du code natif est un sujet particuliĂšrement intĂ©ressant. Pour le dĂ©veloppeur d'appareils, cela permet de dĂ©boguer le firmware sans appareil rĂ©el. Pour le chercheur, c'est une opportunitĂ© de rĂ©aliser une analyse dynamique du code, ce qui n'est pas toujours possible mĂȘme avec un appareil.
Nous voulons fournir aux spécialistes un outil qui soit pratique, relativement simple et qui ne prenne pas trop de temps et d'efforts pour sa configuration et son lancement.
Ăcrivez dans les commentaires votre expĂ©rience avec les Ă©mulateurs matĂ©riels. Nous vous invitons Ă discuter et nous serons ravis de rĂ©pondre Ă vos questions.
Seuls les utilisateurs enregistrés peuvent participer au sondage. , s'il vous plaßt.
Pourquoi utilisez-vous l'émulateur ?
je développe (débogue) des firmwares
j'analyse des firmwares
je lance des jeux (Dendi, Sega, PSP)
autre chose (écrivez dans les commentaires)
7 utilisateurs ont voté. 2 utilisateurs se sont abstenus.
Quel logiciel utilisez-vous pour l'émulation de code natif ?
QEMU
Moteur Unicorn
Proteus
autre chose (écrivez dans les commentaires)
6 utilisateurs ont voté. 2 utilisateurs se sont abstenus.
Qu'aimeriez-vous améliorer dans l'émulateur utilisé ?
je souhaite de la rapidité
je souhaite un réglage/lancement plus facile
je souhaite plus d'options d'interaction avec l'émulateur (API, hooks)
tout me convient
autre chose (écrivez dans les commentaires)
8 utilisateurs ont voté. 1 utilisateur s'est abstenu.
Source : habr.com


