Tê giác bên trong con mèo - chạy chương trình cơ sở trong trình giả lập Kopycat

Tê giác bên trong con mèo - chạy chương trình cơ sở trong trình giả lập Kopycat

Là một phần của cuộc họp 0x0A DC7831 DEF CON Nizhny Novgorod Vào ngày 16 tháng XNUMX, chúng tôi đã trình bày một báo cáo về các nguyên tắc cơ bản của mô phỏng mã nhị phân và sự phát triển của chính chúng tôi - trình mô phỏng nền tảng phần cứng bắt chước.

Trong bài viết này, chúng tôi sẽ mô tả cách chạy chương trình cơ sở của thiết bị trong trình mô phỏng, thể hiện sự tương tác với trình gỡ lỗi và thực hiện phân tích động nhỏ về chương trình cơ sở.

thời tiền sử

Cách đây rất lâu ở một thiên hà xa xôi

Một vài năm trước, trong phòng thí nghiệm của chúng tôi cần phải điều tra phần sụn của thiết bị. Phần sụn đã được nén và giải nén bằng bộ nạp khởi động. Anh ấy đã làm điều này một cách rất phức tạp, chuyển đổi dữ liệu trong bộ nhớ nhiều lần. Và bản thân phần sụn sau đó sẽ tương tác tích cực với các thiết bị ngoại vi. Và tất cả điều này trên lõi MIPS.

Vì lý do khách quan, các trình giả lập có sẵn không phù hợp với chúng tôi nhưng chúng tôi vẫn muốn chạy mã. Sau đó, chúng tôi quyết định tạo trình mô phỏng của riêng mình, trình mô phỏng này sẽ hoạt động ở mức tối thiểu và cho phép chúng tôi giải nén phần sụn chính. Chúng tôi đã thử nó và nó đã hoạt động. Chúng tôi nghĩ, điều gì sẽ xảy ra nếu chúng tôi thêm các thiết bị ngoại vi để thực hiện phần sụn chính. Nó không đau lắm - và nó cũng có tác dụng. Chúng tôi đã suy nghĩ lại và quyết định tạo một trình giả lập chính thức.

Kết quả là một trình giả lập hệ thống máy tính bắt chước.

Tê giác bên trong con mèo - chạy chương trình cơ sở trong trình giả lập Kopycat
Tại sao lại là Kopycat?

Có một cách chơi chữ.

  1. copycat (Tiếng Anh, danh từ [ˈkɒpɪkæt]) - kẻ bắt chước, kẻ bắt chước
  2. làm sao (Tiếng Anh, danh từ [ˈkæt]) - mèo, mèo - con vật yêu thích của một trong những người tạo ra dự án
  3. Chữ “K” là từ ngôn ngữ lập trình Kotlin

bắt chước

Khi tạo trình mô phỏng, các mục tiêu rất cụ thể đã được đặt ra:

  • khả năng tạo nhanh các thiết bị ngoại vi, mô-đun, lõi xử lý mới;
  • khả năng lắp ráp một thiết bị ảo từ nhiều mô-đun khác nhau;
  • khả năng tải bất kỳ dữ liệu nhị phân (chương trình cơ sở) nào vào bộ nhớ của thiết bị ảo;
  • khả năng làm việc với ảnh chụp nhanh (ảnh chụp nhanh trạng thái hệ thống);
  • khả năng tương tác với trình giả lập thông qua trình gỡ lỗi tích hợp sẵn;
  • ngôn ngữ hiện đại tốt đẹp để phát triển.

Do đó, Kotlin đã được chọn để triển khai, kiến ​​trúc bus (đây là khi các mô-đun giao tiếp với nhau thông qua bus dữ liệu ảo), JSON làm định dạng mô tả thiết bị và GDB RSP làm giao thức tương tác với trình gỡ lỗi.

Sự phát triển đã diễn ra được hơn hai năm và đang tích cực diễn ra. Trong thời gian này, các lõi xử lý MIPS, x86, V850ES, ARM và PowerPC đã được triển khai.

Dự án đang phát triển và đã đến lúc giới thiệu nó với công chúng rộng rãi hơn. Chúng tôi sẽ mô tả chi tiết về dự án sau, nhưng hiện tại chúng tôi sẽ tập trung vào việc sử dụng Kopycat.

Đối với những người thiếu kiên nhẫn nhất, có thể tải xuống phiên bản quảng cáo của trình giả lập từ liên kết.

Tê giác trong trình giả lập

Chúng ta hãy nhớ lại rằng trước đó tại hội nghị SMARTRHINO-2018, một thiết bị thử nghiệm “Tê giác” đã được tạo ra để dạy các kỹ năng kỹ thuật đảo ngược. Quá trình phân tích phần sụn tĩnh được mô tả trong bài viết này.

Bây giờ hãy thử thêm “loa” và chạy chương trình cơ sở trong trình mô phỏng.

Chúng tôi sẽ cần:
1) Java 1.8
2) Python và mô-đun jep để sử dụng Python bên trong trình mô phỏng. Bạn có thể xây dựng mô-đun WHL Jep cho Windows tải xuống ở đây.

Đối với Windows:
1) com0com
2) PuTTY

Đối với Linux:
1) xã hội

Bạn có thể sử dụng Eclipse, IDA Pro hoặc radare2 làm máy khách GDB.

Nó hoạt động như thế nào?

Để thực hiện chương trình cơ sở trong trình mô phỏng, cần phải “lắp ráp” một thiết bị ảo, tương tự như một thiết bị thực.

Thiết bị thực (“tê giác”) có thể được hiển thị trong sơ đồ khối:

Tê giác bên trong con mèo - chạy chương trình cơ sở trong trình giả lập Kopycat

Trình mô phỏng có cấu trúc mô-đun và thiết bị ảo cuối cùng có thể được mô tả trong tệp JSON.

JSON 105 dòng

{
  "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"]
  ]
}

Chú ý đến tham số firmware phần thông số là tên của tệp có thể được tải vào thiết bị ảo dưới dạng chương trình cơ sở.

Thiết bị ảo và sự tương tác của nó với hệ điều hành chính có thể được biểu diễn bằng sơ đồ sau:

Tê giác bên trong con mèo - chạy chương trình cơ sở trong trình giả lập Kopycat

Phiên bản thử nghiệm hiện tại của trình mô phỏng liên quan đến việc tương tác với các cổng COM của hệ điều hành chính (gỡ lỗi UART và UART cho mô-đun Bluetooth). Đây có thể là các cổng thực mà thiết bị được kết nối hoặc các cổng COM ảo (để làm được điều này, bạn chỉ cần com0com/socat).

Hiện tại có hai cách chính để tương tác với trình mô phỏng từ bên ngoài:

  • Giao thức GDB RSP (theo đó, các công cụ hỗ trợ giao thức này là Eclipse/IDA/radae2);
  • dòng lệnh mô phỏng nội bộ (Argparse hoặc Python).

Cổng COM ảo

Để tương tác với UART của thiết bị ảo trên máy cục bộ thông qua thiết bị đầu cuối, bạn cần tạo một cặp cổng COM ảo được liên kết. Trong trường hợp của chúng tôi, một cổng được trình mô phỏng sử dụng và cổng thứ hai được sử dụng bởi chương trình đầu cuối (PuTTY hoặc màn hình):

Tê giác bên trong con mèo - chạy chương trình cơ sở trong trình giả lập Kopycat

Sử dụng com0com

Cổng COM ảo được định cấu hình bằng tiện ích thiết lập từ bộ com0com (phiên bản console - C:Tệp chương trình (x86)com0comsetupс.exe, hoặc phiên bản GUI - C:Tệp chương trình (x86)com0comsetupg.exe):

Tê giác bên trong con mèo - chạy chương trình cơ sở trong trình giả lập Kopycat

Kiểm tra các hộp kích hoạt lỗi tràn bộ đệm đối với tất cả các cổng ảo đã tạo, nếu không trình mô phỏng sẽ chờ phản hồi từ cổng COM.

Sử dụng socat

Trên hệ thống UNIX, các cổng COM ảo được trình mô phỏng tự động tạo bằng tiện ích socat để thực hiện việc này, chỉ cần chỉ định tiền tố trong tên cổng khi khởi động trình mô phỏng; socat:.

Giao diện dòng lệnh nội bộ (Argparse hoặc Python)

Vì Kopycat là một ứng dụng bảng điều khiển nên trình mô phỏng cung cấp hai tùy chọn giao diện dòng lệnh để tương tác với các đối tượng và biến của nó: Argparse và Python.

Argparse là CLI được tích hợp trong Kopycat và luôn có sẵn cho mọi người.

Một CLI thay thế là trình thông dịch Python. Để sử dụng nó, bạn cần cài đặt mô-đun Jep Python và định cấu hình trình giả lập để hoạt động với Python (trình thông dịch Python được cài đặt trên hệ thống chính của người dùng sẽ được sử dụng).

Cài đặt mô-đun Python Jep

Trong Linux Jep có thể được cài đặt qua pip:

pip install jep

Để cài đặt Jep trên Windows, trước tiên bạn phải cài đặt Windows SDK và Microsoft Visual Studio tương ứng. Chúng tôi đã làm cho nó dễ dàng hơn một chút cho bạn và bản dựng WHL JEP cho các phiên bản hiện tại của Python dành cho Windows, vì vậy mô-đun có thể được cài đặt từ tệp:

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

Để kiểm tra cài đặt Jep, bạn cần chạy trên dòng lệnh:

python -c "import jep"

Thông báo sau sẽ được nhận để phản hồi:

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

Trong tệp bó trình mô phỏng cho hệ thống của bạn (sao chép.bat - cho cửa sổ, bắt chước - đối với Linux) vào danh sách các tham số DEFAULT_JVM_OPTS thêm một tham số bổ sung Djava.library.path — nó phải chứa đường dẫn đến mô-đun Jep đã cài đặt.

Kết quả cho Windows sẽ là một dòng như thế này:

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

Ra mắt Kopycat

Trình mô phỏng là một ứng dụng JVM trên bảng điều khiển. Việc khởi chạy được thực hiện thông qua tập lệnh dòng lệnh của hệ điều hành (sh/cmd).

Lệnh chạy trong Windows:

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

Lệnh chạy trên Linux bằng tiện ích 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 — Cổng TCP sẽ mở để truy cập vào máy chủ GDB;
  • -n rhino - tên của môđun hệ thống chính (thiết bị đã lắp ráp);
  • -l user — tên thư viện để tìm kiếm mô-đun chính;
  • -y library - đường dẫn tìm kiếm các mô-đun có trong thiết bị;
  • firmwarerhino_pass.bin - đường dẫn đến tập tin phần sụn;
  • COM26 và COM28 là cổng COM ảo.

Kết quả là sẽ xuất hiện một thông báo Python > (hoặc 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 >

Tương tác với IDA Pro

Để đơn giản hóa việc kiểm tra, chúng tôi sử dụng firmware Rhino làm file nguồn để phân tích trong IDA dưới dạng tập tin ELF (thông tin meta được lưu trữ ở đó).

Bạn cũng có thể sử dụng phần sụn chính mà không cần thông tin meta.

Sau khi khởi chạy Kopycat trong IDA Pro, trong menu Trình gỡ lỗi, hãy chuyển đến mục “Chuyển trình gỡ lỗi…" và chọn "Trình gỡ lỗi GDB từ xa". Tiếp theo, thiết lập kết nối: menu Trình gỡ lỗi - Tùy chọn quy trình…

Đặt các giá trị:

  • Ứng dụng - bất kỳ giá trị nào
  • Tên máy chủ: 127.0.0.1 (hoặc địa chỉ IP của máy từ xa nơi Kopycat đang chạy)
  • Cổng: 23946

Tê giác bên trong con mèo - chạy chương trình cơ sở trong trình giả lập Kopycat

Bây giờ nút gỡ lỗi sẽ khả dụng (phím F9):

Tê giác bên trong con mèo - chạy chương trình cơ sở trong trình giả lập Kopycat

Nhấp vào nó để kết nối với mô-đun trình gỡ lỗi trong trình mô phỏng. IDA chuyển sang chế độ gỡ lỗi, các cửa sổ bổ sung sẽ xuất hiện: thông tin về các thanh ghi, về ngăn xếp.

Bây giờ chúng ta có thể sử dụng tất cả các tính năng tiêu chuẩn của trình gỡ lỗi:

  • thực hiện từng bước các hướng dẫn (Bước vào и Bước qua - các phím F7 và F8 tương ứng);
  • bắt đầu và tạm dừng thực hiện;
  • tạo breakpoint cho cả code và dữ liệu (phím F2).

Kết nối với trình gỡ lỗi không có nghĩa là chạy mã chương trình cơ sở. Vị trí thực hiện hiện tại phải là địa chỉ 0x08006A74 - bắt đầu chức năng Đặt lại_Handler. Nếu bạn cuộn xuống danh sách, bạn có thể thấy lệnh gọi hàm chính. Bạn có thể đặt con trỏ trên dòng này (địa chỉ 0x08006ABE) và thực hiện thao tác Chạy cho đến khi con trỏ (phím F4).

Tê giác bên trong con mèo - chạy chương trình cơ sở trong trình giả lập Kopycat

Tiếp theo bạn có thể nhấn F7 để vào chức năng chính.

Lệnh Esli vypolnit Tiếp tục quá trình (Phím F9), sau đó cửa sổ “Xin vui lòng đợi” sẽ xuất hiện chỉ bằng một nút bấm Treo:

Tê giác bên trong con mèo - chạy chương trình cơ sở trong trình giả lập Kopycat

Khi bạn nhấn Treo việc thực thi mã chương trình cơ sở bị tạm dừng và có thể được tiếp tục từ cùng một địa chỉ trong mã nơi nó bị gián đoạn.

Nếu tiếp tục thực thi mã, bạn sẽ thấy các dòng sau trong thiết bị đầu cuối được kết nối với cổng COM ảo:

Tê giác bên trong con mèo - chạy chương trình cơ sở trong trình giả lập Kopycat

Tê giác bên trong con mèo - chạy chương trình cơ sở trong trình giả lập Kopycat

Sự hiện diện của dòng “state bypass” cho biết mô-đun Bluetooth ảo đã chuyển sang chế độ nhận dữ liệu từ cổng COM của người dùng.

Giờ đây, trong thiết bị đầu cuối Bluetooth (COM29 trong hình), bạn có thể nhập lệnh theo giao thức Rhino. Ví dụ: lệnh “MEOW” sẽ trả về chuỗi “mur-mur” cho thiết bị đầu cuối Bluetooth:

Tê giác bên trong con mèo - chạy chương trình cơ sở trong trình giả lập Kopycat

Bắt chước tôi không hoàn toàn

Khi xây dựng trình giả lập, bạn có thể chọn mức độ chi tiết/mô phỏng của một thiết bị cụ thể. Ví dụ: mô-đun Bluetooth có thể được mô phỏng theo nhiều cách khác nhau:

  • thiết bị được mô phỏng đầy đủ với một bộ lệnh đầy đủ;
  • Các lệnh AT được mô phỏng và luồng dữ liệu được nhận từ cổng COM của hệ thống chính;
  • thiết bị ảo cung cấp khả năng chuyển hướng dữ liệu hoàn chỉnh sang thiết bị thực;
  • như một sơ khai đơn giản luôn trả về "OK".

Phiên bản hiện tại của trình mô phỏng sử dụng cách tiếp cận thứ hai - mô-đun Bluetooth ảo thực hiện cấu hình, sau đó nó chuyển sang chế độ "ủy quyền" dữ liệu từ cổng COM của hệ thống chính sang cổng UART của trình mô phỏng.

Tê giác bên trong con mèo - chạy chương trình cơ sở trong trình giả lập Kopycat

Hãy xem xét khả năng thiết lập mã đơn giản trong trường hợp một phần ngoại vi không được triển khai. Ví dụ: nếu bộ hẹn giờ chịu trách nhiệm kiểm soát việc truyền dữ liệu tới DMA chưa được tạo (việc kiểm tra được thực hiện trong hàm ws2812b_wait, raspolojennoy po adresu 0x08006840), thì phần sụn sẽ luôn chờ cờ được đặt lại bận rộnĐặt vị trí tại 0x200004C4trong đó cho thấy sự chiếm chỗ của dòng dữ liệu DMA:

Tê giác bên trong con mèo - chạy chương trình cơ sở trong trình giả lập Kopycat

Chúng ta có thể khắc phục tình trạng này bằng cách đặt lại cờ theo cách thủ công bận rộn ngay sau khi cài đặt nó. Trong IDA Pro, bạn có thể tạo một hàm Python và gọi nó trong một điểm dừng, đồng thời đặt chính điểm dừng đó vào mã sau khi ghi giá trị 1 vào cờ bận rộn.

Trình xử lý điểm dừng

Đầu tiên, hãy tạo một hàm Python trong IDA. Thực đơn Tệp - Lệnh tập lệnh...

Thêm đoạn mã mới vào danh sách bên trái, đặt tên cho nó (ví dụ: BPT),
Trong trường văn bản bên phải, nhập mã chức năng:

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

Tê giác bên trong con mèo - chạy chương trình cơ sở trong trình giả lập Kopycat

Sau đó, nhấp vào chạy và đóng cửa sổ tập lệnh.

Bây giờ chúng ta hãy đi đến mã tại 0x0800688A, đặt điểm dừng (phím F2), chỉnh sửa nó (menu ngữ cảnh Chỉnh sửa điểm dừng...), đừng quên đặt loại tập lệnh thành Python:

Tê giác bên trong con mèo - chạy chương trình cơ sở trong trình giả lập Kopycat
Tê giác bên trong con mèo - chạy chương trình cơ sở trong trình giả lập Kopycat

Nếu giá trị cờ hiện tại bận rộn bằng 1 thì bạn nên thực thi hàm bỏ qua_dma trong dòng kịch bản:

Tê giác bên trong con mèo - chạy chương trình cơ sở trong trình giả lập Kopycat

Nếu bạn chạy chương trình cơ sở để thực thi, bạn có thể thấy việc kích hoạt mã xử lý điểm dừng trong cửa sổ IDA Đầu ra theo dòng Skipping wait ws2812.... Bây giờ phần sụn sẽ không đợi cờ được đặt lại bận rộn.

Tương tác với trình giả lập

Thi đua vì mục đích thi đua khó có thể gây ra sự vui thích, hân hoan. Sẽ thú vị hơn nhiều nếu trình giả lập giúp nhà nghiên cứu xem dữ liệu trong bộ nhớ hoặc thiết lập sự tương tác giữa các luồng.

Chúng tôi sẽ chỉ cho bạn cách thiết lập tương tác động giữa các tác vụ RTOS. Trước tiên bạn nên tạm dừng việc thực thi mã nếu nó đang chạy. Nếu bạn đi đến chức năng bluetooth_task_entry tới nhánh xử lý của lệnh “LED” (địa chỉ 0x080057B8), thì bạn có thể xem nội dung nào được tạo đầu tiên và sau đó được gửi đến hàng đợi hệ thống ledControlHàng đợiXử lý tin nhắn nào đó.

Tê giác bên trong con mèo - chạy chương trình cơ sở trong trình giả lập Kopycat

Bạn nên đặt điểm ngắt để truy cập vào biến ledControlHàng đợiXử lý, raspolojennoy po adresu 0x20000624 và tiếp tục thực thi mã:

Tê giác bên trong con mèo - chạy chương trình cơ sở trong trình giả lập Kopycat

Kết quả là điểm dừng đầu tiên sẽ xảy ra tại địa chỉ 0x080057CA trước khi gọi hàm osMailAlloc, sau đó tại địa chỉ 0x08005806 trước khi gọi hàm osMailPut, sau đó một lúc - đến địa chỉ 0x08005BD4 (trước khi gọi hàm osMailGet), thuộc hàm leds_task_entry (Tác vụ LED), nghĩa là các tác vụ đã được chuyển đổi và bây giờ tác vụ LED đã nhận được điều khiển.

Tê giác bên trong con mèo - chạy chương trình cơ sở trong trình giả lập Kopycat

Bằng cách đơn giản này, bạn có thể thiết lập cách các tác vụ RTOS tương tác với nhau.

Tất nhiên, trên thực tế, việc tương tác giữa các tác vụ có thể phức tạp hơn, nhưng việc sử dụng trình giả lập, việc theo dõi sự tương tác này trở nên ít tốn công sức hơn.

Đây Bạn có thể xem một đoạn video ngắn về quá trình khởi chạy và tương tác với trình giả lập với IDA Pro.

Khởi chạy với Radare2

Bạn không thể bỏ qua một công cụ phổ biến như Radare2.

Để kết nối với trình mô phỏng bằng r2, lệnh sẽ như sau:

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

Ra mắt có sẵn ngay bây giờ (dc) và tạm dừng thực thi (Ctrl+C).

Thật không may, hiện tại, r2 gặp sự cố khi làm việc với máy chủ gdb phần cứng và bố cục bộ nhớ, do đó, các điểm dừng và các bước không hoạt động (lệnh; ds). Chúng tôi hy vọng điều này sẽ sớm được khắc phục.

Chạy với Eclipse

Một trong những lựa chọn khi sử dụng trình giả lập là gỡ lỗi phần sụn của thiết bị đang được phát triển. Để rõ ràng, chúng tôi cũng sẽ sử dụng phần sụn Rhino. Bạn có thể tải xuống các nguồn phần sụn do đó.

Chúng tôi sẽ sử dụng Eclipse từ bộ này làm IDE Bàn làm việc hệ thống cho STM32.

Để trình giả lập tải firmware được biên dịch trực tiếp trong Eclipse, bạn cần thêm tham số firmware=null đến lệnh khởi chạy trình mô phỏng:

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

Thiết lập cấu hình gỡ lỗi

Trong Eclipse, chọn menu Chạy - Cấu hình gỡ lỗi... Trong cửa sổ mở ra, trong phần Gỡ lỗi phần cứng GDB bạn cần thêm cấu hình mới, sau đó trên tab “Chính” chỉ định dự án và ứng dụng hiện tại để gỡ lỗi:

Tê giác bên trong con mèo - chạy chương trình cơ sở trong trình giả lập Kopycat

Trên tab “Trình gỡ lỗi”, bạn cần chỉ định lệnh GDB:
${openstm32_compiler_path}arm-none-eabi-gdb

Và cũng nhập các tham số để kết nối với máy chủ GDB (máy chủ và cổng):

Tê giác bên trong con mèo - chạy chương trình cơ sở trong trình giả lập Kopycat

Trên tab “Khởi động”, bạn phải chỉ định các tham số sau:

  • bật hộp kiểm Tải hình ảnh (để hình ảnh chương trình cơ sở đã lắp ráp được tải vào trình mô phỏng);
  • bật hộp kiểm Tải biểu tượng;
  • thêm lệnh khởi chạy: set $pc = *0x08000004 (đặt thanh ghi PC thành giá trị từ bộ nhớ tại địa chỉ 0x08000004 - địa chỉ được lưu trữ ở đó Trình xử lý lại).

Chú ý, nếu bạn không muốn tải xuống tệp chương trình cơ sở từ Eclipse, thì các tùy chọn Tải hình ảnh и Chạy lệnh không cần phải chỉ ra.

Tê giác bên trong con mèo - chạy chương trình cơ sở trong trình giả lập Kopycat

Sau khi nhấp vào Gỡ lỗi, bạn có thể làm việc ở chế độ trình gỡ lỗi:

  • thực thi mã từng bước
    Tê giác bên trong con mèo - chạy chương trình cơ sở trong trình giả lập Kopycat
  • tương tác với các điểm dừng
    Tê giác bên trong con mèo - chạy chương trình cơ sở trong trình giả lập Kopycat

Ghi. Eclipse có, hmm... một số điều kỳ quặc... và bạn phải chấp nhận chúng. Ví dụ: nếu khi khởi động trình gỡ lỗi, thông báo “Không có nguồn nào cho “0x0” xuất hiện thì hãy thực hiện lệnh Bước (F5)

Tê giác bên trong con mèo - chạy chương trình cơ sở trong trình giả lập Kopycat

Thay vì một kết luận

Giả lập mã gốc là một điều rất thú vị. Nhà phát triển thiết bị có thể gỡ lỗi chương trình cơ sở mà không cần thiết bị thực. Đối với một nhà nghiên cứu, đây là cơ hội để tiến hành phân tích mã động, điều này không phải lúc nào cũng có thể thực hiện được ngay cả với một thiết bị.

Chúng tôi muốn cung cấp cho các chuyên gia một công cụ tiện lợi, đơn giản vừa phải và không tốn nhiều công sức, thời gian để thiết lập và chạy.

Viết nhận xét về trải nghiệm của bạn khi sử dụng trình mô phỏng phần cứng. Chúng tôi mời bạn thảo luận và sẽ sẵn lòng trả lời các câu hỏi.

Chỉ những người dùng đã đăng ký mới có thể tham gia khảo sát. Đăng nhập, xin vui lòng.

Bạn đang sử dụng trình giả lập để làm gì?

  • Tôi phát triển chương trình cơ sở (gỡ lỗi)

  • Tôi đang nghiên cứu phần mềm

  • Tôi khởi động trò chơi (Dendi, Sega, PSP)

  • cái gì khác (viết trong phần bình luận)

7 người dùng bình chọn. 2 người dùng bỏ phiếu trắng.

Bạn sử dụng phần mềm nào để mô phỏng mã gốc?

  • QEMU

  • Động cơ kỳ lân

  • Proteus

  • cái gì khác (viết trong phần bình luận)

6 người dùng bình chọn. 2 người dùng bỏ phiếu trắng.

Bạn muốn cải thiện điều gì trong trình mô phỏng bạn đang sử dụng?

  • Tôi muốn tốc độ

  • Tôi muốn dễ dàng thiết lập/khởi chạy

  • Tôi muốn có thêm tùy chọn để tương tác với trình mô phỏng (API, hook)

  • Tôi hài lòng với mọi thứ

  • cái gì khác (viết trong phần bình luận)

8 người dùng bình chọn. 1 người dùng đã bỏ phiếu trắng.

Nguồn: www.habr.com

Thêm một lời nhận xét