Rino nĂ« brendĂ«si tĂ« maceve — nisja e firmware-it nĂ« emulatorin Kopycat

Rino nĂ« brendĂ«si tĂ« maceve — nisja e firmware-it nĂ« emulatorin Kopycat

Në kuadër të takimit 0x0A DC7831 DEF CON Nizhny Novgorod Më 16 shkurt prezantuam një raport mbi principet bazë të emulimit të kodit binar dhe zhvillimin tonë - një emulator për platforma harduerike Kopycat.

Në këtë artikull do të përshkruajmë si të nisim firmware-n e pajisjes në emulator, do të demonstrojmë ndërveprimin me debugguerin dhe do të kryejmë një analizë të vogël dinamike të firmware-it.

Pas historia

Një herë e një kohë në një galaktikë të largët, shumë larg

Disa vite më parë, në laboratorin tonë shfaqej nevoja për të studiuar firmware-n e një pajisjeje. Firmware-i ishte i kompresuar dhe shkritej nga bootloaderi. Ai e bënte këtë në një mënyrë të komplikuar, duke kaluar të dhënat disa herë në memorje. Gjithashtu, firmware-i ndërvepronte aktivisht me periferikën. Dhe gjithë kjo ndodhte në një bërthamë MIPS.

Emulatorët që ishin në dispozicion për arsye objektive nuk na përmbushnin, por ne dëshironim të ekzekutonim kodin. Kështu, vendosëm të krijonim emulatorin tonë, i cili do të bënte minimumin dhe do të lejonte të zbulohej firmware-i kryesor. E provuam - arritëm. E mendojmë, çfarë do të ndodhte nëse do të shtonim periferikën, në mënyrë që të ekzekutonim gjithashtu firmware-in kryesor. Nuk ishte shumë e dhimbshme - dhe kështu funksionoi. Sërisht menduam dhe vendosëm të krijonim një emulator të plotë.

Në fund, u krijua një emulator i sistemeve kompjuterike Kopycat.

Rino nĂ« brendĂ«si tĂ« maceve — nisja e firmware-it nĂ« emulatorin Kopycat
Pse Kopycat?

Kemi një lojë fjalësh.

  1. copycat (anglisht, subst. [ˈkɒpÉȘkĂŠt]) - imitues, ndjekĂ«s
  2. cat (anglisht, subst. [ˈkÊt]) - mace, këndshme, kafshë e preferuar e njërit prej krijuesve të projektit
  3. Letra 'K' - nga gjuha e programimit Kotlin

Kopycat

Kur u krijua emulatori, ishin vendosur disa qëllime të qarta:

  • mundĂ«sia pĂ«r tĂ« krijuar mjaft shpejt njĂ« periferik tĂ« ri, modul, bĂ«rthamĂ« procesori;
  • mundĂ«sia pĂ«r tĂ« ndĂ«rtuar njĂ« pajisje virtuale nga modula tĂ« ndryshme;
  • mundĂ«sia pĂ«r tĂ« ngarkuar nĂ« memorien e pajisjes virtuale tĂ« dhĂ«na binarĂ« (firmware);
  • mundĂ«sia pĂ«r tĂ« punuar me snapshotet (pamjet e gjendjes sĂ« sistemit);
  • mundĂ«sia pĂ«r tĂ« ndĂ«rvepruar me emulatorin pĂ«rmes debugguerit tĂ« integruar;
  • njĂ« gjuhĂ« moderne e kĂ«ndshme pĂ«r zhvillim.

Në fund, për realizimin u zgjodh Kotlin, arkitektura e autobusit (kur modulat lidhen midis tyre përmes autobusëve virtualë të të dhënave), JSON - si formati i përshkrimit të pajisjes dhe GDB RSP - si protokolli i ndërveprimit me debugguerin.

Zhvillimi ka vazhduar për pak më shumë se dy vjet dhe vazhdon aktivisht. Gjatë kësaj kohe janë realizuar bërthama procesorike MIPS, x86, V850ES, ARM, PowerPC.

Projekti po rritet dhe ka ardhur koha të prezantohet për publikun e gjerë. Një përshkrim të detajuar të projektit do të bëjmë më vonë, tani do të përqendrohemi në përdorimin e Kopycat.

Për ata të padurueshëm - versionin promo të emulatorit mund ta shkarkoni në lidhjes.

Nosi në emulator

Kujtojmë se më parë, për konferencën SMARTRHINO-2018, u krijua një pajisje provuese "Nosi" për të mësuar aftësitë e inxhinierisë inversë. Procesi i analizës statike të firmware-it u përshkrua në këtë artikull.

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

Na nevojiten:
1) Java 1.8
2) Python dhe moduli Jep për të përdorur Python brenda emulatorit. Një ndërtim WHL të 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ërdorni Eclipse, IDA Pro ose radare2.

Si funksionon?

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

Pajisja reale ("nosi") mund të tregohet në diagramin strukturor:

Rino nĂ« brendĂ«si tĂ« maceve — nisja e firmware-it nĂ« emulatorin Kopycat

Emulatori ka një strukturë modulare dhe pajisja virtuale e përfunduar mund të përshkruhet në një skedë JSON.

JSON me 105 rreshta

{
  "top": true,

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

  // Katalogu 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"}
  ],

  // Portat e jashtme 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 midis komponentëve të plugin-it
  "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"]
  ]
}

Vini re parametrin firmware nĂ« seksionin params — Ă«shtĂ« emri i skedarit qĂ« mund tĂ« ngarkohet nĂ« pajisjen virtuale si firmware.

Pajisja virtuale dhe ndërveprimi i saj me sistemin operativ kryesor mund të përfaqësohet me këtë diagram:

Rino nĂ« brendĂ«si tĂ« maceve — nisja e firmware-it nĂ« emulatorin Kopycat

Ekzemplari aktual i emulatorit përfshin ndërveprimin me portet COM të OS kryesore (UART-në e aktivizimit dhe UART për modulin Bluetooth). Këto mund të jenë porte reale ku janë të lidhura pajisje ose porte virtuale COM (për këtë nevojitet com0com / socat).

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

  • protokolli GDB RSP (pĂ«rkatĂ«sisht, mjetet qĂ« mbĂ«shtesin kĂ«tĂ« protokoll — Eclipse / IDA / radare2);
  • konsola e brendshme e emulatorit (Argparse ose Python).

Portat virtuale COM

Për të ndërvepruar me UART-in e pajisjes virtuale në kompjuterin lokal përmes terminalit, është e nevojshme të krijohet një çift portash virtuale të lidhura. Në rastin tonë, një port përdoret nga emulatori, ndërsa tjetri nga programi-terminal (PuTTY ose screen):

Rino nĂ« brendĂ«si tĂ« maceve — nisja e firmware-it nĂ« emulatorin Kopycat

Përdorimi i com0com

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

Rino nĂ« brendĂ«si tĂ« maceve — nisja e firmware-it nĂ« emulatorin Kopycat

Duhet të aktivizoni opsionin enable buffer overrun për të gjitha portat virtuale të krijuara, ndryshe emulatori do të presë një përgjigje nga porta COM.

Përdorimi i socat

Në sistemet UNIX, portat virtuale COM krijohen automatikisht nga emulatori duke përdorur utilitarin socat, për këtë mjafton të specifikoni një prefiks në emrin e portës kur nisni emulatorin socat:.

Ndërfaqja e brendshme e komandave (Argparse ose Python)

Duke qenë se Kopycat është një aplikacion konsolë, për të ndërvepruar me objekte dhe variable të tij, emulatori ofron dy mundësi ndërfaqe komandash: Argparse dhe Python.

Argparse — Ă«shtĂ« CLI, i integruar nĂ« Kopycat, nĂ« dispozitĂ«n e tĂ« gjithĂ«ve dhe gjithmonĂ«.

CLI alternativ — interpretuese 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 interpretuese Python, e instaluar nĂ« sistemin kryesor tĂ« pĂ«rdoruesit).

Instalimi i modulit Python Jep

Nën Linux, Jep mund të instalohet përmes pip:

pip install jep

Për instalimin e Jep nën Windows, është e nevojshme të instaloni paraprakisht Windows SDK dhe përkatësisht Microsoft Visual Studio. Ne e kemi lehtësuar disi punën tuaj dhe kemi bërë blloqet WHL JEP për versionet aktuale të Python për Windows, kështu që 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ë kryeni në linjën e komandës:

python -c "import jep"

Si përgjigje duhet të merrni mesazhin:

ImportError: Jep nuk mbështetet në Python të vetëpavarur, duhet të jetë i përfshirë në Java.

NĂ« skedarin e komandĂ«s sĂ« emulatorit pĂ«r sistemin tuaj (kopycat.bat — pĂ«r Windows, kopycat — pĂ«r Linux) nĂ« listĂ«n e parametrave DEFAULT_JVM_OPTS shtoni njĂ« parametr tĂ« pĂ«rfshirĂ« Djava.library.path — ai duhet tĂ« pĂ«rmbajĂ« rrugĂ«n deri nĂ« modulun e instaluar Jep.

Si rezultat, për Windows duhet të krijohet një varg i tillë:

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

Nisja e Kopycat

Emulatori është një aplikacion konsolë JVM. Nisim përmes skenarit të linjës së komandës së sistemit operativ (sh/cmd).

Komanda për nisje në Windows:

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

Komanda për nisje në Linux duke përdorur utilitarin 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 — porta TCP, e cila do tĂ« hapet pĂ«r qasje nĂ« serverin GDB;
  • -n rhino — emri i modulit kryesor tĂ« sistemit (pajisja e pĂ«rbĂ«rĂ«);
  • -l user — emri i bibliotekĂ«s pĂ«r tĂ« gjetur modul tĂ« parĂ«;
  • -y library — rruga pĂ«r tĂ« gjetur modulet qĂ« bĂ«jnĂ« pjesĂ« nĂ« pajisje;
  • firmwarerhino_pass.bin — rruga e skedarit tĂ« firmware;
  • COM26 dhe COM28 — porta virtuale COM.

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

18:07:59 INFO [eFactoryBuilder.create ]: Moduli i lartë u krijua me sukses si lartë
18:07:59 INFO [ Module.initializeAndRes]: Po vendosim bërthamën në top.u1_stm32.cortexm0.arm për lartë
18:07:59 INFO [ Module.initializeAndRes]: Po vendosim debugin në top.u1_stm32.dbg për lartë
18:07:59 WARN [ Module.initializeAndRes]: Ndalësi nuk u gjet në lartë...
18:07:59 INFO [ Module.initializeAndRes]: Po inicializojmë portet dhe autobuzat...
18:07:59 WARN [ Module.initializePortsA]: VËMENDJE: Disa porte kanĂ« paralajmĂ«rime, pĂ«rdorni printModulesPortsWarnings pĂ«r t'i parĂ« ato...
18:07:59 FINE [ ARMv6CPU.reset ]: Caktoni adresën e hyrjes në 08006A75
18:07:59 INFO [ Module.initializeAndRes]: Moduli lartë u inicializua me sukses dhe u rindez si një qelizë e lartë!
18:07:59 INFO [ Kopycat.open ]: Duke filluar virtualizimin e bordit lartë[rhino] me arm[ARMv6Core]
18:07:59 INFO [ GDBServer.debuggerModule ]: Caktoni modul të ri debuguese top.u1_stm32.dbg për GDB_SERVER(port=23946,alive=true)
Python >

Bashkëveprimi me IDA Pro

Si skedari burim për analizën në IDA për thjeshtimin e testimit, përdorim firmware 'Një hipopotam' në formën të skedarit ELF (aty është ruajtur metainformacioni).

Ju gjithashtu mund të përdorni firmware-n kryesor pa metainformacion.

Pasi tĂ« nisni Kopycat nĂ« IDA Pro, nĂ« menunĂ« Debugger, shkojmĂ« te pika 'Ndrysho debugin
' dhe zgjedhim 'Debuguese i largĂ«t GDB'. MĂ« pas konfigurojmĂ« lidhjen: menuja Debugger — Procesi opsiones


Vendosni vlerat:

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

Rino nĂ« brendĂ«si tĂ« maceve — nisja e firmware-it nĂ« emulatorin Kopycat

Tani bëhet e disponueshme butoni për nisjen e debugging (clavesi F9):

Rino nĂ« brendĂ«si tĂ« maceve — nisja e firmware-it nĂ« emulatorin Kopycat

E shtypim atĂ« — ndodh lidhja me modulin e debugger-it nĂ« emulator. IDA kalon nĂ« modalitetin e debugging, dritaret shtesĂ« bĂ«hen tĂ« disponueshme: informacion mbi regjistrat, mbi stack-un.

Tani mund të përdorim të gjitha mundësitë standarde të punës me debugger-in:

  • ekzekutimin hap pas hapi tĂ« instruktimeve (Step into dhe Step over — ç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 (çelĂ«si F2).

Lidhja me debugger-in nuk do tĂ« thotĂ« nisja e kodit tĂ« firmware-it. Pozita aktuale pĂ«r ekzekutim duhet tĂ« jetĂ« adresa 0x08006A74 — fillimi i funksionit Reset_Handler. NĂ«se rrotullojmĂ« listing-un mĂ« poshtĂ«, mund tĂ« shohim thirrjen e funksionit main. Mund tĂ« vendosim kursorin mbi kĂ«tĂ« rresht (adresa 0x08006ABE) dhe tĂ« kryejmĂ« operacionin Run until cursor (çelĂ«si F4).

Rino nĂ« brendĂ«si tĂ« maceve — nisja e firmware-it nĂ« emulatorin Kopycat

Më pas mund të shtypim F7 për të hyrë në funksionin main.

Nëse ekzekutojmë komandën Continue process (çelësi F9), do të shfaqet një dritare "Please wait" me vetëm një buton Suspend:

Rino nĂ« brendĂ«si tĂ« maceve — nisja e firmware-it nĂ« emulatorin Kopycat

Duke shtypur Suspend ekzekutimi i kodit të firmware-it pezullohet dhe mund të vazhdojë nga e njëjta adresë në kod, ku u ndërpre.

Nëse vazhdojmë ekzekutimin e kodit, në terminalet e lidhura me portat virtuale COM, mund të shihen rreshta të tillë:

Rino nĂ« brendĂ«si tĂ« maceve — nisja e firmware-it nĂ« emulatorin Kopycat

Rino nĂ« brendĂ«si tĂ« maceve — nisja e firmware-it nĂ« emulatorin Kopycat

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

Tani nĂ« terminalin Bluetooth (nĂ« figurĂ« — COM29) mund tĂ« futen komanda sipas protokollit "Nosoroga". PĂ«r shembull, pĂ«r komandĂ«n "MEOW" nĂ« terminalin Bluetooth do tĂ« kthehet rreshti "mur-mur":

Rino nĂ« brendĂ«si tĂ« maceve — nisja e firmware-it nĂ« emulatorin Kopycat

Më imito ashtu siç duhet

Kur ndërtohet emulatori, mund të zgjidhet niveli i detajimit/emulimit të pajisjes. Për shembull, moduli Bluetooth mund të emulohet në mënyra të ndryshme:

  • emulohet e gjithĂ« pajisja me njĂ« grup tĂ« plotĂ« komandash;
  • emulohen komanda AT, ndĂ«rsa fluksi i tĂ« dhĂ«nave merret nga porti COM i sistemit kryesor;
  • pajisja virtuale siguron njĂ« drejtim tĂ« plotĂ« tĂ« tĂ« dhĂ«nave nĂ« pajisjen reale;
  • si njĂ« thjeshtĂ« zĂ«vendĂ«sim, qĂ« gjithmonĂ« kthen "OK".

NĂ« versionin aktual tĂ« emulatorit pĂ«rdoret qasja e dytĂ« — moduli virtual Bluetooth konfiguron, pastaj kalon nĂ« modin "proksimi" tĂ« tĂ« dhĂ«nave nga porosi COM tĂ« sistemit kryesor nĂ« portin UART tĂ« emulatorit.

Rino nĂ« brendĂ«si tĂ« maceve — nisja e firmware-it nĂ« emulatorin Kopycat

Le t'i hedhim një sy mundësisë për instrumentimin e thjeshtë të kodit nëse ndonjë pjesë periferike nuk është realizuar. Për shembull, nëse nuk është krijuar një timer që kontrollon transferimin e të dhënave në DMA (kontrolli bëhet në funksionin ws2812b_wait, i vendosur në adresë 0x08006840), firmuerja do të presë gjithmonë për të rikuperuar flamurin busy, i vendosur në adresë 0x200004C4, i cili tregon ngarkesën e linjës së të dhënave DMA:

Rino nĂ« brendĂ«si tĂ« maceve — nisja e firmware-it nĂ« emulatorin Kopycat

Ne mund ta anashkalojmë këtë situatë duke "rikuperuar" manualisht flamurin busy menjëherë pas vendosjes së tij. Në IDA Pro mund të krijoni një funksion Python dhe ta thërrisni atë në një pikë ndalimi, duke vendosur pikën e ndalimit në kod pas regjistrimit të vlerës 1 në flamur busy.

Pika e ndalimit

SĂ« pari, krijojmĂ« njĂ« funksion Python nĂ« IDA. Menuja File — Script command


Shtoni një snipp të ri në listën në të majtë, i japim një emër (p.sh., BPT),
në fushën e tekstit në të djathtë shkruajmë kodin e funksionit:

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

Rino nĂ« brendĂ«si tĂ« maceve — nisja e firmware-it nĂ« emulatorin Kopycat

Pasi të kemi përfunduar, klikojmë Ekzekuto dhe mbyllim dritaren e skripteve.

Tani kalojmĂ« nĂ« kodin nĂ« adresĂ«n 0x0800688A, vendosim pikĂ«n e ndalimit (çelĂ«si F2), e modifikojmĂ« atĂ« (menuja kontekstuale Edit breakpoint
), mos e harroni tĂ« vendosni llojin e skriptit – Python:

Rino nĂ« brendĂ«si tĂ« maceve — nisja e firmware-it nĂ« emulatorin Kopycat
Rino nĂ« brendĂ«si tĂ« maceve — nisja e firmware-it nĂ« emulatorin Kopycat

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

Rino nĂ« brendĂ«si tĂ« maceve — nisja e firmware-it nĂ« emulatorin Kopycat

Nëse filloni të ekzekutoni firmuerën, mund të shihni aktivizimin e kodit të menaxherit të pikës së ndalimit në IDA në dritaren Output në rreshtin Duke skipuar pritjen ws2812.... Tani firmuerja nuk do të presë për rikuperimin e flamurit. busy.

Interkazione me emulatorin

Emulimi për emulim, vështirë se do të sjellë gëzim dhe kënaqësi. Më interesante është nëse emulatori ndihmon kërkuesin të shohë të dhënat në memorie ose të vendosë ndërveprimin e rrjedhave.

Të shohim se si të vendosim dinamikin e ndërveprimit të detyrave RTOS. Para së gjithash, duhet të ndalni ekzekutimin e kodit nëse po ekzekutohet. Nëse kaloni në funksionin bluetooth_task_entry në degën e përpunimit të komandës "LED" (adresa 0x080057B8), mund të shihni se fillimisht krijohet dhe më pas dërgohet në radhën sistemike ledControlQueueHandle një mesazh i caktuar.

Rino nĂ« brendĂ«si tĂ« maceve — nisja e firmware-it nĂ« emulatorin Kopycat

Duhet të vendosni një pikë ndalimi në aksesimin e variablës ledControlQueueHandle, i vendosur në adresë 0x20000624 dhe të vazhdoni ekzekutimin e kodit:

Rino nĂ« brendĂ«si tĂ« maceve — nisja e firmware-it nĂ« emulatorin Kopycat

Si rezultat, fillimisht do tĂ« ndaloni nĂ« adresĂ«n 0x080057CA para thirrjes sĂ« funksionit osMailAlloc, pastaj — nĂ« adresĂ«n 0x08005806 para thirrjes sĂ« funksionit osMailPut, dhe mĂ« pas pas njĂ« kohe — nĂ« adresĂ«n 0x08005BD4 (para thirrjes sĂ« funksionit osMailGet), e cila i pĂ«rket funksionit leds_task_entry (detyra LED), qĂ« do tĂ« thotĂ« se ndodhi ndĂ«rrimi i detyrave dhe tani mori kontrollin detyra LED.

Rino nĂ« brendĂ«si tĂ« maceve — nisja e firmware-it nĂ« emulatorin Kopycat

Me këtë mënyrë të thjeshtë mund të vendosni se si detyrat RTOS ndërveprojnë me njëra-tjetrën.

Sigurisht, në realitet ndërveprimi i detyrave mund të jetë më i komplikuar, por duke përdorur emulatorin ndjekja e këtij ndërveprimi bëhet më pak e lodhshme.

Këtu mund të shihni një video të vogël të nisjes së emulatorit dhe ndërveprimit me IDA Pro.

Nisja me Radare2

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

Për të 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, deri më tani në r2 ka probleme kur punohet me serverin gdb të harduerit dhe strukturën e memories, për shkak të kësaj nuk punojnë piketat e ndalimit dhe hapjet (komanda ds). Shpresojmë se në të ardhmen kjo do të rregullohet.

Nisja me Eclipse

NjĂ« nga opsionet pĂ«r tĂ« pĂ«rdorur emulatorin — rregullimi i firmuerĂ«s sĂ« pajisjes nĂ« zhvillim. PĂ«r qartĂ«si, do tĂ« pĂ«rdorim gjithashtu firmuerĂ«n "Noserog". Mund tĂ« shkarkoni kodin burimor tĂ« firmuerĂ«s kĂ«tu.

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

Për që firmuerja të ngarkohet direkt në emulator, e cila është ndërtuar në Eclipse, duhet të shtoni parametrin firmware=null në komandën e lançimit të emulatorit:

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

Konfigurimi i debug

NĂ« Eclipse, zgjedhim menunĂ« Run — Debug Configurations
 NĂ« dritaren e hapur, nĂ« seksionin GDB Hardware Debugging duhet tĂ« shtoni njĂ« konfigurim tĂ« ri, pastaj nĂ« skedĂ«n "Main" tĂ« specifikoni projektin aktual dhe aplikacionin pĂ«r debugging:

Rino nĂ« brendĂ«si tĂ« maceve — nisja e firmware-it nĂ« emulatorin Kopycat

Në skedën "Debugger" duhet të specifikoni komandën GDB:
${openstm32_compiler_path}arm-none-eabi-gdb

Gjithashtu, duhet të futni parametrat për lidhjen me serverin GDB (host dhe port):

Rino nĂ« brendĂ«si tĂ« maceve — nisja e firmware-it nĂ« emulatorin Kopycat

Në skedën "Startup" duhet të specifikoni parametrat e mëposhtëm:

  • tĂ« aktivizoni kutinĂ« Load image (pĂ«r tĂ« siguruar ngarkimin nĂ« emulator tĂ« imazhit tĂ« ndĂ«rtuar tĂ« firmuerĂ«s);
  • tĂ« aktivizoni kutinĂ« Load symbols;
  • shtoni komandĂ«n e lancimit: set $pc = *0x08000004 (vendosni nĂ« regjistrin PC vlerĂ«n nga memorie nĂ« adresĂ«n 0x08000004 — aty ruhet adresa ResetHandler’it).

Kërkojmë vëmendje, nëse nuk dëshironi të ngarkoni skedarin e firmware nga Eclipse, atëherë parametrat Load image dhe Ekzekuto komandat nuk duhen specifikuar.

Rino nĂ« brendĂ«si tĂ« maceve — nisja e firmware-it nĂ« emulatorin Kopycat

Pas klikimit të Debug mund të punoni në mënyrën e debugimit:

  • ekzekutimi hap pas hapi i kodit
    Rino nĂ« brendĂ«si tĂ« maceve — nisja e firmware-it nĂ« emulatorin Kopycat
  • bashkĂ«punimi me pikĂ«t e ndalimit
    Rino nĂ« brendĂ«si tĂ« maceve — nisja e firmware-it nĂ« emulatorin Kopycat

ShĂ«nim. NĂ« Eclipse ka, hmm
 disa veçori
 dhe duhet tĂ« jetoni me to. Ja, pĂ«r shembull, nĂ«se gjatĂ« nisjes sĂ« debugerit del mesazhi «No source available for «0x0″», ju lutem ekzekutoni komandĂ«n Step (F5)

Rino nĂ« brendĂ«si tĂ« maceve — nisja e firmware-it nĂ« emulatorin Kopycat

Në vend të përfundimit

Simulimi i kodit natyror Ă«shtĂ« njĂ« gjĂ« shumĂ« interesante. PĂ«r zhvilluesin e pajisjeve, paraqitet mundĂ«sia pĂ«r tĂ« debuguar firmware pa pajisje reale. PĂ«r hulumtuesin — mundĂ«sia pĂ«r tĂ« kryer analizĂ« dinamike tĂ« kodit, e cila nuk Ă«shtĂ« gjithmonĂ« e mundur edhe nĂ« prani tĂ« pajisjes.

Ne duam t'u ofrojmë profesionistëve një mjet që është i lehtë për t'u përdorur, mjaft i thjeshtë dhe që nuk kërkon shumë përpjekje dhe kohë për konfigurim dhe nisje.

Na shkruani në komentet tuaj për përvojën tuaj në përdorimin e emulatorëve të harduerit. 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 lutemi.

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

  • po zhvilloj (debuvoj) firmware

  • po hulumtoj firmware

  • po luaj lojra (Dendi, Sega, PSP)

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

7 përdorues kanë votuar. 2 përdorues kanë abstenuar.

Cilin soft përdorni për simulim të kodit natyror?

  • QEMU

  • Unicorn engine

  • Proteus

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

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

ÇfarĂ« do tĂ« dĂ«shironit tĂ« pĂ«rmirĂ«sonit nĂ« emulatorin e pĂ«rdorur?

  • dua shpejtĂ«si

  • dua lehtĂ«si nĂ« konfigurim/nisje

  • dua mĂ« shumĂ« mundĂ«si bashkĂ«punimi me emulatorin (API, hooks)

  • jam i kĂ«naqur me gjithçka

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

8 përdorues kanë votuar. 1 përdorues është abstenuar.

Burimi: habr.com

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