একটি বিড়ালের ভিতরে গন্ডার - কপিক্যাট এমুলেটরে ফার্মওয়্যার চালান

একটি বিড়ালের ভিতরে গন্ডার - কপিক্যাট এমুলেটরে ফার্মওয়্যার চালান

বৈঠকের অংশ হিসেবে 0x0A DC7831 ডিইএফ কন নিঝনি নভগোরড 16 февраля мы представили доклад о базовых принципах эмуляции бинарного кода и собственной разработке — эмуляторе аппаратных платформ Kopycat.

এই নিবন্ধে আমরা বর্ণনা করব কিভাবে এমুলেটরে ডিভাইস ফার্মওয়্যার চালানো যায়, ডিবাগারের সাথে মিথস্ক্রিয়া প্রদর্শন করা যায় এবং ফার্মওয়্যারের একটি ছোট গতিশীল বিশ্লেষণ করা যায়।

প্রাগঐতিহাসিক

বহুদিন আগে বহু দূরের এক গ্যালাক্সিতে

Пару лет назад в нашей лаборатории возникла необходимость исследовать прошивку устройства. Прошивка была сжата, распаковывалась bootloader’ом. Делал он это весьма замороченным способом, несколько раз перекладывая данные в памяти. Да и сама прошивка потом активно взаимодействовала с периферией. И всё это на ядре MIPS.

উদ্দেশ্যমূলক কারণে, উপলব্ধ এমুলেটরগুলি আমাদের জন্য উপযুক্ত ছিল না, তবে আমরা এখনও কোডটি চালাতে চেয়েছিলাম। তারপরে আমরা আমাদের নিজস্ব এমুলেটর তৈরি করার সিদ্ধান্ত নিয়েছি, যা সর্বনিম্ন করবে এবং আমাদের মূল ফার্মওয়্যারটি আনপ্যাক করার অনুমতি দেবে। আমরা এটি চেষ্টা করেছি এবং এটি কাজ করেছে। আমরা ভেবেছিলাম, যদি আমরা মূল ফার্মওয়্যার সঞ্চালনের জন্য পেরিফেরাল যোগ করি। এটি খুব বেশি আঘাত করেনি - এবং এটিও কার্যকর হয়েছে। আমরা আবার চিন্তা করেছি এবং একটি পূর্ণাঙ্গ এমুলেটর তৈরি করার সিদ্ধান্ত নিয়েছি।

ফলাফল একটি কম্পিউটার সিস্টেম এমুলেটর ছিল Kopycat.

একটি বিড়ালের ভিতরে গন্ডার - কপিক্যাট এমুলেটরে ফার্মওয়্যার চালান
কেন কপিক্যাট?

শব্দ নিয়ে নাটক আছে।

  1. copycat (ইংরেজি, বিশেষ্য [ˈkɒpɪkæt]) - অনুকরণকারী, অনুকরণকারী
  2. বিড়াল (ইংরেজি, বিশেষ্য [ˈkæt]) - বিড়াল, বিড়াল - প্রকল্পের নির্মাতাদের একজনের প্রিয় প্রাণী
  3. "K" অক্ষরটি কোটলিন প্রোগ্রামিং ভাষা থেকে এসেছে

Kopycat

При создании эмулятора ставились совершенно определённые цели:

  • দ্রুত নতুন পেরিফেরাল, মডিউল, প্রসেসর কোর তৈরি করার ক্ষমতা;
  • বিভিন্ন মডিউল থেকে একটি ভার্চুয়াল ডিভাইস একত্রিত করার ক্ষমতা;
  • ভার্চুয়াল ডিভাইসের মেমরিতে যেকোনো বাইনারি ডেটা (ফার্মওয়্যার) লোড করার ক্ষমতা;
  • স্ন্যাপশটগুলির সাথে কাজ করার ক্ষমতা (সিস্টেম স্টেটের স্ন্যাপশট);
  • বিল্ট-ইন ডিবাগারের মাধ্যমে এমুলেটরের সাথে যোগাযোগ করার ক্ষমতা;
  • উন্নয়নের জন্য সুন্দর আধুনিক ভাষা।

ফলস্বরূপ, কোটলিনকে বাস্তবায়নের জন্য বেছে নেওয়া হয়েছিল, বাস আর্কিটেকচার (এটি হল যখন মডিউলগুলি ভার্চুয়াল ডেটা বাসের মাধ্যমে একে অপরের সাথে যোগাযোগ করে), ডিভাইসের বর্ণনার বিন্যাস হিসাবে JSON এবং ডিবাগারের সাথে মিথস্ক্রিয়া করার প্রোটোকল হিসাবে GDB RSP।

উন্নয়ন দুই বছরেরও বেশি সময় ধরে চলছে এবং সক্রিয়ভাবে চলছে। এই সময়ের মধ্যে, MIPS, x86, V850ES, ARM, এবং PowerPC প্রসেসর কোরগুলি বাস্তবায়িত হয়েছিল।

Проект растет, и пришло время представить его широкой общественности. Подробное описание проекта сделаем позже, а сейчас сосредоточимся на использовании Kopycat.

সবচেয়ে অধৈর্যের জন্য, এমুলেটরের একটি প্রচার সংস্করণ থেকে ডাউনলোড করা যেতে পারে লিংক.

এমুলেটরে রাইনো

আমাদের স্মরণ করা যাক যে এর আগে SMARTRHINO-2018 সম্মেলনে, বিপরীত প্রকৌশল দক্ষতা শেখানোর জন্য একটি পরীক্ষামূলক ডিভাইস "গণ্ডার" তৈরি করা হয়েছিল। স্ট্যাটিক ফার্মওয়্যার বিশ্লেষণের প্রক্রিয়াটি বর্ণনা করা হয়েছিল এই নিবন্ধটি.

Теперь же попробуем добавить «динамики» и запустим прошивку в эмуляторе.

আমরা প্রয়োজন হবে:
1) জাভা 1.8
2) Python и модуль জেপ এমুলেটরের ভিতরে পাইথন ব্যবহার করতে। আপনি উইন্ডোজের জন্য WHL মডিউল Jep তৈরি করতে পারেন এখানে ডাউনলোড করুন.

উইন্ডোজ জন্য:
1) com0com
2) পুটিং

লিনাক্সের জন্য:
1) সোকাট

আপনি একটি GDB ক্লায়েন্ট হিসাবে Eclipse, IDA Pro বা radare2 ব্যবহার করতে পারেন।

এটা কিভাবে কাজ করে?

এমুলেটরে ফার্মওয়্যার সম্পাদন করার জন্য, একটি ভার্চুয়াল ডিভাইস "একত্রিত করা" প্রয়োজন, যা একটি বাস্তব ডিভাইসের একটি অ্যানালগ।

আসল ডিভাইস ("গন্ডার") ব্লক ডায়াগ্রামে দেখানো যেতে পারে:

একটি বিড়ালের ভিতরে গন্ডার - কপিক্যাট এমুলেটরে ফার্মওয়্যার চালান

এমুলেটরটির একটি মডুলার কাঠামো রয়েছে এবং চূড়ান্ত ভার্চুয়াল ডিভাইসটি একটি 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"]
  ]
}

পরামিতি মনোযোগ দিন ফার্মওয়্যার অধ্যায় প্যারাম — это имя файла, который можно загружать в виртуальное устройство в качестве прошивки.

ভার্চুয়াল ডিভাইস এবং প্রধান অপারেটিং সিস্টেমের সাথে এর মিথস্ক্রিয়া নিম্নলিখিত চিত্র দ্বারা প্রতিনিধিত্ব করা যেতে পারে:

একটি বিড়ালের ভিতরে গন্ডার - কপিক্যাট এমুলেটরে ফার্মওয়্যার চালান

Текущий тестовый экземпляр эмулятора подразумевает взаимодействие с COM-портами основной ОС (отладочный UART и UART для Bluetooth-модуля). Это могут быть реальные порты, к которым подключены устройства или же виртуальные COM-порты (для этого как раз нужен com0com/socat).

Для взаимодействия с эмулятором извне на данный момент существует два основных способа:

  • GDB RSP প্রোটোকল (অনুসারে, এই প্রোটোকলকে সমর্থন করে এমন সরঞ্জামগুলি হল Eclipse/IDA/radare2);
  • অভ্যন্তরীণ এমুলেটর কমান্ড লাইন (আর্গপার্স বা পাইথন)।

ভার্চুয়াল COM পোর্ট

একটি টার্মিনালের মাধ্যমে স্থানীয় মেশিনে একটি ভার্চুয়াল ডিভাইসের UART-এর সাথে ইন্টারঅ্যাক্ট করার জন্য, আপনাকে একটি জোড়া যুক্ত ভার্চুয়াল COM পোর্ট তৈরি করতে হবে। আমাদের ক্ষেত্রে, একটি পোর্ট এমুলেটর দ্বারা এবং দ্বিতীয়টি একটি টার্মিনাল প্রোগ্রাম (PuTTY বা স্ক্রীন) দ্বারা ব্যবহৃত হয়:

একটি বিড়ালের ভিতরে গন্ডার - কপিক্যাট এমুলেটরে ফার্মওয়্যার চালান

com0com ব্যবহার করে

ভার্চুয়াল COM পোর্টগুলি com0com কিট থেকে সেটআপ ইউটিলিটি ব্যবহার করে কনফিগার করা হয়েছে (কনসোল সংস্করণ - C:প্রোগ্রাম ফাইল (x86)com0comsetupс.exe, বা GUI সংস্করণ - C: প্রোগ্রাম ফাইল (x86)com0comsetupg.exe):

একটি বিড়ালের ভিতরে গন্ডার - কপিক্যাট এমুলেটরে ফার্মওয়্যার চালান

বক্স চেক করুন বাফার ওভাররান সক্ষম করুন সমস্ত তৈরি ভার্চুয়াল পোর্টের জন্য, অন্যথায় এমুলেটরটি COM পোর্ট থেকে একটি প্রতিক্রিয়ার জন্য অপেক্ষা করবে।

Использование socat

ইউনিক্স সিস্টেমে, ভার্চুয়াল COM পোর্টগুলি সোক্যাট ইউটিলিটি ব্যবহার করে এমুলেটর দ্বারা স্বয়ংক্রিয়ভাবে তৈরি করা হয়; এটি করার জন্য, এমুলেটর শুরু করার সময় কেবল পোর্টের নামের মধ্যে উপসর্গটি নির্দিষ্ট করুন socat:.

অভ্যন্তরীণ কমান্ড লাইন ইন্টারফেস (আর্গপার্স বা পাইথন)

যেহেতু কপিক্যাট একটি কনসোল অ্যাপ্লিকেশন, তাই এমুলেটর তার বস্তু এবং ভেরিয়েবলের সাথে ইন্টারঅ্যাক্ট করার জন্য দুটি কমান্ড লাইন ইন্টারফেস বিকল্প সরবরাহ করে: Argparse এবং Python।

Argparse হল কপিক্যাটে তৈরি একটি CLI এবং সর্বদা সবার জন্য উপলব্ধ।

একটি বিকল্প CLI হল পাইথন ইন্টারপ্রেটার। এটি ব্যবহার করার জন্য, আপনাকে জেপ পাইথন মডিউলটি ইনস্টল করতে হবে এবং পাইথনের সাথে কাজ করার জন্য এমুলেটরটি কনফিগার করতে হবে (ব্যবহারকারীর প্রধান সিস্টেমে ইনস্টল করা পাইথন ইন্টারপ্রেটার ব্যবহার করা হবে)।

পাইথন মডিউল জেপ ইনস্টল করা হচ্ছে

Под Linux Jep может быть установлен через pip:

pip install jep

Windows এ Jep ইনস্টল করতে, আপনাকে প্রথমে Windows SDK এবং সংশ্লিষ্ট Microsoft Visual Studio ইনস্টল করতে হবে। আমরা এটি আপনার জন্য একটু সহজ করে দিয়েছি এবং WHL-сборки উইন্ডোজের জন্য পাইথনের বর্তমান সংস্করণগুলির জন্য JEP, তাই মডিউলটি ফাইল থেকে ইনস্টল করা যেতে পারে:

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

জেপের ইনস্টলেশন পরীক্ষা করতে, আপনাকে কমান্ড লাইনে চালাতে হবে:

python -c "import jep"

প্রতিক্রিয়া হিসাবে নিম্নলিখিত বার্তাটি পাওয়া উচিত:

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

В командном файле эмулятора для вашей системы (copycat.bat — для Windows, kopycat — для Linux) к списку параметров 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 Pro এর সাথে মিথস্ক্রিয়া

В качестве исходного файла для анализа в IDA для упрощения тестирования используем прошивку «Носорога» в виде ELF ফাইল (там сохранена метаинформация).

আপনি মেটা তথ্য ছাড়াই প্রধান ফার্মওয়্যার ব্যবহার করতে পারেন।

আইডিএ প্রোতে কপিক্যাট চালু করার পরে, ডিবাগার মেনুতে আইটেমটিতে যান “Switch debugger…"এবং চয়ন করুন"দূরবর্তী GDB ডিবাগার" পরবর্তী, সংযোগ সেট আপ করুন: মেনু ডিবাগার - প্রক্রিয়া বিকল্পগুলি...

মান সেট করুন:

  • আবেদন - যেকোনো মান
  • হোস্টনাম: 127.0.0.1 (অথবা দূরবর্তী মেশিনের আইপি ঠিকানা যেখানে কপিক্যাট চলছে)
  • পোর্ট: 23946

একটি বিড়ালের ভিতরে গন্ডার - কপিক্যাট এমুলেটরে ফার্মওয়্যার চালান

এখন ডিবাগিং বোতামটি উপলব্ধ হয়ে যায় (F9 কী):

একটি বিড়ালের ভিতরে গন্ডার - কপিক্যাট এমুলেটরে ফার্মওয়্যার চালান

এমুলেটরে ডিবাগার মডিউলের সাথে সংযোগ করতে এটিতে ক্লিক করুন। IDA ডিবাগিং মোডে যায়, অতিরিক্ত উইন্ডো পাওয়া যায়: রেজিস্টার সম্পর্কে তথ্য, স্ট্যাক সম্পর্কে।

এখন আমরা ডিবাগারের সমস্ত স্ট্যান্ডার্ড বৈশিষ্ট্য ব্যবহার করতে পারি:

  • ধাপে ধাপে নির্দেশাবলী সম্পাদন (পদার্পণ করা и ধাপ উপরে — কী F7 এবং F8, যথাক্রমে);
  • সঞ্চালন শুরু এবং বিরতি;
  • কোড এবং ডেটা উভয়ের জন্য ব্রেকপয়েন্ট তৈরি করা (F2 কী)।

ডিবাগারের সাথে সংযোগ করা মানে ফার্মওয়্যার কোড চালানো নয়। বর্তমান সম্পাদন অবস্থান ঠিকানা হতে হবে 0x08006A74 - ফাংশন শুরু রিসেট_হ্যান্ডলার. Если прокрутить листинг ниже, то можно увидеть вызов функции প্রধান. আপনি এই লাইনে কার্সার রাখতে পারেন (ঠিকানা 0x08006ABE) и выполнить операцию কার্সার পর্যন্ত চালান (клавиша F4).

একটি বিড়ালের ভিতরে গন্ডার - কপিক্যাট এমুলেটরে ফার্মওয়্যার চালান

Далее можно нажать F7, чтобы зайти в функцию প্রধান.

আপনি যদি কমান্ড চালান প্রক্রিয়া চালিয়ে যান (F9 কী), তারপর "দয়া করে অপেক্ষা করুন" উইন্ডোটি একটি একক বোতাম সহ প্রদর্শিত হবে ঝুলান:

একটি বিড়ালের ভিতরে গন্ডার - কপিক্যাট এমুলেটরে ফার্মওয়্যার চালান

যখন আপনি চাপুন ঝুলান ফার্মওয়্যার কোড কার্যকর করা স্থগিত করা হয়েছে এবং কোডে যে ঠিকানায় এটি বাধাপ্রাপ্ত হয়েছিল সেই ঠিকানা থেকে চালিয়ে যাওয়া যেতে পারে।

আপনি যদি কোডটি কার্যকর করা চালিয়ে যান, আপনি ভার্চুয়াল COM পোর্টগুলির সাথে সংযুক্ত টার্মিনালগুলিতে নিম্নলিখিত লাইনগুলি দেখতে পাবেন:

একটি বিড়ালের ভিতরে গন্ডার - কপিক্যাট এমুলেটরে ফার্মওয়্যার চালান

একটি বিড়ালের ভিতরে গন্ডার - কপিক্যাট এমুলেটরে ফার্মওয়্যার চালান

"স্টেট বাইপাস" লাইনের উপস্থিতি নির্দেশ করে যে ভার্চুয়াল ব্লুটুথ মডিউল ব্যবহারকারীর COM পোর্ট থেকে ডেটা গ্রহণের মোডে স্যুইচ করেছে।

এখন ব্লুটুথ টার্মিনালে (ছবিতে COM29) আপনি রাইনো প্রোটোকল অনুযায়ী কমান্ড লিখতে পারেন। উদাহরণস্বরূপ, "MEOW" কমান্ড স্ট্রিং "mur-mur" ব্লুটুথ টার্মিনালে ফিরিয়ে দেবে:

একটি বিড়ালের ভিতরে গন্ডার - কপিক্যাট এমুলেটরে ফার্মওয়্যার চালান

Эмулируй меня не полностью

একটি এমুলেটর তৈরি করার সময়, আপনি একটি নির্দিষ্ট ডিভাইসের বিশদ/ইমুলেশনের স্তর চয়ন করতে পারেন। উদাহরণস্বরূপ, ব্লুটুথ মডিউলটি বিভিন্ন উপায়ে অনুকরণ করা যেতে পারে:

  • эмулируется полностью устройство с полным набором команд;
  • эмулируются AT-команды, а поток данных принимается с COM-порта основной системы;
  • ভার্চুয়াল ডিভাইসটি প্রকৃত ডিভাইসে সম্পূর্ণ ডেটা পুনঃনির্দেশ প্রদান করে;
  • একটি সাধারণ স্টাব হিসাবে যা সর্বদা "ঠিক আছে" ফেরত দেয়।

এমুলেটরের বর্তমান সংস্করণটি দ্বিতীয় পদ্ধতি ব্যবহার করে - ভার্চুয়াল ব্লুটুথ মডিউল কনফিগারেশন সম্পাদন করে, তারপরে এটি প্রধান সিস্টেমের COM পোর্ট থেকে এমুলেটরের UART পোর্টে ডেটা "প্রক্সিিং" মোডে স্যুইচ করে।

একটি বিড়ালের ভিতরে গন্ডার - কপিক্যাট এমুলেটরে ফার্মওয়্যার চালান

Рассмотрим возможность простой инструментации кода в случае, если не реализована какая-то часть периферии. Например, если не создан таймер, отвечающий за контроль передачи данных в DMA (проверка выполняется в функции ws2812b_অপেক্ষা করুনঅবস্থিত 0x08006840), তারপর ফার্মওয়্যার সর্বদা পতাকা পুনরায় সেট করার জন্য অপেক্ষা করবে ব্যস্তঅবস্থিত 0x200004C4যা DMA ডেটা লাইনের দখল দেখায়:

একটি বিড়ালের ভিতরে গন্ডার - কপিক্যাট এমুলেটরে ফার্মওয়্যার চালান

পতাকাটি ম্যানুয়ালি রিসেট করে আমরা এই পরিস্থিতির কাছাকাছি যেতে পারি ব্যস্ত এটি ইনস্টল করার পরপরই। IDA Pro-তে, আপনি একটি পাইথন ফাংশন তৈরি করতে পারেন এবং এটিকে একটি ব্রেকপয়েন্টে কল করতে পারেন এবং ফ্ল্যাগে মান 1 লেখার পরে কোডে ব্রেকপয়েন্টটি নিজেই রাখতে পারেন। ব্যস্ত.

ব্রেকপয়েন্ট হ্যান্ডলার

প্রথমে আইডিএ-তে একটি পাইথন ফাংশন তৈরি করা যাক। তালিকা ফাইল - স্ক্রিপ্ট কমান্ড...

Добавляем новый сниппет в списке слева, даём ему имя (например, BPT),
ডানদিকে পাঠ্য ক্ষেত্রে, ফাংশন কোড লিখুন:

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

একটি বিড়ালের ভিতরে গন্ডার - কপিক্যাট এমুলেটরে ফার্মওয়্যার চালান

এর পরে আমরা টিপুন চালান и закрываем окно скриптов.

এখন কোড এ যাওয়া যাক 0x0800688A, একটি ব্রেকপয়েন্ট সেট করুন (F2 কী), এটি সম্পাদনা করুন (প্রসঙ্গ মেনু ব্রেকপয়েন্ট সম্পাদনা করুন...), স্ক্রিপ্ট টাইপ পাইথনে সেট করতে ভুলবেন না:

একটি বিড়ালের ভিতরে গন্ডার - কপিক্যাট এমুলেটরে ফার্মওয়্যার চালান
একটি বিড়ালের ভিতরে গন্ডার - কপিক্যাট এমুলেটরে ফার্মওয়্যার চালান

যদি বর্তমান পতাকা মান ব্যস্ত равно 1, то следует выполнить функцию skip_dma স্ক্রিপ্ট লাইনে:

একটি বিড়ালের ভিতরে গন্ডার - কপিক্যাট এমুলেটরে ফার্মওয়্যার চালান

আপনি যদি কার্যকর করার জন্য ফার্মওয়্যার চালান, আপনি IDA উইন্ডোতে ব্রেকপয়েন্ট হ্যান্ডলার কোডের ট্রিগারিং দেখতে পাবেন আউটপুট লাইন দ্বারা Skipping wait ws2812.... Теперь прошивка не будет ожидать сброс флага ব্যস্ত.

এমুলেটরের সাথে মিথস্ক্রিয়া

অনুকরণের জন্য অনুকরণ আনন্দ এবং আনন্দের কারণ হওয়ার সম্ভাবনা নেই। ইমুলেটর যদি গবেষককে মেমরিতে ডেটা দেখতে বা থ্রেডগুলির মিথস্ক্রিয়া স্থাপন করতে সহায়তা করে তবে এটি আরও আকর্ষণীয়।

আমরা আপনাকে দেখাব কিভাবে গতিশীলভাবে RTOS কাজের মধ্যে মিথস্ক্রিয়া স্থাপন করতে হয়। কোডটি চলমান থাকলে আপনাকে প্রথমে এটির এক্সিকিউশনকে বিরতি দিতে হবে। ফাংশনে গেলে bluetooth_task_entry "LED" কমান্ডের প্রক্রিয়াকরণ শাখায় (ঠিকানা 0x080057B8), তারপর আপনি দেখতে পাবেন কি প্রথমে তৈরি করা হয়েছে এবং তারপর সিস্টেম সারিতে পাঠানো হয়েছে ledControlQueueHandle কিছু বার্তা।

একটি বিড়ালের ভিতরে গন্ডার - কপিক্যাট এমুলেটরে ফার্মওয়্যার চালান

ভেরিয়েবল অ্যাক্সেস করার জন্য আপনার একটি ব্রেকপয়েন্ট সেট করা উচিত ledControlQueueHandleঅবস্থিত 0x20000624 и продолжить выполнение кода:

একটি বিড়ালের ভিতরে গন্ডার - কপিক্যাট এমুলেটরে ফার্মওয়্যার চালান

ফলস্বরূপ, স্টপ প্রথমে ঠিকানায় ঘটবে 0x080057CA ফাংশন কল করার আগে osMailAllocতারপর ঠিকানায় 0x08005806 ফাংশন কল করার আগে osMailPut, потом через некоторое время — по адресу 0x08005BD4 (ফাংশন কল করার আগে osMailGet), который принадлежит функции leds_task_entry (এলইডি-টাস্ক), অর্থাৎ, কাজগুলি সুইচ করা হয়েছে এবং এখন এলইডি-টাস্ক নিয়ন্ত্রণ পেয়েছে।

একটি বিড়ালের ভিতরে গন্ডার - কপিক্যাট এমুলেটরে ফার্মওয়্যার চালান

এই সহজ উপায়ে আপনি RTOS কাজগুলি একে অপরের সাথে কীভাবে ইন্টারঅ্যাক্ট করে তা স্থাপন করতে পারেন।

অবশ্যই, বাস্তবে, কার্যগুলির মিথস্ক্রিয়া আরও জটিল হতে পারে, তবে একটি এমুলেটর ব্যবহার করে, এই মিথস্ক্রিয়া ট্র্যাক করা কম শ্রমসাধ্য হয়ে ওঠে।

এখানে আপনি এমুলেটর চালু করার এবং IDA Pro এর সাথে ইন্টারঅ্যাক্ট করার একটি ছোট ভিডিও দেখতে পারেন।

Radare2 দিয়ে লঞ্চ করুন

আপনি Radare2 এর মতো একটি সর্বজনীন সরঞ্জামকে উপেক্ষা করতে পারবেন না।

r2 ব্যবহার করে এমুলেটরের সাথে সংযোগ করতে, কমান্ডটি দেখতে এইরকম হবে:

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

Сейчас доступны запуск (dc) এবং পজ এক্সিকিউশন (Ctrl+C)।

দুর্ভাগ্যবশত, এই মুহুর্তে, হার্ডওয়্যার জিডিবি সার্ভার এবং মেমরি লেআউটের সাথে কাজ করার সময় r2-এর সমস্যা রয়েছে; এর কারণে, ব্রেকপয়েন্ট এবং পদক্ষেপগুলি কাজ করে না (কমান্ড ds). Надеемся, в ближайшее время это будет исправлено.

Запуск с Eclipse

এমুলেটর ব্যবহার করার বিকল্পগুলির মধ্যে একটি হল ডেভেলপ করা ডিভাইসের ফার্মওয়্যার ডিবাগ করা। স্বচ্ছতার জন্য, আমরা Rhino ফার্মওয়্যারও ব্যবহার করব। আপনি ফার্মওয়্যার উত্সগুলি ডাউনলোড করতে পারেন এখানে থেকে.

В качестве IDE будем использовать Eclipse из набора 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 (выставить в регистр PC значение из памяти по адресу 0x08000004 - ঠিকানা সেখানে সংরক্ষিত আছে রিসেটহ্যান্ডলার).

মনোযোগ দাও, আপনি যদি Eclipse থেকে ফার্মওয়্যার ফাইল ডাউনলোড করতে না চান, তাহলে বিকল্পগুলি ছবি লোড করুন и কমান্ড চালান নির্দেশ করার প্রয়োজন নেই।

একটি বিড়ালের ভিতরে গন্ডার - কপিক্যাট এমুলেটরে ফার্মওয়্যার চালান

ডিবাগ ক্লিক করার পরে, আপনি ডিবাগার মোডে কাজ করতে পারেন:

  • ধাপে ধাপে কোড এক্সিকিউশন
    একটি বিড়ালের ভিতরে গন্ডার - কপিক্যাট এমুলেটরে ফার্মওয়্যার চালান
  • ব্রেকপয়েন্টের সাথে মিথস্ক্রিয়া করা
    একটি বিড়ালের ভিতরে গন্ডার - কপিক্যাট এমুলেটরে ফার্মওয়্যার চালান

মন্তব্য. Eclipse আছে, হুম... কিছু quirks... এবং আপনাকে তাদের সাথে থাকতে হবে। উদাহরণস্বরূপ, যদি ডিবাগার শুরু করার সময় "0x0″ এর জন্য কোন উৎস উপলব্ধ নেই" বার্তাটি উপস্থিত হয়, তাহলে ধাপ কমান্ডটি চালান (F5)

একটি বিড়ালের ভিতরে গন্ডার - কপিক্যাট এমুলেটরে ফার্মওয়্যার চালান

পরিবর্তে একটি উপসংহারের

Эмуляция нативного кода — дело весьма интересное. Для разработчика устройств появляется возможность отлаживать прошивку без реального устройства. Для исследователя — возможность проводить динамический анализ кода, что не всегда возможно даже при наличии устройства.

আমরা বিশেষজ্ঞদের এমন একটি টুল সরবরাহ করতে চাই যা সুবিধাজনক, মাঝারিভাবে সহজ এবং সেট আপ এবং চালানোর জন্য অনেক প্রচেষ্টা এবং সময় লাগে না।

হার্ডওয়্যার এমুলেটর ব্যবহার করে আপনার অভিজ্ঞতা সম্পর্কে মন্তব্যে লিখুন। আমরা আপনাকে আলোচনা করার জন্য আমন্ত্রণ জানাই এবং প্রশ্নের উত্তর দিতে পেরে খুশি হব।

শুধুমাত্র নিবন্ধিত ব্যবহারকারীরা জরিপে অংশগ্রহণ করতে পারবেন। সাইন ইন করুনকরুন।

আপনি কি জন্য এমুলেটর ব্যবহার করছেন?

  • আমি (ডিবাগ) ফার্মওয়্যার বিকাশ করি

  • আমি ফার্মওয়্যার নিয়ে গবেষণা করছি

  • আমি গেম চালু করি (ডেন্ডি, সেগা, পিএসপি)

  • অন্য কিছু (মন্তব্যে লিখুন)

7 ব্যবহারকারী ভোট দিয়েছেন। 2 জন ব্যবহারকারী বিরত ছিলেন।

নেটিভ কোড অনুকরণ করতে আপনি কোন সফ্টওয়্যার ব্যবহার করেন?

  • QEMU দ্বারা

  • Unicorn engine

  • প্রোটিয়াস

  • অন্য কিছু (মন্তব্যে লিখুন)

6 ব্যবহারকারী ভোট দিয়েছেন। 2 জন ব্যবহারকারী বিরত ছিলেন।

আপনি যে এমুলেটর ব্যবহার করছেন তাতে আপনি কী উন্নতি করতে চান?

  • хочется скорости

  • আমি সেটআপ/লঞ্চের সহজতা চাই

  • আমি এমুলেটরের সাথে ইন্টারঅ্যাক্ট করার জন্য আরও বিকল্প চাই (API, হুক)

  • আমি সবকিছুতেই খুশি

  • অন্য কিছু (মন্তব্যে লিখুন)

8 জন ব্যবহারকারী ভোট দিয়েছেন। ১ জন ব্যবহারকারী বিরত ছিলেন।

উত্স: www.habr.com

একটি মন্তব্য জুড়ুন