ٻلي جي اندر گينڊا - ڪوپي ڪيٽ ايموليٽر ۾ فرم ویئر کي هلائي

ٻلي جي اندر گينڊا - ڪوپي ڪيٽ ايموليٽر ۾ فرم ویئر کي هلائي

اجلاس جي حصي جي طور تي 0x0A DC7831 DEF CON Nizhny Novgorod 16 февраля мы представили доклад о базовых принципах эмуляции бинарного кода и собственной разработке — эмуляторе аппаратных платформ ڪاپي ڪيٽ.

هن آرٽيڪل ۾ اسين بيان ڪنداسين ته ايموليٽر ۾ ڊوائيس فرم ویئر کي ڪيئن هلائڻ، ڊيبگر سان رابطي جو مظاهرو ڪيو، ۽ فرمائيندڙ جو ننڍڙو متحرڪ تجزيو انجام ڏيو.

prehistory

گهڻو وقت اڳ هڪ ڪهڪشان ۾ تمام گهڻو پري

ڪجهه سال اڳ اسان جي ليبارٽري ۾ هڪ ڊوائيس جي firmware جي تحقيق ڪرڻ جي ضرورت هئي. فرم ویئر کي دٻايو ويو ۽ بوٽ لوڊر سان انپيڪ ڪيو ويو. هن اهو ڪم تمام پيچيده طريقي سان ڪيو، ڊيٽا کي ڪيترائي ڀيرا ميموري ۾ شفٽ ڪيو. ۽ فرمائيندڙ پاڻ وري فعال طور تي پرديئرز سان رابطو ڪيو. ۽ اهو سڀ ڪجهه MIPS ڪور تي.

مقصدي سببن جي ڪري، دستياب ايموليٽر اسان کي مناسب نه هئا، پر اسان اڃا تائين ڪوڊ هلائڻ چاهيون ٿا. ان کان پوء اسان فيصلو ڪيو ته اسان جو پنهنجو ايموليٽر ٺاهيو، جيڪو گهٽ ۾ گهٽ ڪندو ۽ اسان کي اجازت ڏيندو ته مکيه فرم ویئر کي کولڻ لاء. اسان ان جي ڪوشش ڪئي ۽ اهو ڪم ڪيو. اسان سوچيو، ڇا جيڪڏهن اسان مکيه فرم ويئر کي انجام ڏيڻ لاء پرديئرز شامل ڪيو. اهو تمام گهڻو نقصان نه ٿيو - ۽ اهو پڻ ڪم ڪيو. اسان وري سوچيو ۽ فيصلو ڪيو ته هڪ مڪمل ايموليٽر ٺاهيو.

نتيجو هڪ ڪمپيوٽر سسٽم ايموليٽر هو ڪاپي ڪيٽ.

ٻلي جي اندر گينڊا - ڪوپي ڪيٽ ايموليٽر ۾ فرم ویئر کي هلائي
ڇو Kopycat؟

لفظن تي هڪ راند آهي.

  1. ڪاپيڪٽ (انگريزي، اسم [ˈkɒpɪkæt]) - تقليد ڪندڙ، تقليد ڪندڙ
  2. ٻلي (انگريزي، اسم [ˈkæt]) - ٻلي، ٻلي - پروجيڪٽ جي تخليق ڪندڙن مان هڪ جو پسنديده جانور
  3. اکر "K" Kotlin پروگرامنگ ٻولي مان آهي

ڪاپي ڪيٽ

جڏهن ايموليٽر ٺاهي، تمام خاص مقصد مقرر ڪيا ويا:

  • جلدي نئين پرديئرز، ماڊل، پروسيسر ڪور ٺاهڻ جي صلاحيت؛
  • возможность собрать виртуальное устройство из различных модулей;
  • ڪنهن به بائنري ڊيٽا (فرم ویئر) کي ورچوئل ڊيوائس جي ياداشت ۾ لوڊ ڪرڻ جي صلاحيت؛
  • سنيپ شاٽ سان ڪم ڪرڻ جي صلاحيت (سسٽم اسٽيٽ جا سنيپ شاٽ)؛
  • بلٽ ان ڊيبگر ذريعي ايموليٽر سان لهه وچڙ ڪرڻ جي صلاحيت؛
  • ترقي لاء سٺي جديد ٻولي.

نتيجي طور، Kotlin تي عمل درآمد لاءِ چونڊيو ويو، بس آرڪيٽيڪچر (اهو تڏهن آهي جڏهن ماڊلز هڪ ٻئي سان ورچوئل ڊيٽا بس ذريعي رابطو ڪندا آهن)، JSON جيئن ڊيوائس وضاحت جي فارميٽ، ۽ ڊيبگر سان رابطي لاءِ پروٽوڪول طور GDB RSP.

ترقي ٻن سالن کان ٿورو وڌيڪ ٿي چڪي آهي ۽ فعال طور تي جاري آهي. هن وقت دوران، MIPS، x86، V850ES، ARM، ۽ پاور پي سي پروسيسر ڪور لاڳو ڪيا ويا.

پروجيڪٽ وڌي رهيو آهي ۽ اهو وقت آهي ته ان کي وسيع عوام ڏانهن پيش ڪيو وڃي. اسان منصوبي جي تفصيلي وضاحت بعد ۾ ڪنداسين، پر ھاڻي اسان کي استعمال ڪرڻ تي ڌيان ڏينداسين Kopycat.

Для самых нетерпеливых — промо-версию эмулятора можно скачать по لنڪ.

ايموليٽر ۾ رينو

ياد رهي ته ان کان اڳ SMARTRHINO-2018 ڪانفرنس ۾ ريورس انجنيئرنگ اسڪلز سيکارڻ لاءِ هڪ ٽيسٽ ڊيوائس “Rhinoceros” ٺاهي وئي هئي. جامد فرم ویئر جي تجزيي جي عمل ۾ بيان ڪيو ويو آهي اهو مضمون.

ھاڻي اچو ته ”اسپيڪرز“ کي شامل ڪرڻ جي ڪوشش ڪريون ۽ ايموليٽر ۾ فرم ویئر کي ھلايو.

اسان کي گهرجي:
1) جاوا 1.8
2) پٿون ۽ ماڊل جيپ ايموليٽر اندر پٿون استعمال ڪرڻ لاءِ. توھان ٺاھي سگھو ٿا WHL ماڊل Jep ونڊوز لاءِ هتي ڊائون لوڊ ڪريو.

ونڊوز لاءِ:
1) com0com
2) PuTTY

لينڪس لاءِ:
1) سوڪٽ

توھان استعمال ڪري سگھو ٿا Eclipse، IDA Pro يا radare2 GDB ڪلائنٽ طور.

ان کي ڪيئن ڪم ڪندو؟

ايموليٽر ۾ فرمائيندڙ کي انجام ڏيڻ لاء، اهو ضروري آهي ته "جمع" هڪ مجازي ڊوائيس، جيڪو حقيقي ڊوائيس جو هڪ اينالاگ آهي.

حقيقي ڊوائيس ("رينو") بلاڪ ڊراگرام ۾ ڏيکاريو وڃي ٿو:

ٻلي جي اندر گينڊا - ڪوپي ڪيٽ ايموليٽر ۾ فرم ویئر کي هلائي

ايموليٽر وٽ ماڊلر ڍانچي آهي ۽ حتمي ورچوئل ڊيوائس JSON فائل ۾ بيان ڪري سگهجي ٿي.

JSON 105 لائنون

{
  "top": true,

  // Plugin name should be the same as file name (or full path from library start)
  "plugin": "rhino",

  // Directory where plugin places
  "library": "user",

  // Plugin parameters (constructor parameters if jar-plugin version)
  "params": [
    { "name": "tty_dbg", "type": "String"},
    { "name": "tty_bt", "type": "String"},
    { "name": "firmware", "type": "String", "default": "NUL"}
  ],

  // Plugin outer ports
  "ports": [  ],

  // Plugin internal buses
  "buses": [
    { "name": "mem", "size": "BUS30" },
    { "name": "nand", "size": "4" },
    { "name": "gpio", "size": "BUS32" }
  ],

  // Plugin internal components
  "modules": [
    {
      "name": "u1_stm32",
      "plugin": "STM32F042",
      "library": "mcu",
      "params": {
        "firmware:String": "params.firmware"
      }
    },
    {
      "name": "usart_debug",
      "plugin": "UartSerialTerminal",
      "library": "terminals",
      "params": {
        "tty": "params.tty_dbg"
      }
    },
    {
      "name": "term_bt",
      "plugin": "UartSerialTerminal",
      "library": "terminals",
      "params": {
        "tty": "params.tty_bt"
      }
    },
    {
      "name": "bluetooth",
      "plugin": "BT",
      "library": "mcu"
    },

    { "name": "led_0",  "plugin": "LED", "library": "mcu" },
    { "name": "led_1",  "plugin": "LED", "library": "mcu" },
    { "name": "led_2",  "plugin": "LED", "library": "mcu" },
    { "name": "led_3",  "plugin": "LED", "library": "mcu" },
    { "name": "led_4",  "plugin": "LED", "library": "mcu" },
    { "name": "led_5",  "plugin": "LED", "library": "mcu" },
    { "name": "led_6",  "plugin": "LED", "library": "mcu" },
    { "name": "led_7",  "plugin": "LED", "library": "mcu" },
    { "name": "led_8",  "plugin": "LED", "library": "mcu" },
    { "name": "led_9",  "plugin": "LED", "library": "mcu" },
    { "name": "led_10", "plugin": "LED", "library": "mcu" },
    { "name": "led_11", "plugin": "LED", "library": "mcu" },
    { "name": "led_12", "plugin": "LED", "library": "mcu" },
    { "name": "led_13", "plugin": "LED", "library": "mcu" },
    { "name": "led_14", "plugin": "LED", "library": "mcu" },
    { "name": "led_15", "plugin": "LED", "library": "mcu" }
  ],

  // Plugin connection between components
  "connections": [
    [ "u1_stm32.ports.usart1_m", "usart_debug.ports.term_s"],
    [ "u1_stm32.ports.usart1_s", "usart_debug.ports.term_m"],

    [ "u1_stm32.ports.usart2_m", "bluetooth.ports.usart_m"],
    [ "u1_stm32.ports.usart2_s", "bluetooth.ports.usart_s"],

    [ "bluetooth.ports.bt_s", "term_bt.ports.term_m"],
    [ "bluetooth.ports.bt_m", "term_bt.ports.term_s"],

    [ "led_0.ports.pin",  "u1_stm32.buses.pin_output_a", "0x00"],
    [ "led_1.ports.pin",  "u1_stm32.buses.pin_output_a", "0x01"],
    [ "led_2.ports.pin",  "u1_stm32.buses.pin_output_a", "0x02"],
    [ "led_3.ports.pin",  "u1_stm32.buses.pin_output_a", "0x03"],
    [ "led_4.ports.pin",  "u1_stm32.buses.pin_output_a", "0x04"],
    [ "led_5.ports.pin",  "u1_stm32.buses.pin_output_a", "0x05"],
    [ "led_6.ports.pin",  "u1_stm32.buses.pin_output_a", "0x06"],
    [ "led_7.ports.pin",  "u1_stm32.buses.pin_output_a", "0x07"],
    [ "led_8.ports.pin",  "u1_stm32.buses.pin_output_a", "0x08"],
    [ "led_9.ports.pin",  "u1_stm32.buses.pin_output_a", "0x09"],
    [ "led_10.ports.pin", "u1_stm32.buses.pin_output_a", "0x0A"],
    [ "led_11.ports.pin", "u1_stm32.buses.pin_output_a", "0x0B"],
    [ "led_12.ports.pin", "u1_stm32.buses.pin_output_a", "0x0C"],
    [ "led_13.ports.pin", "u1_stm32.buses.pin_output_a", "0x0D"],
    [ "led_14.ports.pin", "u1_stm32.buses.pin_output_a", "0x0E"],
    [ "led_15.ports.pin", "u1_stm32.buses.pin_output_a", "0x0F"]
  ]
}

پيراگراف تي ڌيان ڏيو firmware سيڪشن params ھڪڙي فائل جو نالو آھي جنھن کي ورچوئل ڊيوائس ۾ firmware طور لوڊ ڪري سگھجي ٿو.

ورچوئل ڊيوائس ۽ ان جو مکيه آپريٽنگ سسٽم سان لاڳاپو هيٺين آراگرام ذريعي ظاھر ڪري سگھجي ٿو:

ٻلي جي اندر گينڊا - ڪوپي ڪيٽ ايموليٽر ۾ فرم ویئر کي هلائي

ايموليٽر جي موجوده ٽيسٽ مثال ۾ مکيه OS جي COM بندرگاهن سان رابطو شامل آهي (بلوٽوت ماڊل لاءِ UART ۽ UART کي ڊيب ڪريو). اهي حقيقي بندرگاهن ٿي سگهن ٿيون جن سان ڊوائيسز ڳنڍيل آهن يا مجازي COM بندرگاهن (هن لاء توهان کي صرف ضرورت آهي com0com/socat).

في الحال ٻه مکيه طريقا آهن ٻاهران ايموليٽر سان لهه وچڙ ۾:

  • GDB RSP پروٽوڪول (ان جي مطابق، اوزار جيڪي هن پروٽوڪول کي سپورٽ ڪن ٿا Eclipse / IDA / radare2)؛
  • اندروني ايموليٽر ڪمانڊ لائن (Argparse يا Python).

مجازي COM بندرگاهن

ٽرمينل ذريعي مقامي مشين تي هڪ مجازي ڊوائيس جي UART سان لهه وچڙ ڪرڻ لاء، توهان کي لاڳاپيل مجازي COM بندرگاهن جو هڪ جوڙو ٺاهڻ جي ضرورت آهي. اسان جي حالت ۾، هڪ بندرگاهه ايموليٽر طرفان استعمال ڪيو ويندو آهي، ۽ ٻيو استعمال ڪيو ويندو آهي ٽرمينل پروگرام (PuTTY يا اسڪرين):

ٻلي جي اندر گينڊا - ڪوپي ڪيٽ ايموليٽر ۾ فرم ویئر کي هلائي

com0com استعمال ڪندي

ورچوئل COM بندرگاهن com0com ڪٽ مان سيٽ اپ يوٽيلٽي استعمال ڪندي ترتيب ڏنل آهن (ڪنسول ورزن - ج: پروگرام فائلون (x86)com0comsetupс.exe، يا GUI نسخو - ج: پروگرام فائلون (x86) com0comsetupg.exe):

ٻلي جي اندر گينڊا - ڪوپي ڪيٽ ايموليٽر ۾ فرم ویئر کي هلائي

باڪس چيڪ ڪريو بفر اووررن کي فعال ڪريو سڀني ٺاهيل مجازي بندرگاهن لاءِ، ٻي صورت ۾ ايموليٽر COM بندرگاهن مان جواب جو انتظار ڪندو.

سوڪٽ استعمال ڪندي

UNIX سسٽم تي، ورچوئل COM بندرگاهن خود بخود ٺاهيا ويندا آهن ايموليٽر طرفان socat يوٽيلٽي استعمال ڪندي؛ ائين ڪرڻ لاءِ، ايموليٽر کي شروع ڪرڻ وقت صرف پورٽ جي نالي ۾ اڳياڙي بيان ڪريو. socat:.

اندروني ڪمانڊ لائن انٽرفيس (Argparse يا Python)

جيئن ته Kopycat هڪ ڪنسول ايپليڪيشن آهي، ايموليٽر ٻن ڪمانڊ لائن انٽرفيس آپشنز مهيا ڪري ٿو ان جي شين ۽ متغيرن سان رابطي لاءِ: Argparse ۽ ​​Python.

Argparse هڪ CLI آهي جيڪو Kopycat ۾ ٺهيل آهي ۽ هميشه هر ڪنهن لاءِ دستياب آهي.

هڪ متبادل CLI Python مترجم آهي. ان کي استعمال ڪرڻ لاءِ، توھان کي Jep Python ماڊيول انسٽال ڪرڻو پوندو ۽ پٿون سان ڪم ڪرڻ لاءِ ايموليٽر کي ترتيب ڏيڻو پوندو (استعمال ڪندڙ جي مکيه سسٽم تي Python مترجم نصب ڪيو ويندو).

Python ماڊل Jep انسٽال ڪرڻ

لينڪس جيپ تحت انسٽال ڪري سگھجي ٿو پائپ ذريعي:

pip install jep

ونڊوز تي Jep انسٽال ڪرڻ لاءِ، توهان کي پهريان ونڊوز SDK ۽ لاڳاپيل Microsoft Visual Studio انسٽال ڪرڻو پوندو. اسان ان کي توهان لاءِ ٿورو آسان ڪيو آهي ۽ WHL ٺاهي ٿو ونڊوز لاءِ پٿون جي موجوده ورزن لاءِ JEP، تنهنڪري ماڊل فائل مان انسٽال ڪري سگهجي ٿو:

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

Jep جي انسٽاليشن کي چيڪ ڪرڻ لاء، توهان کي ڪمان لائن تي هلائڻ جي ضرورت آهي:

python -c "import jep"

جواب ۾ ھيٺ ڏنل پيغام حاصل ڪرڻ گھرجي:

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

توهان جي سسٽم لاءِ ايموليٽر بيچ فائل ۾ (copycat.bat - ونڊوز لاء، ڪاپي ڪيٽ - لينڪس لاءِ) پيرا ميٽرن جي لسٽ ۾ DEFAULT_JVM_OPTS اضافي پيٽرولر شامل ڪريو Djava.library.path - ان ۾ لازمي طور تي نصب ٿيل Jep ماڊل ڏانھن رستو شامل آھي.

ونڊوز جو نتيجو هن طرح هجڻ گهرجي:

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

لينڪس تحت هلائڻ لاء حڪم 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 پرو سان رابطو

جانچ کي آسان ڪرڻ لاءِ، اسان استعمال ڪريون ٿا Rhino firmware کي ماخذ فائل طور IDA ۾ تجزيو لاءِ فارم ۾ ELF فائل (ميٽا معلومات اتي ذخيرو ٿيل آهي).

توھان پڻ استعمال ڪري سگھو ٿا مکيه firmware بغير ميٽا ڄاڻ.

IDA پرو ۾ Kopycat شروع ڪرڻ کان پوء، ڊيبگر مينيو ۾ شيون ڏانهن وڃو "ڊيبگر کي تبديل ڪريو..."۽ چونڊيو"ريموٽ GDB ڊيبگر". اڳيون، ڪنيڪشن قائم ڪريو: مينيو ڊيبگر - پروسيس جا اختيار...

قدر مقرر ڪريو:

  • درخواست - ڪنهن به قدر
  • هسٽري جو نالو: 127.0.0.1 (يا ريموٽ مشين جو IP پتو جتي Kopycat هلي رهيو آهي)
  • پورٽ: 23946

ٻلي جي اندر گينڊا - ڪوپي ڪيٽ ايموليٽر ۾ فرم ویئر کي هلائي

ھاڻي ڊيبگنگ بٽڻ موجود آھي (F9 ڪي):

ٻلي جي اندر گينڊا - ڪوپي ڪيٽ ايموليٽر ۾ فرم ویئر کي هلائي

ايموليٽر ۾ ڊيبگر ماڊل سان ڳنڍڻ لاءِ ان تي ڪلڪ ڪريو. IDA ڊيبگنگ موڊ ۾ وڃي ٿو، اضافي ونڊوز دستياب ٿي ويندا آهن: رجسٽر بابت معلومات، اسٽيڪ بابت.

هاڻي اسان ڊيبگر جي سڀني معياري خصوصيتن کي استعمال ڪري سگهون ٿا:

  • هدايتن جي قدم قدم تي عملدرآمد (داخل ٿيڻ и قدم اڳتي - ڪنجيون F7 ۽ F8، ترتيب سان؛
  • عملدرآمد شروع ڪرڻ ۽ روڪڻ؛
  • ڪوڊ ۽ ڊيٽا ٻنهي لاءِ بريڪ پوائنٽ ٺاهڻ (F2 ڪي).

ڊيبگر سان ڳنڍڻ جو مطلب اهو ناهي ته فرم ويئر ڪوڊ هلائڻ. موجوده عمل جي پوزيشن کي پتو هجڻ گهرجي 0x08006A74 - فنڪشن جي شروعات Reset_Handler. جيڪڏھن توھان لسٽنگ ھيٺ لٿو، توھان ڏسي سگھوٿا فنڪشن ڪال مکيه. توھان ھن لائن تي ڪسر رکي سگھو ٿا (address 0x08006ABE) ۽ آپريشن کي انجام ڏيو ڪرسر تائين هلايو (ڪي F4).

ٻلي جي اندر گينڊا - ڪوپي ڪيٽ ايموليٽر ۾ فرم ویئر کي هلائي

اڳيون، توهان فنڪشن داخل ڪرڻ لاء F7 کي دٻايو مکيه.

جيڪڏهن توهان حڪم هلائيندا آهيو عمل جاري رکو (F9 key)، پوء "مهرباني ڪري انتظار ڪريو" ونڊو هڪ واحد بٽڻ سان ظاهر ٿيندو معطل:

ٻلي جي اندر گينڊا - ڪوپي ڪيٽ ايموليٽر ۾ فرم ویئر کي هلائي

جڏهن توهان دٻايو معطل فرم ویئر ڪوڊ جي عمل کي معطل ڪيو ويو آهي ۽ ڪوڊ ۾ ساڳئي ايڊريس کان جاري رکي سگهجي ٿو جتي اهو مداخلت ڪئي وئي هئي.

جيڪڏهن توهان ڪوڊ تي عمل ڪرڻ جاري رکو ٿا، توهان هيٺيون لائينون ڏسندا ٽرمينلز ۾ جيڪي ورچوئل COM بندرگاهن سان ڳنڍيل آهن:

ٻلي جي اندر گينڊا - ڪوپي ڪيٽ ايموليٽر ۾ فرم ویئر کي هلائي

ٻلي جي اندر گينڊا - ڪوپي ڪيٽ ايموليٽر ۾ فرم ویئر کي هلائي

Наличие строки «state bypass» говорит о том, что виртуальный Bluetooth-модуль перешёл в режим приёма данных от COM-порта пользователя.

ھاڻي بلوٽوٿ ٽرمينل ۾ (تصوير ۾ COM29) توھان Rhino پروٽوڪول جي مطابق حڪم داخل ڪري سگھو ٿا. مثال طور، "MEOW" حڪم "mur-mur" کي بلوٽوت ٽرمينل ڏانهن واپس آڻيندو:

ٻلي جي اندر گينڊا - ڪوپي ڪيٽ ايموليٽر ۾ فرم ویئر کي هلائي

مون کي مڪمل طور تي emulate نه

جڏهن هڪ ايموليٽر ٺاهي، توهان هڪ خاص ڊوائيس جي تفصيل / ايموليشن جي سطح کي منتخب ڪري سگهو ٿا. مثال طور، Bluetooth ماڊل مختلف طريقن سان emulated ڪري سگهجي ٿو:

  • ڊوائيس مڪمل طور تي حڪمن جي مڪمل سيٽ سان ٺهيل آهي؛
  • اي ٽي حڪمن کي نقل ڪيو ويو آهي، ۽ ڊيٽا جو وهڪرو مکيه سسٽم جي COM بندرگاهن مان حاصل ڪيو ويو آهي؛
  • مجازي ڊوائيس حقيقي ڊوائيس ڏانهن مڪمل ڊيٽا ريڊائريشن مهيا ڪري ٿي؛
  • هڪ سادي اسٽب وانگر جيڪو هميشه "ٺيڪ" موٽائي ٿو.

ايموليٽر جو موجوده نسخو ٻئي طريقي سان استعمال ڪري ٿو - مجازي بلوٽوت ماڊل ترتيب ڏئي ٿو، جنهن کان پوء اهو "پراڪسينگ" ڊيٽا جي موڊ کي تبديل ڪري ٿو مکيه سسٽم جي COM بندرگاهه کان ايموليٽر جي UART بندرگاهه ڏانهن.

ٻلي جي اندر گينڊا - ڪوپي ڪيٽ ايموليٽر ۾ فرم ویئر کي هلائي

اچو ته ڪوڊ جي سادي اوزار جي امڪان تي غور ڪريون ته صورت ۾ پردي جي ڪجهه حصي تي عمل نه ڪيو ويو آهي. مثال طور، جيڪڏهن ڊي ايم اي ڏانهن ڊيٽا جي منتقلي کي ڪنٽرول ڪرڻ جو ذميوار ٽائمر نه ٺاهيو ويو آهي (چڪ فنڪشن ۾ ڪيو ويندو آهي ws2812b_waitتي واقع 0x08006840)، پوء firmware هميشه پرچم کي ريٽ ڪرڻ لاء انتظار ڪندو مصروفتي واقع 0x200004C4جيڪو DMA ڊيٽا لائن جي قبضي کي ڏيکاري ٿو:

ٻلي جي اندر گينڊا - ڪوپي ڪيٽ ايموليٽر ۾ فرم ویئر کي هلائي

اسان هن صورتحال جي چوڌاري حاصل ڪري سگهون ٿا دستي طور تي پرچم کي ري سيٽ ڪندي مصروف ان کي انسٽال ڪرڻ کان پوء فوري طور تي. IDA پرو ۾، توهان هڪ Python فنڪشن ٺاهي سگهو ٿا ۽ ان کي بريڪ پوائنٽ ۾ ڪال ڪري سگهو ٿا، ۽ بريڪ پوائنٽ پاڻ کي ڪوڊ ۾ وجهي سگهو ٿا قيمت 1 کي پرچم ڏانهن لکڻ کان پوء مصروف.

بريڪ پوائنٽ سنڀاليندڙ

Сначала создадим Python-функцию в IDA. Меню فائل - اسڪرپٽ حڪم ...

Добавляем новый сниппет в списке слева, даём ему имя (например, بي بي ٽي),
ساڄي پاسي واري ٽيڪسٽ فيلڊ ۾، فنڪشن ڪوڊ داخل ڪريو:

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

ٻلي جي اندر گينڊا - ڪوپي ڪيٽ ايموليٽر ۾ فرم ویئر کي هلائي

ان کان پوء اسان کي دٻايو هل ۽ اسڪرپٽ ونڊو بند ڪريو.

هاڻي اچو ته ڪوڊ تي وڃو 0x0800688A، هڪ بريڪ پوائنٽ مقرر ڪريو (F2 ڪيئي)، ان کي تبديل ڪريو (ڪانٽيڪٽ مينيو بريڪ پوائنٽ کي تبديل ڪريو...)، اسڪرپٽ جو قسم مقرر ڪرڻ نه وساريو Python:

ٻلي جي اندر گينڊا - ڪوپي ڪيٽ ايموليٽر ۾ فرم ویئر کي هلائي
ٻلي جي اندر گينڊا - ڪوپي ڪيٽ ايموليٽر ۾ فرم ویئر کي هلائي

جيڪڏهن موجوده پرچم جي قيمت مصروف برابر 1، پوء توهان کي فنڪشن کي عمل ڪرڻ گهرجي skip_dma اسڪرپٽ لائن ۾:

ٻلي جي اندر گينڊا - ڪوپي ڪيٽ ايموليٽر ۾ فرم ویئر کي هلائي

جيڪڏهن توهان عمل لاءِ فرمائيندڙ هلائيندا آهيو، توهان IDA ونڊو ۾ بريڪ پوائنٽ هينڊلر ڪوڊ جي ٽرگرنگ ڏسي سگهو ٿا پيداوار по строке Skipping wait ws2812.... هاڻي فرمائيندڙ پرچم کي ريٽ ڪرڻ جو انتظار نه ڪندو مصروف.

ايموليٽر سان رابطو

ايموليشن جي لاءِ تخليق لذت ۽ خوشي جو سبب بڻجڻ ممڪن ناهي. اهو وڌيڪ دلچسپ آهي جيڪڏهن ايموليٽر محقق کي ميموري ۾ ڊيٽا ڏسڻ يا موضوعن جي وچ ۾ رابطي کي قائم ڪرڻ ۾ مدد ڪري ٿي.

اسان توهان کي ڏيکارينداسين ته ڪيئن متحرڪ طور تي RTOS ڪمن جي وچ ۾ رابطي کي قائم ڪرڻ. توهان کي پهريان ڪوڊ جي عمل کي روڪڻ گهرجي جيڪڏهن اهو هلندڙ آهي. جيڪڏھن توھان فنڪشن ڏانھن وڃو bluetooth_task_entry "ايل اي ڊي" ڪمانڊ جي پروسيسنگ برانچ ڏانهن (ائڊريس 0x080057B8)، پوء توهان ڏسي سگهو ٿا جيڪو پهريون ٺاهيو ويو آهي ۽ پوء سسٽم قطار ڏانهن موڪليو ويو ledControlQueueHandle ڪجهه پيغام.

ٻلي جي اندر گينڊا - ڪوپي ڪيٽ ايموليٽر ۾ فرم ویئر کي هلائي

متغير تائين رسائي حاصل ڪرڻ لاءِ توهان کي بريڪ پوائنٽ مقرر ڪرڻ گهرجي ledControlQueueHandleتي واقع 0x20000624 ۽ ڪوڊ تي عمل ڪرڻ جاري رکو:

ٻلي جي اندر گينڊا - ڪوپي ڪيٽ ايموليٽر ۾ فرم ویئر کي هلائي

نتيجي طور، اسٽاپ پهرين پتي تي ٿيندي 0x080057CA перед вызовом функции osMailAlloc، پوءِ ايڊريس تي 0x08005806 перед вызовом функции osMailPut، پوءِ ٿوري دير کان پوءِ - ايڊريس تي 0x08005BD4 (فنڪشن کي سڏڻ کان اڳ osMailGet), который принадлежит функции leds_task_entry (LED-task)، اهو آهي، ڪمن کي تبديل ڪيو ويو، ۽ هاڻي LED-ٽاسڪ ڪنٽرول حاصل ڪيو.

ٻلي جي اندر گينڊا - ڪوپي ڪيٽ ايموليٽر ۾ فرم ویئر کي هلائي

هن سادي طريقي سان توهان قائم ڪري سگهو ٿا ته ڪيئن RTOS ڪم هڪ ٻئي سان لهه وچڙ ۾.

يقينن، حقيقت ۾، ڪمن جي رابطي کان وڌيڪ پيچيده ٿي سگهي ٿي، پر هڪ ايموليٽر استعمال ڪندي، هن رابطي کي ٽريڪ ڪرڻ گهٽ محنت وارو ٿيندو.

تُوت توهان ايموليٽر لانچ ڪرڻ ۽ IDA پرو سان لهه وچڙ جي مختصر وڊيو ڏسي سگهو ٿا.

Radare2 سان لانچ ڪريو

توھان نظر انداز نٿا ڪري سگھو اھڙي آفاقي اوزار جيئن Radare2.

Для подключения к эмулятору с использованием r2 команда будет выглядеть так:

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

لانچ ھاڻي دستياب آھي (dc) ۽ عمل کي روڪيو (Ctrl+C).

بدقسمتي سان، هن وقت، r2 مسئلا آهن جڏهن هارڊويئر جي ڊي بي سرور ۽ ياداشت جي ترتيب سان ڪم ڪري رهيا آهن؛ انهي جي ڪري، بريڪ پوائنٽ ۽ قدم ڪم نه ڪندا آهن (حڪم ds). اسان کي اميد آهي ته اهو جلد طئي ڪيو ويندو.

Eclipse سان هلڻ

ايموليٽر استعمال ڪرڻ لاءِ اختيارن مان ھڪڙو آھي ڊيبگ ڪرڻ لاءِ ڊيوائس جو فرم ویئر ٺاھيو پيو وڃي. وضاحت لاء، اسان پڻ استعمال ڪنداسين Rhino firmware. توھان ڊائون لوڊ ڪري سگھو ٿا firmware ذريعن هتي کان.

اسان سيٽ مان Eclipse کي IDE طور استعمال ڪنداسين STM32 لاءِ سسٽم ورڪ بينچ.

ايموليٽر لاءِ سڌو سنئون Eclipse ۾ مرتب ٿيل فرم ویئر لوڊ ڪرڻ لاءِ، توهان کي پيراميٽر شامل ڪرڻو پوندو firmware=null ايموليٽر لانچ حڪم ڏانهن:

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

ڊيبگ جي ترتيب کي ترتيب ڏيڻ

Eclipse ۾، مينيو چونڊيو هلايو - ڊيبگ ڪنفيگريشنز... ونڊو ۾ جيڪو کلي ٿو، سيڪشن ۾ GDB هارڊويئر ڊيبگنگ توهان کي نئين ترتيب شامل ڪرڻ جي ضرورت آهي، پوء "مين" ٽئب تي موجوده پروجيڪٽ ۽ ڊيبگنگ لاء ايپليڪيشن بيان ڪريو:

ٻلي جي اندر گينڊا - ڪوپي ڪيٽ ايموليٽر ۾ فرم ویئر کي هلائي

"ڊيبگر" ٽئب تي توهان کي GDB حڪم بيان ڪرڻ جي ضرورت آهي:
${openstm32_compiler_path}arm-none-eabi-gdb

۽ GDB سرور (ميزبان ۽ بندرگاھ) سان ڳنڍڻ لاءِ پڻ پيٽرول داخل ڪريو:

ٻلي جي اندر گينڊا - ڪوپي ڪيٽ ايموليٽر ۾ فرم ویئر کي هلائي

"Startup" ٽئب تي، توھان کي ھيٺين پيٽرولن جي وضاحت ڪرڻ گھرجي:

  • چيڪ باڪس کي فعال ڪريو تصوير لوڊ ڪريو (чтобы выполнялась загрузка в эмулятор собранного образа прошивки);
  • چيڪ باڪس کي فعال ڪريو لوڊ علامتون;
  • لانچ حڪم شامل ڪريو: set $pc = *0x08000004 (پي سي رجسٽر کي ميموري مان ويل ويل ايڊريس تي مقرر ڪريو 0x08000004 - پتو اتي ذخيرو ٿيل آهي ري سيٽ هينڊلر).

ڌيان ڏيڻ، جيڪڏھن توھان نٿا چاھيو ڊائون لوڊ ڪريو فرم ویئر فائل Eclipse مان، پوءِ اختيارن تصوير لوڊ ڪريو и Run commands اشارو ڪرڻ جي ضرورت ناهي.

ٻلي جي اندر گينڊا - ڪوپي ڪيٽ ايموليٽر ۾ فرم ویئر کي هلائي

ڊيبگ کي ڪلڪ ڪرڻ کان پوء، توهان ڊيبگر موڊ ۾ ڪم ڪري سگهو ٿا:

  • قدم قدم ڪوڊ جي عملدرآمد
    ٻلي جي اندر گينڊا - ڪوپي ڪيٽ ايموليٽر ۾ فرم ویئر کي هلائي
  • وقفي پوائنٽن سان رابطو
    ٻلي جي اندر گينڊا - ڪوپي ڪيٽ ايموليٽر ۾ فرم ویئر کي هلائي

ويچاري. Eclipse آهي، ها... ڪجهه نرالا... ۽ توهان کي انهن سان گڏ رهڻو پوندو. مثال طور، جيڪڏهن ڊيبگر شروع ڪرڻ وقت پيغام "0x0" لاءِ ڪو به ذريعو دستياب ناهي، پوءِ اسٽيپ ڪمانڊ (F5) تي عمل ڪريو.

ٻلي جي اندر گينڊا - ڪوپي ڪيٽ ايموليٽر ۾ فرم ویئر کي هلائي

سوچيم ته هڪ ٿڪل جي

ملڪي ڪوڊ کي نقل ڪرڻ هڪ تمام دلچسپ شيء آهي. اهو ممڪن آهي ته هڪ ڊوائيس ڊولپر لاءِ حقيقي ڊوائيس کان سواءِ فرمائيندڙ کي ڊيبگ ڪرڻ لاءِ. هڪ محقق لاء، اهو هڪ موقعو آهي متحرڪ ڪوڊ تجزيو ڪرڻ جو، جيڪو هميشه ممڪن ناهي جيتوڻيڪ هڪ ڊوائيس سان.

اسان ماهرن کي ھڪڙو اوزار مهيا ڪرڻ چاھيون ٿا جيڪو آسان، اعتدال پسند سادو آھي ۽ سيٽ ڪرڻ ۽ ھلائڻ ۾ گھڻي ڪوشش ۽ وقت نه ٿو وٺي.

هارڊويئر ايموليٽر استعمال ڪندي پنهنجي تجربي بابت تبصرن ۾ لکو. اسان توهان کي بحث ڪرڻ جي دعوت ڏين ٿا ۽ سوالن جا جواب ڏيڻ لاء خوش ٿي ويندا.

صرف رجسٽرڊ استعمال ڪندڙ سروي ۾ حصو وٺي سگهن ٿا. سائن ان ڪريو، توهان جي مهرباني.

توهان ڇا لاءِ ايموليٽر استعمال ڪري رهيا آهيو؟

  • مان ترقي ڪريان ٿو (ڊيبگ) فرمائيندڙ

  • مان تحقيق ڪري رهيو آهيان firmware

  • مان رانديون شروع ڪريان ٿو (ڊندي، سيگا، پي ايس پي)

  • ٻيو ڪجهه (تبصرن ۾ لکو)

7 صارفين ووٽ ڪيو. 2 استعمال ڪندڙن کي روڪيو ويو.

توهان ڪهڙو سافٽ ويئر استعمال ڪندا آهيو اصلي ڪوڊ کي نقل ڪرڻ لاءِ؟

  • QEMU

  • يونيڪورن انجڻ

  • Proteus

  • ٻيو ڪجهه (تبصرن ۾ لکو)

6 صارفين ووٽ ڪيو. 2 استعمال ڪندڙن کي روڪيو ويو.

توهان استعمال ڪري رهيا آهيو ايموليٽر ۾ ڇا بهتر ڪرڻ چاهيندا؟

  • مان رفتار چاهيان ٿو

  • مون کي سيٽ اپ / لانچ جي آساني چاهيون ٿا

  • مان ايموليٽر سان رابطي لاءِ وڌيڪ آپشنز چاهيان ٿو (API، ٿلهو)

  • مان هر شي سان خوش آهيان

  • ٻيو ڪجهه (تبصرن ۾ لکو)

8 صارفين ووٽ ڏنو. 1 استعمال ڪندڙ روڪيو.

جو ذريعو: www.habr.com

تبصرو شامل ڪريو