Насарог ўнутры ката - запускаем прашыўку ў эмулятары Kopycat

Насарог ўнутры ката - запускаем прашыўку ў эмулятары Kopycat

У рамках сустрэчы 0x0A DC7831 DEF CON Ніжні Ноўгарад 16 лютага мы прадставілі даклад аб базавых прынцыпах эмуляцыі бінарнага кода і ўласнай распрацоўцы - эмулятары апаратных платформ. Kopycat.

У артыкуле мы прывядзем апісанне запуску прашыўкі прылады ў эмулятары, прадэманструем узаемадзеянне з адладчыкам і выканаем невялікі дынамічны аналіз прашыўкі.

перадгісторыя

У long time in galaxy far far away

Пару гадоў таму ў нашай лабараторыі ўзнікла неабходнасць даследаваць прашыўку прылады. Прашыўка была сціснутая, распакоўвалася bootloader'ам. Рабіў ён гэта вельмі затлумленым спосабам, некалькі разоў перакладаючы дадзеныя ў памяці. Ды і сама прашыўка потым актыўна ўзаемадзейнічала з перыферыяй. І ўсё гэта на ядры MIPS.

Наяўныя эмулятары па аб'ектыўных чынніках нас не задаволілі, а жадалася ўсёткі запусціць код. Тады вырашылі зрабіць свой эмулятар, які зробіць мінімум і дазволіць распакаваць асноўную прашыўку. Паспрабавалі - атрымалася. Падумалі, а што калі дадаць перыферыю, каб яшчэ і асноўную прашыўку выконваць. Было не вельмі балюча - і таксама атрымалася. Зноў падумалі і вырашылі рабіць паўнавартасны эмулятар.

У выніку атрымаўся эмулятар вылічальных сістэм Kopycat.

Насарог ўнутры ката - запускаем прашыўку ў эмулятары Kopycat
Чаму Kopycat?

Мае месца гульня слоў.

  1. copycat (англ., наз. [ˈkɒpɪkæt]) — пераймальнік, імітатар
  2. котка (англ., наз. [ˈkæt]) — котка, кот — любімая жывёла аднаго са стваральнікаў праекта
  3. Літара "K" - ад мовы праграмавання Kotlin

Kopycat

Пры стварэнні эмулятара ставіліся зусім вызначаныя мэты:

  • магчымасць дастаткова хутка стварыць новую перыферыю, модуль, працэсарнае ядро;
  • магчымасць сабраць віртуальную прыладу з розных модуляў;
  • магчымасць загрузіць у памяць віртуальнай прылады любыя двайковыя дадзеныя (прашыўку);
  • магчымасць працы са снапшотамі (здымкі стану сістэмы);
  • магчымасць узаемадзеяння з эмулятарам праз убудаваны адладчык;
  • прыемны сучасную мову для распрацоўкі.

У выніку, для рэалізацыі быў абраны Kotlin, шынная архітэктура (гэта калі модулі звязваюцца паміж сабой праз віртуальныя шыны дадзеных), JSON – у якасці фармату апісання прылады, і GDB RSP – у якасці пратакола ўзаемадзеяння з адладчыкам.

Распрацоўка ідзе на працягу крыху больш за два гады і актыўна працягваецца. За гэты час былі рэалізаваны працэсарныя ядры MIPS, x86, V850ES, ARM, PowerPC.

Праект расце, і прыйшоў час прадставіць яго шырокай грамадскасці. Падрабязнае апісанне праекта зробім пазней, а зараз засяродзімся на выкарыстанні Kopycat.

Для самых нецярплівых - прома-версію эмулятара можна спампаваць па спасылцы.

Насарог у эмулятары

Нагадаем, раней для канферэнцыі SMARTRHINO-2018 была створана тэставая прылада «Насарог» для навучання навыкам рэверс-інжынірынгу. Працэс статычнага аналізу прашыўкі быў апісаны ў гэтым артыкуле.

Цяпер жа паспрабуем дадаць "дынамікі" і запусцім прашыўку ў эмулятары.

Нам спатрэбяцца:
1) Java 1.8
2) Python і модуль Джып для выкарыстання Python ўнутры эмулятара. WHL-cборку модуля Jep пад Windows можна спампаваць тут.

Для Windows:
1) com0com
2) PuTTY

Для Linux:
1) socat

У якасці GDB-кліента можна выкарыстоўваць Eclipse, IDA Pro ці radare2.

Як гэта працуе?

Для таго, каб выконваць прашыўку ў эмулятары, неабходна "сабраць" віртуальную прыладу, якое ўяўляе сабой аналаг рэальнай прылады.

Рэальную прыладу («насарог») можна паказаць на структурнай схеме:

Насарог ўнутры ката - запускаем прашыўку ў эмулятары 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"]
  ]
}

Звярніце ўвагу на параметр прашыўкі у раздзеле ПАРАМЕТРЫ - гэта імя файла, які можна загружаць у віртуальную прыладу ў якасці прашыўкі.

Віртуальная прылада і яго ўзаемадзеянне з асноўнай аперацыйнай сістэмай можна прадставіць вось такой схемай:

Насарог ўнутры ката - запускаем прашыўку ў эмулятары Kopycat

Бягучы тэставы асобнік эмулятара мае на ўвазе ўзаемадзеянне з COM-партамі асноўнай АС (адладкавы UART і UART для Bluetooth-модуля). Гэта могуць быць рэальныя парты, да якіх падлучаныя прылады ці ж віртуальныя COM-парты (для гэтага як раз патрэбен com0com / socat).

Для ўзаемадзеяння з эмулятарам звонку на дадзены момант існуе два асноўных спосабу:

  • пратакол GDB RSP (адпаведна, якія падтрымліваюць гэты пратакол, прылады - Eclipse / IDA / radare2);
  • унутраны камандны радок эмулятара (Argparse або Python).

Віртуальныя COM-парты

Для таго каб узаемадзейнічаць з UART-ом віртуальнай прылады на лакальнай машыне праз тэрмінал, неабходна стварыць пару злучаных віртуальных COM-партоў. У нашым выпадку адзін порт задзейнічае эмулятар, а другі - праграма-тэрмінал (PuTTY або screen):

Насарог ўнутры ката - запускаем прашыўку ў эмулятары Kopycat

Выкарыстанне com0com

Віртуальныя COM-парты наладжваюцца setup-утылітай з камплекта com0com (кансольная версія — C:Program Files (x86)com0comsetupс.exe, або GUI-версія - C:Program Files (x86)com0comsetupg.exe):

Насарог ўнутры ката - запускаем прашыўку ў эмулятары Kopycat

Варта ўсталяваць галачкі enable buffer overrun для ўсіх створаных віртуальных партоў, інакш эмулятар будзе чакаць водгуку ад COM-порта.

Выкарыстанне socat

На UNIX-сістэмах віртуальныя COM-парты аўтаматычна ствараюцца эмулятарам пры дапамозе ўтыліты socat, для гэтага досыць пры запуску эмулятара ў імі порта паказаць прэфікс. socat:.

Унутраны інтэрфейс каманднага радка (Argparse ці Python)

Паколькі Kopycat уяўляе сабой кансольнае прыкладанне, для ўзаемадзеяння са сваімі аб'ектамі і зменнымі эмулятар падае два варыянту інтэрфейсу каманднага радка: Argparse і Python.

Argparse – гэта CLI, убудаваны ў Kopycat, ён даступны заўсёды і ўсім.

Альтэрнатыўны CLI – інтэрпрэтатар Python. Для яго выкарыстання неабходна ўсталяваць Python-модуль Jep і наладзіць эмулятар для працы з 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.

У камандным файле эмулятара для вашай сістэмы (kopycat.bat - для Windows, kopycat - для 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

У якасці зыходнага файла для аналізу ў IDA для спрашчэння тэсціравання выкарыстоўваем прашыўку «Насарога» ў выглядзе ELF-файла (там захавана метаінфармацыя).

Вы таксама можаце выкарыстоўваць асноўную прашыўку без метаінфармацыі.

Пасля запуску Kopycat у IDA Pro у меню Debugger ідзем у пункт «Switch debugger…і выбіраемыRemote GDB debugger“. Далей наладжваем падлучэнне: меню Debugger – Process options…

Усталёўваны значэнні:

  • Application - любое значэнне
  • Hostname: 127.0.0.1 (ці IP-адрас выдаленай машыны, дзе запушчаны Kopycat)
  • Порт: 23946

Насарог ўнутры ката - запускаем прашыўку ў эмулятары Kopycat

Цяпер становіцца даступная кнопка запуску адладкі (клавіша F9):

Насарог ўнутры ката - запускаем прашыўку ў эмулятары Kopycat

Націскаем яе - адбываецца падлучэнне да модуля адладчыка ў эмулятары. IDA пераходзіць у рэжым адладкі, становяцца даступныя дадатковыя вокны: інфармацыя аб рэгістрах, аб стэку.

Цяпер мы можам выкарыстоўваць усе стандартныя магчымасці працы з адладчыкам:

  • пакрокавае выкананне інструкцый (Крок у и Пераступаць - клавішы F7 і F8, адпаведна);
  • запуск і прыпыненне выканання;
  • стварэнне кропак супыну як на код, так і на дадзеныя (клавіша F2).

Падлучэнне да адладчыка не азначае запуску кода прашыўкі. Бягучай пазіцыяй для выканання павінен быць адрас 0x08006A74 - пачатак функцыі Reset_Handler. Калі пракруціць лістынг ніжэй, то можна ўбачыць выклік функцыі асноўнай. Можна ўсталяваць курсор на гэтым радку (адрас 0x08006ABE) і выканаць аперацыю Run until cursor (клавіша F4).

Насарог ўнутры ката - запускаем прашыўку ў эмулятары Kopycat

Далей можна націснуць F7, каб зайсці ў функцыю асноўнай.

Калі выканаць каманду Continue process (клавіша F9), то з'явіцца акно "Please wait" з адзінай кнопкай Прыпыняць:

Насарог ўнутры ката - запускаем прашыўку ў эмулятары Kopycat

Пры націску Прыпыняць выкананне кода прашыўкі прыпыняецца і можа быць працягнута з таго ж адраса ў кодзе, дзе было перапынена.

Калі працягнуць выкананне кода, то ў тэрміналах, падлучаных да віртуальных COM-партоў, можна ўбачыць наступныя радкі:

Насарог ўнутры ката - запускаем прашыўку ў эмулятары Kopycat

Насарог ўнутры ката - запускаем прашыўку ў эмулятары Kopycat

Наяўнасць радка "state bypass" кажа аб тым, што віртуальны Bluetooth-модуль перайшоў у рэжым прыёму дадзеных ад COM-порта карыстальніка.

Зараз у Bluetooth-тэрмінале (на малюнку - COM29) можна ўводзіць каманды ў адпаведнасці з пратаколам «Насарога». Напрыклад, на каманду "MEOW" у Bluetooth-тэрмінал вернецца радок "mur-mur":

Насарог ўнутры ката - запускаем прашыўку ў эмулятары Kopycat

Эмулюй мяне не цалкам

Пры пабудове эмулятара можна выбіраць ступень дэталізацыі/эмуляцыі той ці іншай прылады. Так, напрыклад, модуль Bluetooth можна эмуляваць па-рознаму:

  • эмулюецца цалкам прылада з поўным наборам каманд;
  • эмулююцца AT-каманды, а струмень дадзеных прымаецца з COM-порта асноўнай сістэмы;
  • віртуальная прылада забяспечвае поўнае перанакіраванне дадзеных на рэальную прыладу;
  • у выглядзе простай заглушкі, якая заўсёды вяртае "OK".

У бягучай версіі эмулятара выкарыстоўваецца другі падыход – віртуальны Bluetooth-модуль выконвае канфігураванне, пасля чаго пераходзіць у рэжым "праксіравання" дадзеных з COM-порта асноўнай сістэмы ў UART-порт эмулятара.

Насарог ўнутры ката - запускаем прашыўку ў эмулятары Kopycat

Разгледзім магчымасць простай інструментацыі кода ў выпадку, калі не рэалізавана нейкая частка перыферыі. Напрыклад, калі не створаны таймер, які адказвае за кантроль перадачы дадзеных у DMA (праверка выконваецца ў функцыі ws2812b_wait, размешчанай па адрасе 0x08006840), то прашыўка будзе заўсёды чакаць скіду сцяга заняты, размешчанага па адрасе 0x200004C4, які паказвае занятасць лініі дадзеных DMA:

Насарог ўнутры ката - запускаем прашыўку ў эмулятары Kopycat

Мы можам абысці такую ​​сітуацыю шляхам «ручнога» скіду сцяга. заняты адразу пасля яго ўстаноўкі. У IDA Pro можна стварыць Python-функцыю і выклікаць яе ў breakpoint'е, пры гэтым сам breakpoint паставіць у кодзе пасля запісу значэння 1 у сцяг заняты.

Breakpoint-апрацоўшчык

Спачатку створым Python-функцыю ў IDA. Меню File - Script command…

Дадаем новы сниппет ў спісе злева, даём яму імя (напрыклад, БПТ),
у тэкставым полі справа ўводны код функцыі:

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

Насарог ўнутры ката - запускаем прашыўку ў эмулятары Kopycat

Пасля гэтага націскаем прагон і закрываем акно скрыптоў.

Цяпер пяройдзем у код па адрасе 0x0800688A, усталюем breakpoint (клавіша F2), адрэдагуем яго (кантэкснае меню Edit breakpoint…), не забудзем усталяваць тып скрыпту – Python:

Насарог ўнутры ката - запускаем прашыўку ў эмулятары Kopycat
Насарог ўнутры ката - запускаем прашыўку ў эмулятары Kopycat

Калі бягучае значэнне сцяга заняты роўна 1, то варта выканаць функцыю skip_dma у радку скрыптоў:

Насарог ўнутры ката - запускаем прашыўку ў эмулятары Kopycat

Калі запусціць прашыўку на выкананне, то спрацоўванне кода breakpoint-апрацоўшчыка можна ўбачыць у IDA у акне выхад па радку Skipping wait ws2812.... Цяпер прашыўка не будзе чакаць скід сцяга заняты.

Узаемадзеянне з эмулятарам

Эмуляцыя дзеля эмуляцыі ці наўрад выкліча захапленне і радасць. Значна цікавей, калі эмулятар дапаможа даследніку ўбачыць дадзеныя ў памяці або ўсталяваць узаемадзеянне патокаў.

Пакажам, як у дынаміцы ўсталяваць узаемадзеянне RTOS-таскаў. Папярэдне трэба прыпыніць выкананне кода, калі яно запушчана. Калі перайсці ў функцыю bluetooth_task_entry у галіну апрацоўкі каманды «LED» (адрас 0x080057B8), то можна ўбачыць, што спачатку ствараецца, а потым адпраўляецца ў сістэмную чаргу ledControlQueueHandle некаторае паведамленне.

Насарог ўнутры ката - запускаем прашыўку ў эмулятары Kopycat

Варта ўсталяваць breakpoint на зварот да зменнай ledControlQueueHandle, размешчанай па адрасе 0x20000624 і працягнуць выкананне кода:

Насарог ўнутры ката - запускаем прашыўку ў эмулятары Kopycat

У выніку спачатку адбудзецца прыпынак на адрас 0x080057CA перад выклікам функцыі osMailAlloc, далей – па адрасе 0x08005806 перад выклікам функцыі osMailPut, потым праз некаторы час - па адрасе 0x08005BD4 (перад выклікам функцыі osMailGet), які належыць функцыі leds_task_entry (LED-таск), гэта значыць адбылося пераключэнне цягінаў, і зараз кіраванне атрымаў 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-серверам і разметкай памяці, з-за гэтага не працуюць кропкі супыну і Step'ы (каманда ds). Спадзяемся, хуткім часам гэта будзе выпраўлена.

Запуск з Eclipse

Адзін з варыянтаў выкарыстання эмулятара - адладка прашыўкі распрацоўванай прылады. Для навочнасці будзем таксама выкарыстоўваць прашыўку «Насарога». Спампаваць зыходнікі прашыўкі можна адсюль.

У якасці IDE будзем выкарыстоўваць Eclipse з набору System Workbench for STM32.

Для таго, каб у эмулятар загружалася прашыўка непасрэдна сабраная ў Eclipse, неабходна дадаць параметр firmware=null у каманду запуску эмулятара:

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

Настройка debug-канфігурацыі

У Eclipse выбіраемы меню Run - Debug Configurations ... У якое адкрылася акне ў раздзеле GDB Hardware Debugging неабходна дадаць новую канфігурацыю, пасля чаго на ўкладцы «Main» пазначыць бягучы праект і дадатак для адладкі:

Насарог ўнутры ката - запускаем прашыўку ў эмулятары Kopycat

На ўкладцы "Debugger" неабходна пазначыць GDB-каманду:
${openstm32_compiler_path}arm-none-eabi-gdb

А таксама ўвесці параметры для падлучэння да GDB-серверу (хост і порт):

Насарог ўнутры ката - запускаем прашыўку ў эмулятары Kopycat

На ўкладцы "Startup" неабходна пазначыць наступныя параметры:

  • уключыць галачку Загрузіць малюнак (каб выконвалася загрузка ў эмулятар сабранай выявы прашыўкі);
  • уключыць галачку Load symbols;
  • дадаць каманду запуску: set $pc = *0x08000004 (выставіць у рэгістр PC значэнне з памяці па адрасе 0x08000004 - там захоўваецца адрас ResetHandler'а).

Звярніце ўвагу, калі вы не хочаце загружаць файл прашыўкі з Eclipse, то параметры Загрузіць малюнак и Run commands паказваць не трэба.

Насарог ўнутры ката - запускаем прашыўку ў эмулятары Kopycat

Пасля націску Debug можна працаваць у рэжыме адладчыка:

  • пакрокавае выкананне кода
    Насарог ўнутры ката - запускаем прашыўку ў эмулятары Kopycat
  • узаемадзеянне з кропкамі супыну
    Насарог ўнутры ката - запускаем прашыўку ў эмулятары Kopycat

Заўвага. У Eclipse ёсць, хмм… некаторыя асаблівасці… і з імі даводзіцца жыць. Вось, напрыклад, калі пры запуску адладчыка з'явіцца паведамленне "No source available for "0x0"", то выканайце каманду Step (F5)

Насарог ўнутры ката - запускаем прашыўку ў эмулятары Kopycat

замест заключэння

Эмуляцыя натыўнага кода - справа вельмі цікавае. Для распрацоўніка прылад з'яўляецца магчымасць адладжваць прашыўку без рэальнай прылады. Для даследніка - магчымасць праводзіць дынамічны аналіз кода, што не заўсёды магчыма нават пры наяўнасці прылады.

Мы жадаем падаць адмыслоўцам прылада, які быў бы зручны, у меру просты і не адымаў шмат сіл і чакай на сваю наладу і запуск.

Напішыце ў каментарах аб сваім досведзе выкарыстання апаратных эмулятараў. Запрашаем да абмеркавання і будзем рады адказаць на пытанні.

Толькі зарэгістраваныя карыстачы могуць удзельнічаць у апытанні. Увайдзіце, Калі ласка.

Для чаго Вы выкарыстоўваеце эмулятар?

  • распрацоўваю (адладжваю) прашыўкі

  • даследую прашыўкі

  • запускаю гульні (Dendi, Sega, PSP)

  • нешта іншае (напішыце ў каментары)

Прагаласавалі 7 карыстальнікаў. Устрымаліся 2 карыстальніка.

Які софт Вы карыстаецеся для эмуляцыі натыўнага кода?

  • QEMU

  • Unicorn engine

  • Пратэй

  • нешта іншае (напішыце ў каментары)

Прагаласавалі 6 карыстальнікаў. Устрымаліся 2 карыстальніка.

Што б Вам жадалася палепшыць у выкарыстоўваным эмулятары?

  • хочацца хуткасці

  • хочацца зручнасці наладкі / запуску

  • хочацца больш магчымасцяў узаемадзеяння з эмулятарам (API, хукі)

  • мяне ўсё задавальняе

  • нешта іншае (напішыце ў каментары)

Прагаласавалі 8 карыстальнікаў. Устрымаўся 1 карыстач.

Крыніца: habr.com

Дадаць каментар