Rhinoceros brenda mace — ngremĂ« firmware nĂ« emulatorin Kopycat

Rhinoceros brenda mace — ngremĂ« firmware nĂ« emulatorin Kopycat

NĂ« takimin 0x0A DC7831 DEF CON Nizhny Novgorod MĂ« 16 shkurt, ne paraqitĂ«m njĂ« raport mbi parimet bazĂ« tĂ« emulimit tĂ« kodit binar dhe zhvillimin tonĂ« tĂ« vetĂ« — emuluesin e platformave harduerike. Kopycat.

Në këtë artikull, ne do të paraqesim përshkrimin e nisjes së firmware-it në emulues, do të demonstrojmë ndërveprimin me debug-er-in dhe do të realizojmë një analizë të vogël dinamike të firmware-it.

Historia e mëparshme

Një kohë e gjatë më parë në një galaktikë shumë, shumë larg

Disa vjet më parë, në laboratorin tonë, u shfaq nevoja për të hetuar firmware-in e një pajisjeje. Firmware ishte e kompresuar, e cila u shpërbë deri në bootloader. Ai e bënte këtë në një mënyrë mjaft të komplikuar, duke kaluar disa herë të dhënat në memorie. Po ashtu, firmware-i vetë ndërvepronte aktivisht me periferinë. Dhe gjithë kjo ishte në bërthamën MIPS.

Emuluesit ekzistues, pĂ«r arsye objektive, nuk na kĂ«naqĂ«n, por dĂ«shironim tĂ« lançonim kodin. AtĂ«herĂ« vendosĂ«m tĂ« bĂ«nim emuluesin tonĂ«, i cili do tĂ« bĂ«nte minimumin dhe do tĂ« lejonte shfarosjen e firmware-it kryesor. E provuam — doli mjaft mirĂ«. Menduam, çfarĂ« pĂ«r tĂ« shtuar periferinĂ«, qĂ« tĂ« mund tĂ« ekzekutonim gjithashtu firmware-in kryesor. Nuk ishte shumĂ« e dhimbshme — dhe doli pĂ«rsĂ«ri. PĂ«r njĂ« herĂ« tjetĂ«r, menduam dhe vendosĂ«m tĂ« bĂ«nim njĂ« emulues tĂ« plotĂ«.

Në fund, dolën emulues të sistemeve të llogaritjes. Kopycat.

Rhinoceros brenda mace — ngremĂ« firmware nĂ« emulatorin Kopycat
Pse Kopycat?

Ka një lojë fjalësh.

  1. copycat (angl., subst. [ˈkɒpÉȘkĂŠt]) — imitator, ndjekĂ«s
  2. cat (angl., subst. [ˈkĂŠt]) — mace, kat — kafshĂ« e preferuar e njĂ« prej krijuesve tĂ« projektit
  3. Letra "K" — nga gjuha programuese Kotlin

Kopycat

Kur po krijonim emuluesin, u vendosën disa qëllime të caktuara:

  • mundĂ«sia pĂ«r tĂ« krijuar mjaft shpejt njĂ« periferik, modul, bĂ«rthamĂ« procesori;
  • mundĂ«sia pĂ«r tĂ« ndĂ«rtuar njĂ« pajisje virtuale nga modulet e ndryshme;
  • mundĂ«sia pĂ«r tĂ« ngarkuar nĂ« memorien e pajisjes virtuale çdo tĂ« dhĂ«na binare (firmware);
  • mundĂ«sia pĂ«r tĂ« punuar me snapshot-e (foto tĂ« gjendjes sĂ« sistemit);
  • mundĂ«sia pĂ«r ndĂ«rveprim me emuluesin pĂ«rmes debug-er-it tĂ« integruar;
  • njĂ« gjuhĂ« e kĂ«ndshme moderne pĂ«r zhvillim.

NĂ« fund, pĂ«r realizimin u zgjodh Kotlin, arkitektura e autobusĂ«ve (kĂ«tu modulojnĂ« tĂ« lidhen me njĂ«ra-tjetrĂ«n pĂ«rmes autobusĂ«ve virtualĂ« tĂ« tĂ« dhĂ«nave), JSON — si format pĂ«r pĂ«rshkrimin e pajisjes, dhe GDB RSP — si protokoll ndĂ«rveprimi me debug-er-in.

Zhvillimi ka vazhduar për më shumë se dy vite dhe po vazhdon me intensitet. Gjatë kësaj kohe janë realizuar bërthamat e procesorëve MIPS, x86, V850ES, ARM, PowerPC.

Projekti po rritet dhe ka ardhur koha për ta prezantuar atë për publikun e gjerë. Një përshkrim i detajuar i projektit do të bëhet më vonë, ndërsa tani do të përqendrohemi në përdorimin e Kopycat.

PĂ«r ata qĂ« nuk mund tĂ« presin — mund tĂ« shkarkoni versionin promovues tĂ« emulatorit nga linkun.

Rhinoceros në emulator

Kujtojmë se më parë për konferencën SMARTRHINO-2018 u krijua një pajisje testuese "Rhinoceros" për të mësuar aftësitë e inxhinierisë së përmbajtjes. Procesi i analizës statike të firmware-it u përshkrua në këto artikuj.

Tani do të përpiqemi të shtojmë "dinamik" dhe të nxjerrim firmware-in në emulator.

Na duhen:
1) Java 1.8
2) Python dhe moduli Jep për të përdorur Python brenda emulatorit. Ndërtimi WHL i modulit Jep për Windows mund të shkarkohet këtu.

Për Windows:
1) com0com
2) PuTTY

Për Linux:
1) socat

Si klient GDB mund të përdoret Eclipse, IDA Pro ose radare2.

Si funksionon kjo?

Për të ekzekutuar firmware në emulator, është e nevojshme të "ndërtohet" një pajisje virtuale, e cila është një analog i pajisjes reale.

Pajisja reale ("rhinoceros") mund të tregojë në skemën strukturore:

Rhinoceros brenda mace — ngremĂ« firmware nĂ« emulatorin Kopycat

Emulatori ka një strukturë modulare dhe pajisja virtuale përfundimtare mund të përshkruhet në një skedar JSON.

JSON në 105 rreshta

{
  "top": true,

  // Emri i plugin-it duhet të jetë i njëjtë me emrin e skedarit (ose rrugën e plotë nga fillimi i bibliotekës)
  "plugin": "rhino",

  // Drejtoria ku vendoset plugin-i
  "library": "user",

  // Parametrat e plugin-it (parametrat e konstruktorit nëse është versioni jar-plugin)
  "params": [
    { "name": "tty_dbg", "type": "String"},
    { "name": "tty_bt", "type": "String"},
    { "name": "firmware", "type": "String", "default": "NUL"}
  ],

  // Portet ekstern të plugin-it
  "ports": [  ],

  // Autobusët e brendshëm të plugin-it
  "buses": [
    { "name": "mem", "size": "BUS30" },
    { "name": "nand", "size": "4" },
    { "name": "gpio", "size": "BUS32" }
  ],

  // Komponentët e brendshëm të plugin-it
  "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" }
  ],

  // lidhjet e plugin-it mes komponentëve
  "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"]
  ]
}

Kujdesi me parametrin firmware nĂ« seksionin params — Ă«shtĂ« emri i skedarit qĂ« mund tĂ« ngarkohet nĂ« njĂ« pajisje virtuale si firmware.

Një pajisje virtuale dhe ndërveprimi i saj me sistemin operativ kryesor mund të paraqitet kështu:

Rhinoceros brenda mace — ngremĂ« firmware nĂ« emulatorin Kopycat

Ekzemplari aktual i emulatorit parashikon ndërveprimin me portet COM të sistemit operativ kryesor (UART për debug dhe UART për modulin Bluetooth). Këto mund të jenë porte reale, të cilat janë të lidhura me pajisje ose porte virtuale COM (për këtë saktësisht nevojitet com0com / socat).

Për të ndërvepruar me emulatorin nga jashtë, në këtë moment ekzistojnë dy mënyra kryesore:

  • protokolli GDB RSP (pĂ«rkatĂ«sisht, mjetet qĂ« e mbĂ«shtesin kĂ«tĂ« protokoll — Eclipse / IDA / radare2);
  • interface-i i brendshĂ«m i komandave tĂ« emulatorit (Argparse ose Python).

Portet virtuale COM

PĂ«r tĂ« ndĂ«rvepruar me UART-in e pajisjes virtuale nĂ« makinĂ«n lokale pĂ«rmes terminalit, Ă«shtĂ« e nevojshme tĂ« krijoni njĂ« çift portesh virtuale COM tĂ« lidhura. NĂ« rastin tonĂ«, njĂ« port pĂ«rdoret nga emulatori, dhe tjetri — nga programi-terminal (PuTTY ose screen):

Rhinoceros brenda mace — ngremĂ« firmware nĂ« emulatorin Kopycat

Përdorimi i com0com

Portet virtuale COM konfigurohen me utilitarin setup nga paketa com0com (versioni konsolĂ« — C:Program Files (x86)com0comsetupс.exe, ose versioni GUI — C:Program Files (x86)com0comsetupg.exe):

Rhinoceros brenda mace — ngremĂ« firmware nĂ« emulatorin Kopycat

Duhet të vendosen shenjat enabled buffer overrun për të gjitha portet virtuale të krijuara, ndryshe, emulatori do të presë një përgjigje nga porti COM.

Përdorimi i socat

Në sistemet UNIX, portet virtuale COM krijohen automatikisht nga emulatori duke përdorur utilitarin socat, për këtë është mjaft e mjaftueshme që gjatë nisjes së emulatorit në emrin e portit të specifikohet prefiksi socat:.

Interface-i i brendshëm i komandës (Argparse ose Python)

Duke qenë se Kopycat është një aplikacion në konsolë, për të ndërvepruar me objektet dhe variablat e tij, emulatori ofron dy opcione për ndërfaqen e komandave të linjës: Argparse dhe Python.

Argparse — Ă«shtĂ« CLI, i integruar nĂ« Kopycat, i cili Ă«shtĂ« gjithmonĂ« i aksesueshĂ«m pĂ«r tĂ« gjithĂ«.

CLI alternativ — interpretuesi Python. PĂ«r ta pĂ«rdorur, duhet tĂ« instaloni modulin Python Jep dhe tĂ« konfiguroni emulatorin pĂ«r tĂ« punuar me Python (do tĂ« pĂ«rdoret interpretuesi Python, i instaluar nĂ« sistemin kryesor tĂ« pĂ«rdoruesit).

Instalimi i modulit Python Jep

Nën Linux Jep mund të instalohen përmes pip:

pip install jep

Për të instaluar Jep nën Windows, është e nevojshme të installoni fillimisht Windows SDK dhe versionin përkatës të Microsoft Visual Studio. Ne e kemi lehtësuar pak punën tuaj dhe krijuam NDH-paketat WHL JEP për versionet aktuale të Python për Windows, prandaj moduli mund të instalohet nga skedari:

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

Për të verifikuar instalimin e Jep, duhet të ekzekutoni në komandën e linjës:

python -c "import jep"

Në përgjigje duhet të merrni mesazhin:

ImportError: Jep nuk mbështetet në Python të pavarur, ai duhet të inkorporohet në Java.

NĂ« skedarin e komandĂ«s pĂ«r emulatorin pĂ«r sistemin tuaj (kopycat.bat — pĂ«r Windows, kopycat — pĂ«r Linux) nĂ« listĂ«n e parametrave DEFAULT_JVM_OPTS shtoni parametrin e ri Djava.library.path — ai duhet tĂ« pĂ«rmbajĂ« rrugĂ«n deri te moduli i instaluar Jep.

Si rezultat, për Windows duhet të keni një string të tillë:

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

Startimi i Kopycat

Emulatori është një aplikacion konsolle JVM. Startimi bëhet përmes skenarit të linjës së komandave të sistemit operativ (sh/cmd).

Komanda për startimin nën Windows:

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

Komanda për startimin nën Linux duke përdorur utilitarin socat:

./bin/kopycat -g 23946 -n rhinoceros -l user -y library -p firmware=./firmware/rhino_pass.bin, tty_dbg=socat:./COM26,tty_bt=socat:./COM28

  • -g 23646 — porta TCP, e cila do tĂ« hapet pĂ«r qasje nĂ« serverin GDB;
  • -n rhinoceros — emri i modulit kryesor tĂ« sistemit (dispositivi i pĂ«rmbledhur);
  • -l user — emri i bibliotekĂ«s pĂ«r gjetjen e modulit kryesor;
  • -y library — rruga pĂ«r tĂ« gjetur modulat qĂ« pĂ«rfshihen nĂ« pajisje;
  • firmwarerhino_pass.bin — rruga pĂ«r skedarin e firmware-it;
  • COM26 dhe COM28 — porta virtuale COM.

Si rezultat do të shfaqet një ftesë Python > (ose Argparse >):

18:07:59 INFO [eFactoryBuilder.create]: Moduli top u krijua me sukses si top
18:07:59 INFO [Module.initializeAndRes]: Setup core për top.u1_stm32.cortexm0.arm për top
18:07:59 INFO [Module.initializeAndRes]: Setup debugger për top.u1_stm32.dbg për top
18:07:59 WARN [Module.initializeAndRes]: Tracer nuk u gjet në top...
18:07:59 INFO [Module.initializeAndRes]: Duke inicializuar porta dhe autobusa...
18:07:59 WARN [Module.initializePortsA]: VËREJTJE: Disa porte kanĂ« paralajmĂ«rim pĂ«rdorni printModulesPortsWarnings pĂ«r ta parĂ«...
18:07:59 FINE [ARMv6CPU.reset]: Vendos adresën e pikës së hyrjes në 08006A75
18:07:59 INFO [Module.initializeAndRes]: Moduli top është inicializuar dhe rivendosur me sukses si një qelë top!
18:07:59 INFO [Kopycat.open]: Duke filluar virtualizimin e bordit top[rhinoceros] me arm[ARMv6Core]
18:07:59 INFO [GDBServer.debuggerModule]: Vendos modul të ri debugimi top.u1_stm32.dbg për GDB_SERVER(port=23946,alive=true)
Python >

Ndërveprimi me IDA Pro

Si skedari burim për analizë në IDA për thjeshtimin e testimit përdorim firmware-n "Rhinoceros" në formën e skedarit ELF (aty është ruajtur meta-informacioni).

Ju gjithashtu mund të përdorni firmware-in kryesor pa meta-informacionin.

Pas startimit tĂ« Kopycat nĂ« IDA Pro, nĂ« menunĂ« Debugger shkojmĂ« te pike "Switch debugger
" dhe zgjedhim "Debuggeri i largĂ«t GDB«. MĂ« pas konfiguroni lidhjen: menu Debugger — Opcionet e procesit


Vendosim vlerat:

  • Aplikacioni — çdo vlerĂ«
  • Hostname: 127.0.0.1 (ose adresa IP e makinĂ«s sĂ« largĂ«t ku Ă«shtĂ« aktivizuar Kopycat)
  • Porti: 23946

Rhinoceros brenda mace — ngremĂ« firmware nĂ« emulatorin Kopycat

Tani është e disponueshme butoni për nisjen e debugging (tasti F9):

Rhinoceros brenda mace — ngremĂ« firmware nĂ« emulatorin Kopycat

E shtypim atĂ« — ngjitet me modulin e debugger nĂ« emulator. IDA kalon nĂ« modin e debugging, dhe janĂ« tĂ« disponueshme dritare tĂ« tjera: informacion rreth regjistrave dhe stackut.

Tani mund të përdorim të gjitha mundësitë standarde të punës me debuggerin:

  • ekzekutimi hap pas hapi i instruksioneve (Hyr nĂ« dhe Kaloni nĂ« — çelĂ«sat F7 dhe F8, pĂ«rkatĂ«sisht);
  • nisja dhe pezullimi i ekzekutimit;
  • krijimi i pikave tĂ« ndalimit si nĂ« kod ashtu edhe nĂ« tĂ« dhĂ«na (tasti F2).

Lidhja me debuggerin nuk do tĂ« thotĂ« fillimin e kodit tĂ« firmware. Pozita aktuale pĂ«r ekzekutim duhet tĂ« jetĂ« adresa 0x08006A74 — fillimi i funksionit Reset_Handler. NĂ«se rrotulloni listimin poshtĂ«, mund tĂ« shihni thirrjen e funksionit main. Mund tĂ« vendosni kursorin nĂ« kĂ«tĂ« rresht (adresa 0x08006ABE) dhe tĂ« kryeni operacionin Ekzekuto deri nĂ« kursorin (tasti F4).

Rhinoceros brenda mace — ngremĂ« firmware nĂ« emulatorin Kopycat

Pastaj mund të shtypni F7 për të hyrë në funksionin main.

Nëse ekzekutoni komandën Vazhdo procesin (tasti F9), do të shfaqet dritarja «Ju lutem prisni» me një buton të vetëm Pezullo:

Rhinoceros brenda mace — ngremĂ« firmware nĂ« emulatorin Kopycat

Kur e shtypni Pezullo ekzekutimi i kodit të firmware do të pezullohet dhe mund të vazhdojë nga ajo adresë në kod ku u ndërpre.

Nëse vazhdoni ekzekutimin e kodit, në terminalet e lidhura në portat virtuale COM, mund të shihni këto rreshta:

Rhinoceros brenda mace — ngremĂ« firmware nĂ« emulatorin Kopycat

Rhinoceros brenda mace — ngremĂ« firmware nĂ« emulatorin Kopycat

Prania e rreshtit «state bypass» tregon se moduli virtual Bluetooth ka kaluar në modin e pranimit të të dhënave nga porti COM i përdoruesit.

Tani nĂ« terminalin Bluetooth (nĂ« figurĂ« — COM29) mund tĂ« futni komanda pĂ«rkatĂ«se me protokollin «NjĂ« Rhinoceros». PĂ«r shembull, nĂ« komandĂ«n «MEOW» nĂ« terminalin Bluetooth do tĂ« kthehet rreshti «mur-mur»:

Rhinoceros brenda mace — ngremĂ« firmware nĂ« emulatorin Kopycat

Më emulo, por jo plotësisht

Kur ndërtoni emulatorin, mund të zgjidhni nivelin e detajizimit/emulimit të pajisjes. Kështu, për shembull, moduli Bluetooth mund të emulohet në mënyrë të ndryshme:

  • emulohet plotĂ«sisht pajisja me njĂ« grup tĂ« plotĂ« komandash;
  • emulohen komandat AT, dhe fluksi i tĂ« dhĂ«nave merret nga porta COM e sistemit kryesor;
  • pajisja virtuale siguron njĂ« ridrejtim tĂ« plotĂ« tĂ« tĂ« dhĂ«nave nĂ« pajisjen reale;
  • nĂ« formĂ«n e njĂ« strehimi tĂ« thjeshtĂ«, i cili gjithmonĂ« kthen «OK».

NĂ« versionin aktual tĂ« emulatorit pĂ«rdoret qasja e dytĂ« — moduli virtual Bluetooth konfigurimi kryen konfigurimin, pastaj kalon nĂ« modin "proxy" pĂ«r tĂ« dhĂ«nat nga porta COM e sistemit kryesor nĂ« portin UART tĂ« emulatorit.

Rhinoceros brenda mace — ngremĂ« firmware nĂ« emulatorin Kopycat

Le të shqyrtojmë mundësinë e instrumentimit të thjeshtë të kodit në rast se nuk është realizuar ndonjë pjesë e periferisë. Për shembull, nëse nuk është krijuar një timer, që përgjigjet për kontrollin e transferimit të të dhënave në DMA (kontrolli kryhet në funksionin ws2812b_wait, e cila ndodhet në adresën 0x08006840), atëherë firmware do të priste gjithmonë rinovimin e flamurit busy, i vendosur në adresën 0x200004C4, i cili tregon ngarkesën e linjës së të dhënave DMA:

Rhinoceros brenda mace — ngremĂ« firmware nĂ« emulatorin Kopycat

Ne mund ta anashkalojmë një situatë të tillë duke bërë "rinovimin manual" të flamurit busy menjëherë pas vendosjes së tij. Në IDA Pro mund të krijojmë një funksion Python dhe ta thërrasim atë në breakpoint, duke vendosur vetë breakpoint në kodin pas shkrimit të vlerës 1 në flamur busy.

Përgjegjës i breakpoint-it

Fillimisht krijojmĂ« njĂ« funksion Python nĂ« IDA. Menyu File — Script command


Shtojmë një snippett të ri në listën majtas, i japim një emër (për shembull, BPT),
në fushën e tekstit në të djathtë shkruajmë kodin e funksionit:

def skip_dma():
    print "Duke skip-uar pritjen e ws2812..."
    value = Byte(0x200004C4)
    if value == 1:
        PatchDbgByte(0x200004C4, 0)
return False

Rhinoceros brenda mace — ngremĂ« firmware nĂ« emulatorin Kopycat

Pasi të bëjnë këtë, klikojmë Ekzekuto dhe mbyllim dritaren e skripteve.

Tani le tĂ« kalojmĂ« nĂ« kodin nĂ« adresĂ«n 0x0800688A, vendosim breakpoint (çelĂ«si F2), e redaktojmĂ« atĂ« (konteksti i menusĂ« Edit breakpoint
), mos harroni tĂ« vendosni llojin e skriptĂ«s – Python:

Rhinoceros brenda mace — ngremĂ« firmware nĂ« emulatorin Kopycat
Rhinoceros brenda mace — ngremĂ« firmware nĂ« emulatorin Kopycat

Nëse vlera aktuale e flamurit busy është 1, atëherë duhet ekzekutuar funksioni skip_dma në rreshtin e skripteve:

Rhinoceros brenda mace — ngremĂ« firmware nĂ« emulatorin Kopycat

Nëse e nisni firmware-n për ekzekutimin, atëherë aktivizimi i kodit të përgjegjësit të breakpoint-it mund të shihet në IDA në dritaren Output në rreshtin Duke skip-uar pritjen e ws2812.... Tani firmware nuk do të presë rinovimin e flamurit. busy.

Të bashkëpunojmë me emulatorin

Emulimi vetëm për emulim vështirë se do të shkaktoi entuziazëm dhe gëzim. Më interesante është nëse emulatori ndihmon kërkuesin të shohë të dhënat në memorie ose të vendosë bashkëpunimin e gatishmërisë.

Le të tregojmë se si të vendosim bashkëpunimin e RTOS-tasks në dinamikë. Së pari, duhet të ndërpresim ekzekutimin e kodit, nëse është i nisur. Nëse kalojmë në funksionin bluetooth_task_entry në degën e trajtimit të komandës "LED" (adresa 0x080057B8), atëherë mund të shohim se fillimisht krijohet, pastaj dërgohet në radhën sistemit ledControlQueueHandle një mesazh i caktuar.

Rhinoceros brenda mace — ngremĂ« firmware nĂ« emulatorin Kopycat

Duhet të vendosim breakpoint në përthyerjen e variablës ledControlQueueHandle, e cila ndodhet në adresën 0x20000624 dhe të vazhdojmë ekzekutimin e kodit:

Rhinoceros brenda mace — ngremĂ« firmware nĂ« emulatorin Kopycat

Si fillimisht do tĂ« ndodhĂ« ndalimi nĂ« adresĂ«n 0x080057CA para thirrjes sĂ« funksionit osMailAlloc, mĂ« pas — nĂ« adresĂ«n 0x08005806 para thirrjes sĂ« funksionit osMailPut, pastaj pas njĂ« kohe — nĂ« adresĂ«n 0x08005BD4 (para thirrjes sĂ« funksionit osMailGet), e cila i pĂ«rket funksionit leds_task_entry (LED-task), do tĂ« thotĂ« se ka ndodhur ndĂ«rprerja e task-eve dhe tani kontrollin e ka marrĂ« LED-task.

Rhinoceros brenda mace — ngremĂ« firmware nĂ« emulatorin Kopycat

Me këtë mënyrë të thjeshtë mund të përcaktohet si bashkëveprojnë task-et RTOS me njëri-tjetrin.

Sigurisht, në realitet bashkëveprimi i task-eve mund të jetë më i komplikuar, por duke përdorur emulatorin, gjurmimi i këtij bashkëveprimi bëhet më pak i punës.

Këtu mund të shikoni një video të vogël për nisjen e emulatorit dhe bashkëveprimin me IDA Pro.

Nisja me Radare2

Nuk mund të anashkalohet një mjet të tillë universale si Radare2.

Për t'u lidhur me emulatorin duke përdorur r2, komanda do të duket kështu:

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

Aktualisht janë të disponueshme nisja (dc) dhe ndalimi i ekzekutimit (Ctrl+C).

Fatkeqësisht, për momentin në r2 ka probleme gjatë punës me serverin hardwarë gdb dhe skemën e memories, për këtë arsye nuk funksionojnë pikat e ndalimit dhe hapjeve (komanda ds). Shpresojmë se së shpejti do të rregullohet.

Nisja me Eclipse

Një nga opsionet për përdorimin e emulatorit është debugimi i firmware-it të pajisjes që po zhvillohet. Për qartësi, do të përdorim edhe firmware-in "Noshoroga". Mund të shkarkoni burimet e firmware-it këtu.

Si IDE do të përdorim Eclipse nga paketa System Workbench for STM32.

Për që firmware-i të ngarkohej në emulator direkt i ndërtuar në Eclipse, është e nevojshme të shtoni parametrin firmware=null në komandën e nisjes së emulatorit:

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

Konfigurimi i debug

NĂ« Eclipse zgjidhni menu-nĂ« Run — Debug Configurations
 NĂ« dritaren e hapur nĂ« seksionin GDB Hardware Debugging duhet tĂ« shtoni njĂ« konfigurim tĂ« ri, pas sĂ« cilĂ«s nĂ« skedĂ«n «Main» tĂ« tregoni projektin aktual dhe aplikacionin pĂ«r debugim:

Rhinoceros brenda mace — ngremĂ« firmware nĂ« emulatorin Kopycat

Në skedën «Debugger» duhet të tregoni komandën GDB:
${openstm32_compiler_path}arm-none-eabi-gdb

Dhe gjithashtu të vendosni parametrat për të lidhur me serverin GDB (host dhe port):

Rhinoceros brenda mace — ngremĂ« firmware nĂ« emulatorin Kopycat

Në skedën «Startup» duhet të tregoni parametrat e mëposhtëm:

  • tĂ« aktivizoni kutinĂ« Load image (qĂ« tĂ« merren parasysh ngarkimi nĂ« emulator i imazhit tĂ« ndĂ«rtuar tĂ« firmware-it);
  • tĂ« aktivizoni kutinĂ« Load symbols;
  • shtoni komandĂ«n e nisjes: set $pc = *0x08000004 (tĂ« regjistrosh nĂ« PC vlerĂ«n nga memoria nĂ« adresĂ«n 0x08000004 — aty ruhet adresa tĂ« ResetHandler).

Vini re, nëse nuk dëshiron të ngarkosh skedarin e firmware nga Eclipse, atëherë parametrat Load image dhe Kryej komandat nuk është e nevojshme të specifikosh.

Rhinoceros brenda mace — ngremĂ« firmware nĂ« emulatorin Kopycat

Pas shtypjes së Debug mund të punosh në mënyrën e depuratorit:

  • ekzekutimi hap pas hapi i kodit
    Rhinoceros brenda mace — ngremĂ« firmware nĂ« emulatorin Kopycat
  • interaksioni me piketat e pushimit
    Rhinoceros brenda mace — ngremĂ« firmware nĂ« emulatorin Kopycat

ShĂ«nim. NĂ« Eclipse ka, hmmm
 disa veçori
 dhe me to duhet tĂ« jetosh. Ja, p.sh., nĂ«se gjatĂ« nisjes sĂ« depuratorit shfaqet mesazhi «No source available for «0x0″», atĂ«herĂ« ekzekuto urdhrin Step (F5)

Rhinoceros brenda mace — ngremĂ« firmware nĂ« emulatorin Kopycat

Në përfundim

Emulimi i kodit natyral Ă«shtĂ« njĂ« çështje mjaft interesante. PĂ«r zhvilluesin e pajisjeve shfaqet mundĂ«sia pĂ«r tĂ« depurimi firmware pa pajisje reale. PĂ«r hulumtuesin — mundĂ«sia pĂ«r tĂ« kryer njĂ« analizĂ« dinamike tĂ« kodit, e cila nuk Ă«shtĂ« gjithmonĂ« e mundur edhe nĂ«se ka pajisje.

Ne duam të ofrojmë specialistëve një mjet i cili do të ishte i rehatshëm, relativisht i thjeshtë dhe nuk do të merrte shumë energji dhe kohë për konfigurimin dhe nisjen e tij.

Na shkruani në komente për përvojën tuaj me emuluesit harduerikë. Ju ftojmë në diskutim dhe do të jemi të lumtur t'ju përgjigjemi pyetjeve.

Vetëm përdoruesit e regjistruar mund të marrin pjesë në anketë. Hyni, ju lutem.

Për çfarë e përdorni emuluesin?

  • po zhvilloj (depunoj) firmware

  • po hulumtoj firmware

  • po nis lojra (Dendi, Sega, PSP)

  • diçka tjetĂ«r (shkruani nĂ« komente)

Votuan 7 përdorues. U abstenuan 2 përdorues.

ÇfarĂ« softi po pĂ«rdorni pĂ«r emulimin e kodit natyror?

  • QEMU

  • Unicorn engine

  • Proteus

  • diçka tjetĂ«r (shkruani nĂ« komente)

Gati 6 përdorues votuan. 2 përdorues u abstenuan.

ÇfarĂ« do dĂ«shironit tĂ« pĂ«rmirĂ«sonit nĂ« emuluesin qĂ« pĂ«rdorni?

  • dĂ«shiroj shpejtĂ«si

  • dĂ«shiroj lehtĂ«si nĂ« konfigurim/nisje

  • dĂ«shiroj mĂ« shumĂ« mundĂ«si interaksioni me emuluesin (API, hooks)

  • mĂ« pĂ«lqen gjithçka

  • diçka tjetĂ«r (shkruani nĂ« komente)

Të votojnë 8 përdorues. U përgjigj një përdorues.

Burimi: habr.com

Blini hosting tĂ« besueshĂ«m pĂ«r faqe interneti me mbrojtje nga DDoS, serverĂ« VPS VDS đŸ”„ Blini hosting tĂ« besueshĂ«m pĂ«r faqe interneti me mbrojtje nga DDoS, serverĂ« VPS VDS | ProHoster