ืงืจื ืฃ ื‘ืชื•ืš ื—ืชื•ืœ - ื”ืคืขืœ ืืช ื”ืงื•ืฉื—ื” ื‘ืืžื•ืœื˜ื•ืจ Kopycat

ืงืจื ืฃ ื‘ืชื•ืš ื—ืชื•ืœ - ื”ืคืขืœ ืืช ื”ืงื•ืฉื—ื” ื‘ืืžื•ืœื˜ื•ืจ Kopycat

ื‘ืžืกื’ืจืช ื”ืคื’ื™ืฉื” 0x0A DC7831 DEF CON ื ื™ื–'ื ื™ ื ื•ื‘ื’ื•ืจื•ื“ ื‘-16 ื‘ืคื‘ืจื•ืืจ ื”ืฆื’ื ื• ื“ื•"ื— ืขืœ ื”ืขืงืจื•ื ื•ืช ื”ื‘ืกื™ืกื™ื™ื ืฉืœ ืืžื•ืœืฆื™ื™ืช ืงื•ื“ ื‘ื™ื ืืจื™ ื•ื”ืคื™ืชื•ื— ืฉืœื ื• - ืืžื•ืœื˜ื•ืจ ืคืœื˜ืคื•ืจืžืช ื—ื•ืžืจื” ืขื•ืชืง.

ื‘ืžืืžืจ ื–ื” ื ืชืืจ ื›ื™ืฆื“ ืœื”ืคืขื™ืœ ืืช ืงื•ืฉื—ืช ื”ืžื›ืฉื™ืจ ื‘ืืžื•ืœื˜ื•ืจ, ืœื”ื“ื’ื™ื ืื™ื ื˜ืจืืงืฆื™ื” ืขื ื”-debugger, ื•ืœื‘ืฆืข ื ื™ืชื•ื— ื“ื™ื ืžื™ ืงื˜ืŸ ืฉืœ ื”ืงื•ืฉื—ื”.

ืคืจื”ื™ืกื˜ื•ืจื™ื”

ืœืคื ื™ ื”ืจื‘ื” ื–ืžืŸ ื‘ื’ืœืงืกื™ื” ืจื—ื•ืงื” ืจื—ื•ืงื”

ืœืคื ื™ ื›ืžื” ืฉื ื™ื ื‘ืžืขื‘ื“ื” ืฉืœื ื• ื”ื™ื” ืฆื•ืจืš ืœื—ืงื•ืจ ืืช ื”ืงื•ืฉื—ื” ืฉืœ ืžื›ืฉื™ืจ. ื”ืงื•ืฉื—ื” ื ื“ื—ืกื” ื•ืคื•ืจืงื” ืขื ื˜ื•ืขืŸ ืืชื—ื•ืœ. ื”ื•ื ืขืฉื” ื–ืืช ื‘ืฆื•ืจื” ืžืื•ื“ ืžืกื•ื‘ื›ืช, ื•ื”ืขื‘ื™ืจ ืืช ื”ื ืชื•ื ื™ื ื‘ื–ื™ื›ืจื•ืŸ ืžืกืคืจ ืคืขืžื™ื. ื•ื”ืงื•ืฉื—ื” ืขืฆืžื” ืขืฉืชื” ืื– ืื™ื ื˜ืจืืงืฆื™ื” ืืงื˜ื™ื‘ื™ืช ืขื ื”ืฆื™ื•ื“ ื”ื”ื™ืงืคื™. ื•ื›ืœ ื–ื” ื‘ืœื™ื‘ืช MIPS.

ืžืกื™ื‘ื•ืช ืื•ื‘ื™ื™ืงื˜ื™ื‘ื™ื•ืช, ื”ืืžื•ืœื˜ื•ืจื™ื ื”ื–ืžื™ื ื™ื ืœื ื”ืชืื™ืžื• ืœื ื•, ืื‘ืœ ื‘ื›ืœ ื–ืืช ืจืฆื™ื ื• ืœื”ืคืขื™ืœ ืืช ื”ืงื•ื“. ื•ืื– ื”ื—ืœื˜ื ื• ืœื™ืฆื•ืจ ืืžื•ืœื˜ื•ืจ ืžืฉืœื ื•, ืฉื™ืขืฉื” ืืช ื”ืžื™ื ื™ืžื•ื ื•ื™ืืคืฉืจ ืœื ื• ืœืคืจืง ืืช ื”ืงื•ืฉื—ื” ื”ืจืืฉื™ืช. ื ื™ืกื™ื ื• ืืช ื–ื” ื•ื–ื” ืขื‘ื“. ื—ืฉื‘ื ื•, ืžื” ืื ื ื•ืกื™ืฃ ืฆื™ื•ื“ ื”ื™ืงืคื™ ื›ื“ื™ ืœื‘ืฆืข ื’ื ืืช ื”ืงื•ืฉื—ื” ื”ืจืืฉื™ืช. ื–ื” ืœื ื›ืื‘ ื‘ืžื™ื•ื—ื“ - ื•ื’ื ื–ื” ื”ืกืชื“ืจ. ื—ืฉื‘ื ื• ืฉื•ื‘ ื•ื”ื—ืœื˜ื ื• ืœืขืฉื•ืช ืืžื•ืœื˜ื•ืจ ืžืŸ ื”ืžื ื™ื™ืŸ.

ื”ืชื•ืฆืื” ื”ื™ื™ืชื” ืืžื•ืœื˜ื•ืจ ืžืขืจื›ื•ืช ืžื—ืฉื‘ ืขื•ืชืง.

ืงืจื ืฃ ื‘ืชื•ืš ื—ืชื•ืœ - ื”ืคืขืœ ืืช ื”ืงื•ืฉื—ื” ื‘ืืžื•ืœื˜ื•ืจ Kopycat
ืœืžื” ืงื•ืคื™ืงืื˜?

ื™ืฉ ืžืฉื—ืง ืžื™ืœื™ื.

  1. ื—ืงื™ื™ืŸ (ืื ื’ืœื™ืช, ืฉื ืขืฆื [หˆkษ’pษชkรฆt]) - ื—ืงื™ื™ืŸ, ื—ืงื™ื™ืŸ
  2. ื—ืชื•ืœ (ืื ื’ืœื™ืช, ืฉื ืขืฆื [หˆkรฆt]) - ื—ืชื•ืœ, ื—ืชื•ืœ - ื”ื—ื™ื” ื”ืื”ื•ื‘ื” ืขืœ ืื—ื“ ืžื™ื•ืฆืจื™ ื”ืคืจื•ื™ืงื˜
  3. ื”ืื•ืช "K" ื”ื™ื ืžืฉืคืช ื”ืชื›ื ื•ืช Kotlin

ืขื•ืชืง

ื‘ืขืช ื™ืฆื™ืจืช ื”ืืžื•ืœื˜ื•ืจ, ื”ื•ื’ื“ืจื• ื™ืขื“ื™ื ืžืื•ื“ ืกืคืฆื™ืคื™ื™ื:

  • ื”ื™ื›ื•ืœืช ืœื™ืฆื•ืจ ื‘ืžื”ื™ืจื•ืช ืฆื™ื•ื“ ื”ื™ืงืคื™, ืžื•ื“ื•ืœื™ื, ืœื™ื‘ื•ืช ืžืขื‘ื“ื™ื ื—ื“ืฉื™ื;
  • ื”ื™ื›ื•ืœืช ืœื”ืจื›ื™ื‘ ืžื›ืฉื™ืจ ื•ื™ืจื˜ื•ืืœื™ ืžืžื•ื“ื•ืœื™ื ืฉื•ื ื™ื;
  • ื”ื™ื›ื•ืœืช ืœื˜ืขื•ืŸ ื›ืœ ื ืชื•ื ื™ื ื‘ื™ื ืืจื™ื™ื (ืงื•ืฉื—ื”) ืœื–ื™ื›ืจื•ืŸ ืฉืœ ืžื›ืฉื™ืจ ื•ื™ืจื˜ื•ืืœื™;
  • ื™ื›ื•ืœืช ืœืขื‘ื•ื“ ืขื ืชืฆืœื•ืžื™ ืžืฆื‘ (ืชืฆืœื•ืžื™ื ืฉืœ ืžืฆื‘ ื”ืžืขืจื›ืช);
  • ื”ื™ื›ื•ืœืช ืœื™ืฆื•ืจ ืื™ื ื˜ืจืืงืฆื™ื” ืขื ื”ืืžื•ืœื˜ื•ืจ ื‘ืืžืฆืขื•ืช ืžืืชืจ ื”ื‘ืื’ื™ื ื”ืžื•ื‘ื ื”;
  • ืฉืคื” ืžื•ื“ืจื ื™ืช ื ื—ืžื“ื” ืœื”ืชืคืชื—ื•ืช.

ื›ืชื•ืฆืื” ืžื›ืš, Kotlin ื ื‘ื—ืจ ืœื™ื™ืฉื•ื, ืืจื›ื™ื˜ืงื˜ื•ืจืช ื”ืื•ื˜ื•ื‘ื•ืก (ื–ื” ื›ืืฉืจ ืžื•ื“ื•ืœื™ื ืžืชืงืฉืจื™ื ื–ื” ืขื ื–ื” ื‘ืืžืฆืขื•ืช ืืคื™ืงื™ ื ืชื•ื ื™ื ื•ื™ืจื˜ื•ืืœื™ื™ื), JSON ื›ืคื•ืจืžื˜ ืชื™ืื•ืจ ื”ืžื›ืฉื™ืจ, ื•-GDB RSP ื›ืคืจื•ื˜ื•ืงื•ืœ ืœืื™ื ื˜ืจืืงืฆื™ื” ืขื ื”-debugger.

ื”ืคื™ืชื•ื— ื ืžืฉืš ืงืฆืช ื™ื•ืชืจ ืžืฉื ืชื™ื™ื ื•ื ืžืฉืš ื‘ืื•ืคืŸ ืคืขื™ืœ. ื‘ืžื”ืœืš ืชืงื•ืคื” ื–ื• ื™ื•ืฉืžื• ืœื™ื‘ื•ืช ืžืขื‘ื“ MIPS, x86, V850ES, ARM ื•-PowerPC.

ื”ืคืจื•ื™ืงื˜ ืฆื•ืžื— ื•ื”ื’ื™ืข ื”ื–ืžืŸ ืœื”ืฆื™ื’ ืื•ืชื• ืœืฆื™ื‘ื•ืจ ื”ืจื—ื‘. ืื ื• ื ืขืฉื” ืชื™ืื•ืจ ืžืคื•ืจื˜ ืฉืœ ื”ืคืจื•ื™ืงื˜ ืžืื•ื—ืจ ื™ื•ืชืจ, ืืš ืœืขืช ืขืชื” ื ืชืžืงื“ ื‘ืฉื™ืžื•ืฉ ื‘ืงื•ืคื™ืงืื˜.

ืขื‘ื•ืจ ื—ืกืจื™ ื”ืกื‘ืœื ื•ืช ื‘ื™ื•ืชืจ, ื ื™ืชืŸ ืœื”ื•ืจื™ื“ ื’ืจืกืช ืคืจื•ืžื• ืฉืœ ื”ืืžื•ืœื˜ื•ืจ ืงืฉืจ.

ืงืจื ืฃ ื‘ืืžื•ืœื˜ื•ืจ

ื”ื‘ื” ื ื–ื›ื™ืจ ื›ื™ ืžื•ืงื“ื ื™ื•ืชืจ ืขื‘ื•ืจ ื›ื ืก SMARTRHINO-2018, ื ื•ืฆืจ ืžื›ืฉื™ืจ ื‘ื“ื™ืงื” "ืงืจื ืฃ" ืœื”ื•ืจืืช ืžื™ื•ืžื ื•ื™ื•ืช ื”ื ื“ืกื” ื”ืคื•ื›ื”. ื”ืชื”ืœื™ืš ืฉืœ ื ื™ืชื•ื— ืงื•ืฉื—ื” ืกื˜ื˜ื™ ืชื•ืืจ ื‘ ืžืืžืจ ื–ื”.

ื›ืขืช ื ื ืกื” ืœื”ื•ืกื™ืฃ "ืจืžืงื•ืœื™ื" ื•ืœื”ืคืขื™ืœ ืืช ื”ืงื•ืฉื—ื” ื‘ืืžื•ืœื˜ื•ืจ.

ืื ื—ื ื• ืฆืจื™ื›ื™ื:
1) Java 1.8
2) ืคื™ื™ืชื•ืŸ ื•ืžื•ื“ื•ืœ ื’'ืค ืœื”ืฉืชืžืฉ ื‘-Python ื‘ืชื•ืš ื”ืืžื•ืœื˜ื•ืจ. ืืชื” ื™ื›ื•ืœ ืœื‘ื ื•ืช ืืช ืžื•ื“ื•ืœ WHL Jep ืขื‘ื•ืจ Windows ื”ื•ืจื“ ื›ืืŸ.

ืขื‘ื•ืจ Windows:
1) com0com
2) ืžืจืง

ืขื‘ื•ืจ ืœื™ื ื•ืงืก:
1) socat

ืืชื” ื™ื›ื•ืœ ืœื”ืฉืชืžืฉ ื‘-Eclipse, IDA Pro ืื• radare2 ื›ืœืงื•ื— GDB.

ืื™ืš ื–ื” ืขื•ื‘ื“?

ืขืœ ืžื ืช ืœื‘ืฆืข ืงื•ืฉื—ื” ื‘ืืžื•ืœื˜ื•ืจ, ื™ืฉ ืฆื•ืจืš "ืœื”ืจื›ื™ื‘" ืžื›ืฉื™ืจ ื•ื™ืจื˜ื•ืืœื™, ืฉื”ื•ื ืื ืœื•ื’ื™ ืœืžื›ืฉื™ืจ ืืžื™ืชื™.

ื ื™ืชืŸ ืœื”ืฆื™ื’ ืืช ื”ืžื›ืฉื™ืจ ื”ืืžื™ืชื™ ("ืงืจื ืฃ") ื‘ืชืจืฉื™ื ื”ื‘ืœื•ืง:

ืงืจื ืฃ ื‘ืชื•ืš ื—ืชื•ืœ - ื”ืคืขืœ ืืช ื”ืงื•ืฉื—ื” ื‘ืืžื•ืœื˜ื•ืจ 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"]
  ]
}

ืฉื™ืžื• ืœื‘ ืœืคืจืžื˜ืจ ื”ืงื•ืฉื—ื” ืกืขื™ืฃ params ื”ื•ื ืฉื ืฉืœ ืงื•ื‘ืฅ ืฉื ื™ืชืŸ ืœื˜ืขื•ืŸ ืœืžื›ืฉื™ืจ ื•ื™ืจื˜ื•ืืœื™ ื‘ืชื•ืจ ืงื•ืฉื—ื”.

ื ื™ืชืŸ ืœื™ื™ืฆื’ ืืช ื”ืžื›ืฉื™ืจ ื”ื•ื™ืจื˜ื•ืืœื™ ื•ื”ืื™ื ื˜ืจืืงืฆื™ื” ืฉืœื• ืขื ืžืขืจื›ืช ื”ื”ืคืขืœื” ื”ืจืืฉื™ืช ื‘ืืžืฆืขื•ืช ื”ื“ื™ืื’ืจืžื” ื”ื‘ืื”:

ืงืจื ืฃ ื‘ืชื•ืš ื—ืชื•ืœ - ื”ืคืขืœ ืืช ื”ืงื•ืฉื—ื” ื‘ืืžื•ืœื˜ื•ืจ Kopycat

ืžื•ืคืข ื”ื‘ื“ื™ืงื” ื”ื ื•ื›ื—ื™ ืฉืœ ื”ืืžื•ืœื˜ื•ืจ ื›ื•ืœืœ ืื™ื ื˜ืจืืงืฆื™ื” ืขื ื™ืฆื™ืื•ืช ื”-COM ืฉืœ ืžืขืจื›ืช ื”ื”ืคืขืœื” ื”ืจืืฉื™ืช (ื ื™ืคื•ื™ ื‘ืื’ื™ื ื‘-UART ื•-UART ืขื‘ื•ืจ ืžื•ื“ื•ืœ ื”-Bluetooth). ืืœื• ื™ื›ื•ืœื•ืช ืœื”ื™ื•ืช ื™ืฆื™ืื•ืช ืืžื™ืชื™ื•ืช ืฉืืœื™ื”ืŸ ืžื—ื•ื‘ืจื™ื ื”ืชืงื ื™ื ืื• ื™ืฆื™ืื•ืช COM ื•ื™ืจื˜ื•ืืœื™ื•ืช (ื‘ืฉื‘ื™ืœ ื–ื” ืืชื” ืจืง ืฆืจื™ืš com0com/socat).

ื›ื“ื™ ืœื™ืฆื•ืจ ืื™ื ื˜ืจืืงืฆื™ื” ืขื ื”ืืžื•ืœื˜ื•ืจ ืžื‘ื—ื•ืฅ, ื™ืฉ ื›ืจื’ืข ืฉืชื™ ื“ืจื›ื™ื ืขื™ืงืจื™ื•ืช:

  • ืคืจื•ื˜ื•ืงื•ืœ GDB RSP (ื‘ื”ืชืื, ื”ื›ืœื™ื ื”ืชื•ืžื›ื™ื ื‘ืคืจื•ื˜ื•ืงื•ืœ ื–ื” ื”ื Eclipse / IDA / radare2);
  • ืฉื•ืจืช ื”ืคืงื•ื“ื” ื”ืคื ื™ืžื™ืช ืฉืœ ืืžื•ืœื˜ื•ืจ (Argparse ืื• Python).

ื™ืฆื™ืื•ืช COM ื•ื™ืจื˜ื•ืืœื™ื•ืช

ืขืœ ืžื ืช ืœื™ืฆื•ืจ ืื™ื ื˜ืจืืงืฆื™ื” ืขื UART ืฉืœ ืžื›ืฉื™ืจ ื•ื™ืจื˜ื•ืืœื™ ื‘ืžื—ืฉื‘ ื”ืžืงื•ืžื™ ื‘ืืžืฆืขื•ืช ืžืกื•ืฃ, ืขืœื™ืš ืœื™ืฆื•ืจ ื–ื•ื’ ื™ืฆื™ืื•ืช COM ื•ื™ืจื˜ื•ืืœื™ื•ืช ืžืฉื•ื™ื›ื•ืช. ื‘ืžืงืจื” ืฉืœื ื•, ื™ืฆื™ืื” ืื—ืช ืžืฉืžืฉืช ืืช ื”ืืžื•ืœื˜ื•ืจ, ื•ื”ืฉื ื™ื™ื” ืขืœ ื™ื“ื™ ืชื•ื›ื ื™ืช ืžืกื•ืฃ (PuTTY ืื• ืžืกืš):

ืงืจื ืฃ ื‘ืชื•ืš ื—ืชื•ืœ - ื”ืคืขืœ ืืช ื”ืงื•ืฉื—ื” ื‘ืืžื•ืœื˜ื•ืจ Kopycat

ืฉื™ืžื•ืฉ ื‘-com0com

ื™ืฆื™ืื•ืช COM ื•ื™ืจื˜ื•ืืœื™ื•ืช ืžื•ื’ื“ืจื•ืช ื‘ืืžืฆืขื•ืช ืชื•ื›ื ื™ืช ื”ืฉื™ืจื•ืช ืœื”ื’ื“ืจื” ืžื”ืขืจื›ืช com0com (ื’ืจืกืช ื”ืžืกื•ืฃ - C:Program Files (x86)com0comsetupั.exe, ืื• ื’ืจืกืช GUI - C:Program Files (x86)com0comsetupg.exe):

ืงืจื ืฃ ื‘ืชื•ืš ื—ืชื•ืœ - ื”ืคืขืœ ืืช ื”ืงื•ืฉื—ื” ื‘ืืžื•ืœื˜ื•ืจ Kopycat

ืกืžืŸ ืืช ื”ืชื™ื‘ื•ืช ืืคืฉืจ ื”ืฆืคืช ืžืื’ืจ ืขื‘ื•ืจ ื›ืœ ื”ื™ืฆื™ืื•ืช ื”ื•ื™ืจื˜ื•ืืœื™ื•ืช ืฉื ื•ืฆืจื•, ืื—ืจืช ื”ืืžื•ืœื˜ื•ืจ ื™ืžืชื™ืŸ ืœืชื’ื•ื‘ื” ืžื™ืฆื™ืืช ื”-COM.

ื‘ืืžืฆืขื•ืช socat

ื‘ืžืขืจื›ื•ืช UNIX, ื™ืฆื™ืื•ืช COM ื•ื™ืจื˜ื•ืืœื™ื•ืช ื ื•ืฆืจื•ืช ืื•ื˜ื•ืžื˜ื™ืช ืขืœ ื™ื“ื™ ื”ืืžื•ืœื˜ื•ืจ ื‘ืืžืฆืขื•ืช ื›ืœื™ ื”ืฉื™ืจื•ืช socat; ืœืฉื ื›ืš, ืคืฉื•ื˜ ืฆื™ื™ืŸ ืืช ื”ืงื™ื“ื•ืžืช ื‘ืฉื ื”ื™ืฆื™ืื” ื‘ืขืช ื”ืคืขืœืช ื”ืืžื•ืœื˜ื•ืจ socat:.

ืžืžืฉืง ืฉื•ืจืช ืคืงื•ื“ื” ืคื ื™ืžื™ (Argparse ืื• Python)

ืžื›ื™ื•ื•ืŸ ืฉืงื•ืคื™ืงื˜ ื”ื•ื ื™ื™ืฉื•ื ืžืกื•ืฃ, ื”ืืžื•ืœื˜ื•ืจ ืžืกืคืง ืฉืชื™ ืืคืฉืจื•ื™ื•ืช ืžืžืฉืง ืฉื•ืจืช ืคืงื•ื“ื” ืœืื™ื ื˜ืจืืงืฆื™ื” ืขื ื”ืื•ื‘ื™ื™ืงื˜ื™ื ื•ื”ืžืฉืชื ื™ื ืฉืœื•: Argparse ื•-Python.

Argparse ื”ื•ื CLI ืžื•ื‘ื ื” ื‘ืงื•ืคื™ืงืื˜ ื•ื–ืžื™ืŸ ืชืžื™ื“ ืœื›ื•ืœื.

CLI ื—ืœื•ืคื™ ื”ื•ื ืžืชื•ืจื’ืžืŸ Python. ื›ื“ื™ ืœื”ืฉืชืžืฉ ื‘ื•, ืขืœื™ืš ืœื”ืชืงื™ืŸ ืืช ืžื•ื“ื•ืœ Jep Python ื•ืœื”ื’ื“ื™ืจ ืืช ื”ืืžื•ืœื˜ื•ืจ ืœืขื‘ื•ื“ ืขื 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.

ื‘ืงื•ื‘ืฅ ื”ืืฆื•ื•ื” ืฉืœ ื”ืืžื•ืœื˜ื•ืจ ืขื‘ื•ืจ ื”ืžืขืจื›ืช ืฉืœืš (copycat.bat - ืขื‘ื•ืจ Windows, ืขื•ืชืง - ืขื‘ื•ืจ ืœื™ื ื•ืงืก) ืœืจืฉื™ืžืช ื”ืคืจืžื˜ืจื™ื 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

ืคืงื•ื“ื” ืœื”ืคืขืœื” ืชื—ืช ืœื™ื ื•ืงืก ื‘ืืžืฆืขื•ืช ื›ืœื™ ื”ืฉื™ืจื•ืช 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

ื›ื“ื™ ืœืคืฉื˜ ืืช ื”ื‘ื“ื™ืงื•ืช, ืื ื• ืžืฉืชืžืฉื™ื ื‘ืงื•ืฉื—ื” ืฉืœ Rhino ื›ืงื•ื‘ืฅ ื”ืžืงื•ืจ ืœื ื™ืชื•ื— ื‘-IDA ื‘ื˜ื•ืคืก ืงื•ื‘ืฅ ELF (ืžื™ื“ืข ืžื˜ื ืžืื•ื—ืกืŸ ืฉื).

ืืชื” ื™ื›ื•ืœ ื’ื ืœื”ืฉืชืžืฉ ื‘ืงื•ืฉื—ื” ื”ืจืืฉื™ืช ืœืœื ืžื˜ื ืžื™ื“ืข.

ืœืื—ืจ ื”ืฉืงืช Kopycat ื‘-IDA Pro, ื‘ืชืคืจื™ื˜ Debugger ืขื‘ื•ืจ ืืœ ื”ืคืจื™ื˜ "ื”ื—ืœืฃ ืžืืชืจ ื‘ืื’ื™ื..." ื•ื‘ื—ืจ "ืžืืชืจ ื‘ืื’ื™ื ืžืจื•ื—ืง ืฉืœ GDB". ืœืื—ืจ ืžื›ืŸ, ื”ื’ื“ืจ ืืช ืชืคืจื™ื˜ ื”ื—ื™ื‘ื•ืจ: ืžืืชืจ ื‘ืื’ื™ื - ืืคืฉืจื•ื™ื•ืช ืชื”ืœื™ืš...

ื”ื’ื“ืจ ืืช ื”ืขืจื›ื™ื:

  • ื™ื™ืฉื•ื - ื›ืœ ืขืจืš
  • ืฉื ืžืืจื—: 127.0.0.1 (ืื• ื›ืชื•ื‘ืช ื”-IP ืฉืœ ื”ืžื—ืฉื‘ ื”ืžืจื•ื—ืง ืฉื‘ื• ืคื•ืขืœ Kopycat)
  • ื‘ื ืžืœ: 23946

ืงืจื ืฃ ื‘ืชื•ืš ื—ืชื•ืœ - ื”ืคืขืœ ืืช ื”ืงื•ืฉื—ื” ื‘ืืžื•ืœื˜ื•ืจ Kopycat

ื›ืขืช ื›ืคืชื•ืจ ืื™ืชื•ืจ ื”ื‘ืื’ื™ื ื”ื•ืคืš ืœื–ืžื™ืŸ (ืžืงืฉ F9):

ืงืจื ืฃ ื‘ืชื•ืš ื—ืชื•ืœ - ื”ืคืขืœ ืืช ื”ืงื•ืฉื—ื” ื‘ืืžื•ืœื˜ื•ืจ Kopycat

ืœื—ืฅ ืขืœื™ื• ื›ื“ื™ ืœื”ืชื—ื‘ืจ ืœืžื•ื“ื•ืœ ื ื™ืคื•ื™ ื”ื‘ืื’ื™ื ื‘ืืžื•ืœื˜ื•ืจ. IDA ื ื›ื ืก ืœืžืฆื‘ ืื™ืชื•ืจ ื‘ืื’ื™ื, ื—ืœื•ื ื•ืช ื ื•ืกืคื™ื ื”ื•ืคื›ื™ื ืœื–ืžื™ื ื™ื: ืžื™ื“ืข ืขืœ ืื•ื’ืจื™ื, ืขืœ ื”ืžื—ืกื ื™ืช.

ื›ืขืช ื ื•ื›ืœ ืœื”ืฉืชืžืฉ ื‘ื›ืœ ื”ืชื›ื•ื ื•ืช ื”ืกื˜ื ื“ืจื˜ื™ื•ืช ืฉืœ ืžืืชืจ ื”ื‘ืื’ื™ื:

  • ื‘ื™ืฆื•ืข ืฆืขื“ ืื—ืจ ืฆืขื“ ืฉืœ ื”ื•ืจืื•ืช (ืœื”ื›ื ืก ืœืชื•ืš ะธ ืœื“ืจื•ืš ืžืขืœ - ืžืคืชื—ื•ืช F7 ื•- F8, ื‘ื”ืชืืžื”);
  • ื”ืชื—ืœื” ื•ื”ืฉื”ื™ื™ืช ื‘ื™ืฆื•ืข;
  • ื™ืฆื™ืจืช ื ืงื•ื“ื•ืช ืฉื‘ื™ืจื” ื”ืŸ ืขื‘ื•ืจ ืงื•ื“ ื•ื”ืŸ ืขื‘ื•ืจ ื ืชื•ื ื™ื (ืžืงืฉ F2).

ื—ื™ื‘ื•ืจ ืœ-debugger ืœื ืื•ืžืจ ืœื”ืคืขื™ืœ ืืช ืงื•ื“ ื”ืงื•ืฉื—ื”. ืขืžื“ืช ื”ื‘ื™ืฆื•ืข ื”ื ื•ื›ื—ื™ืช ื—ื™ื™ื‘ืช ืœื”ื™ื•ืช ื”ื›ืชื•ื‘ืช 0x08006A74 - ืชื—ื™ืœืช ื”ืคื•ื ืงืฆื™ื” Reset_Handler. ืื ืชื’ืœื•ืœ ืœืžื˜ื” ื‘ืจื™ืฉื•ื, ืชื•ื›ืœ ืœืจืื•ืช ืืช ืฉื™ื—ืช ื”ืคื•ื ืงืฆื™ื” ืจืืฉื™. ืืชื” ื™ื›ื•ืœ ืœืžืงื ืืช ื”ืกืžืŸ ืขืœ ืฉื•ืจื” ื–ื• (ื›ืชื•ื‘ืช 0x08006ABE) ื•ืœื‘ืฆืข ืืช ื”ืคืขื•ืœื” ื”ืคืขืœ ืขื“ ื”ืกืžืŸ (ืžืงืฉ F4).

ืงืจื ืฃ ื‘ืชื•ืš ื—ืชื•ืœ - ื”ืคืขืœ ืืช ื”ืงื•ืฉื—ื” ื‘ืืžื•ืœื˜ื•ืจ Kopycat

ืœืื—ืจ ืžื›ืŸ, ืชื•ื›ืœ ืœืœื—ื•ืฅ ืขืœ F7 ื›ื“ื™ ืœื”ื™ื›ื ืก ืœืคื•ื ืงืฆื™ื” ืจืืฉื™.

ืื ืชืคืขื™ืœ ืืช ื”ืคืงื•ื“ื” ื”ืžืฉืš ื‘ืชื”ืœื™ืš (ืžืงืฉ F9), ื•ืื– ื™ื•ืคื™ืข ื—ืœื•ืŸ "ื ื ื”ืžืชืŸ" ืขื ื›ืคืชื•ืจ ื‘ื•ื“ื“ ืœื”ืฉืขื•ืช:

ืงืจื ืฃ ื‘ืชื•ืš ื—ืชื•ืœ - ื”ืคืขืœ ืืช ื”ืงื•ืฉื—ื” ื‘ืืžื•ืœื˜ื•ืจ Kopycat

ื›ืฉืืชื” ืœื•ื—ืฅ ืœื”ืฉืขื•ืช ื‘ื™ืฆื•ืข ืงื•ื“ ื”ืงื•ืฉื—ื” ืžื•ืฉืขื” ื•ื ื™ืชืŸ ืœื”ืžืฉื™ืš ืื•ืชื” ืžืื•ืชื” ื›ืชื•ื‘ืช ื‘ืงื•ื“ ืฉื‘ื” ื”ื•ื ื”ื•ืคืกืง.

ืื ืชืžืฉื™ืš ื‘ื‘ื™ืฆื•ืข ื”ืงื•ื“, ืชืจืื” ืืช ื”ืฉื•ืจื•ืช ื”ื‘ืื•ืช ื‘ืžืกื•ืคื™ื ื”ืžื—ื•ื‘ืจื™ื ืœื™ืฆื™ืื•ืช ื”-COM ื”ื•ื™ืจื˜ื•ืืœื™ื•ืช:

ืงืจื ืฃ ื‘ืชื•ืš ื—ืชื•ืœ - ื”ืคืขืœ ืืช ื”ืงื•ืฉื—ื” ื‘ืืžื•ืœื˜ื•ืจ Kopycat

ืงืจื ืฃ ื‘ืชื•ืš ื—ืชื•ืœ - ื”ืคืขืœ ืืช ื”ืงื•ืฉื—ื” ื‘ืืžื•ืœื˜ื•ืจ Kopycat

ื”ื ื•ื›ื—ื•ืช ืฉืœ ืงื• "ืขืงื™ืคืช ื”ืžื“ื™ื ื”" ืžืฆื‘ื™ืขื” ืขืœ ื›ืš ืฉืžื•ื“ื•ืœ ื”-Bluetooth ื”ื•ื™ืจื˜ื•ืืœื™ ืขื‘ืจ ืœืžืฆื‘ ืฉืœ ืงื‘ืœืช ื ืชื•ื ื™ื ืžื™ืฆื™ืืช ื”-COM ืฉืœ ื”ืžืฉืชืžืฉ.

ื›ืขืช ื‘ืžืกื•ืฃ ื‘ืœื•ื˜ื•ืช' (COM29 ื‘ืชืžื•ื ื”) ื ื™ืชืŸ ืœื”ื–ื™ืŸ ืคืงื•ื“ื•ืช ื‘ื”ืชืื ืœืคืจื•ื˜ื•ืงื•ืœ Rhino. ืœื“ื•ื’ืžื”, ื”ืคืงื•ื“ื” "MEOW" ืชื—ื–ื™ืจ ืืช ื”ืžื—ืจื•ื–ืช "mur-mur" ืœืžืกื•ืฃ ื”-Bluetooth:

ืงืจื ืฃ ื‘ืชื•ืš ื—ืชื•ืœ - ื”ืคืขืœ ืืช ื”ืงื•ืฉื—ื” ื‘ืืžื•ืœื˜ื•ืจ Kopycat

ืชื—ืงื• ืื•ืชื™ ืœื ืœื’ืžืจื™

ื‘ืขืช ื‘ื ื™ื™ืช ืืžื•ืœื˜ื•ืจ, ื ื™ืชืŸ ืœื‘ื—ื•ืจ ืืช ืจืžืช ื”ืคื™ืจื•ื˜/ื”ื“ืžื™ื™ื” ืฉืœ ืžื›ืฉื™ืจ ืžืกื•ื™ื. ืœื“ื•ื’ืžื”, ื ื™ืชืŸ ืœื—ืงื•ืช ืืช ืžื•ื“ื•ืœ ื”-Bluetooth ื‘ื“ืจื›ื™ื ืฉื•ื ื•ืช:

  • ื”ืžื›ืฉื™ืจ ืžื—ื•ืœืง ื‘ืžืœื•ืื• ืขื ืงื‘ื•ืฆื” ืžืœืื” ืฉืœ ืคืงื•ื“ื•ืช;
  • ืคืงื•ื“ื•ืช AT ืžื—ื•ืงื•ืช, ื•ื–ืจื ื”ื ืชื•ื ื™ื ืžืชืงื‘ืœ ืžื™ืฆื™ืืช ื”-COM ืฉืœ ื”ืžืขืจื›ืช ื”ืจืืฉื™ืช;
  • ื”ืžื›ืฉื™ืจ ื”ื•ื™ืจื˜ื•ืืœื™ ืžืกืคืง ื”ืคื ื™ื™ืช ื ืชื•ื ื™ื ืžืœืื” ืœืžื›ืฉื™ืจ ื”ืืžื™ืชื™;
  • ื‘ืชื•ืจ ื‘ื“ืœ ืคืฉื•ื˜ ืฉืชืžื™ื“ ืžื—ื–ื™ืจ "ื‘ืกื“ืจ".

ื”ื’ืจืกื” ื”ื ื•ื›ื—ื™ืช ืฉืœ ื”ืืžื•ืœื˜ื•ืจ ืžืฉืชืžืฉืช ื‘ื’ื™ืฉื” ื”ืฉื ื™ื™ื” - ืžื•ื“ื•ืœ ื”-Bluetooth ื”ื•ื™ืจื˜ื•ืืœื™ ืžื‘ืฆืข ืชืฆื•ืจื”, ื•ืœืื—ืจ ืžื›ืŸ ื”ื•ื ืขื•ื‘ืจ ืœืžืฆื‘ ืฉืœ "ืคืจื•ืงืกื™" ื ืชื•ื ื™ื ืžื™ืฆื™ืืช ื”-COM ืฉืœ ื”ืžืขืจื›ืช ื”ืจืืฉื™ืช ืœื™ืฆื™ืืช UART ืฉืœ ื”ืืžื•ืœื˜ื•ืจ.

ืงืจื ืฃ ื‘ืชื•ืš ื—ืชื•ืœ - ื”ืคืขืœ ืืช ื”ืงื•ืฉื—ื” ื‘ืืžื•ืœื˜ื•ืจ Kopycat

ื‘ื•ืื• ื ืฉืงื•ืœ ืืช ื”ืืคืฉืจื•ืช ืฉืœ ืžื›ืฉื•ืจ ืคืฉื•ื˜ ืฉืœ ื”ืงื•ื“ ื‘ืžืงืจื” ืฉื—ืœืง ืžื”ืคืจื™ืคืจื™ื” ืœื ืžื™ื•ืฉื. ืœื“ื•ื’ืžื”, ืื ืœื ื ื•ืฆืจ ื˜ื™ื™ืžืจ ืฉืื—ืจืื™ ืขืœ ื‘ืงืจืช ื”ืขื‘ืจืช ื”ื ืชื•ื ื™ื ืœ-DMA (ื”ื‘ื“ื™ืงื” ืžืชื‘ืฆืขืช ื‘ืคื•ื ืงืฆื™ื” ws2812b_waitืžืžื•ืงื ื‘ 0x08006840), ืื– ื”ืงื•ืฉื—ื” ืชืžื™ื“ ืชื—ื›ื” ืœืื™ืคื•ืก ื”ื“ื’ืœ ืขืกื•ืงืžืžื•ืงื ื‘ 0x200004C4ืฉืžืจืื” ืืช ื”ืชืคื•ืกื” ืฉืœ ืงื• ื”ื ืชื•ื ื™ื ืฉืœ DMA:

ืงืจื ืฃ ื‘ืชื•ืš ื—ืชื•ืœ - ื”ืคืขืœ ืืช ื”ืงื•ืฉื—ื” ื‘ืืžื•ืœื˜ื•ืจ Kopycat

ื ื•ื›ืœ ืœืขืงื•ืฃ ืืช ื”ืžืฆื‘ ื”ื–ื” ืขืœ ื™ื“ื™ ืื™ืคื•ืก ื™ื“ื ื™ ืฉืœ ื”ื“ื’ืœ ืขืกื•ืง ืžื™ื“ ืœืื—ืจ ื”ืชืงื ืชื•. ื‘-IDA Pro ืืคืฉืจ ืœื™ืฆื•ืจ ืคื•ื ืงืฆื™ื™ืช Python ื•ืœืงืจื•ื ืœื” ื‘-breakpoint, ื•ืœืฉื™ื ืืช ื”-breakpoint ืขืฆืžื• ื‘ืงื•ื“ ืœืื—ืจ ื›ืชื™ื‘ืช ื”ืขืจืš 1 ืœื“ื’ืœ ืขืกื•ืง.

ืžื˜ืคืœ ื‘ื ืงื•ื“ืช ืฉื‘ื™ืจื”

ืจืืฉื™ืช, ื‘ื•ืื• ื ื™ืฆื•ืจ ืคื•ื ืงืฆื™ื™ืช Python ื‘-IDA. ืชึทืคืจึดื™ื˜ ืงื•ื‘ืฅ - ืคืงื•ื“ืช ืกืงืจื™ืคื˜...

ื”ื•ืกืฃ ืงื˜ืข ืงื•ื“ ื—ื“ืฉ ื‘ืจืฉื™ืžื” ืžืฉืžืืœ, ืชืŸ ืœื• ืฉื (ืœื“ื•ื’ืžื”, BPT),
ื‘ืฉื“ื” ื”ื˜ืงืกื˜ ื‘ืฆื“ ื™ืžื™ืŸ, ื”ื–ืŸ ืืช ืงื•ื“ ื”ืคื•ื ืงืฆื™ื”:

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

ืงืจื ืฃ ื‘ืชื•ืš ื—ืชื•ืœ - ื”ืคืขืœ ืืช ื”ืงื•ืฉื—ื” ื‘ืืžื•ืœื˜ื•ืจ Kopycat

ืื—ืจื™ ื–ื” ืื ื—ื ื• ืœื•ื—ืฆื™ื ื”ืคืขืœื” ื•ืกื’ื•ืจ ืืช ื—ืœื•ืŸ ื”ืกืงืจื™ืคื˜.

ื›ืขืช ื ืขื‘ื•ืจ ืœืงื•ื“ ื‘- 0x0800688A, ื”ื’ื“ืจ ื ืงื•ื“ืช ืขืฆื™ืจื” (ืžืงืฉ F2), ืขืจื•ืš ืื•ืชื” (ืชืคืจื™ื˜ ื”ื”ืงืฉืจ ืขืจื•ืš ื ืงื•ื“ืช ืขืฆื™ืจื”...), ืืœ ืชืฉื›ื— ืœื”ื’ื“ื™ืจ ืืช ืกื•ื’ ื”ืกืงืจื™ืคื˜ ืœืคื™ื™ืชื•ืŸ:

ืงืจื ืฃ ื‘ืชื•ืš ื—ืชื•ืœ - ื”ืคืขืœ ืืช ื”ืงื•ืฉื—ื” ื‘ืืžื•ืœื˜ื•ืจ Kopycat
ืงืจื ืฃ ื‘ืชื•ืš ื—ืชื•ืœ - ื”ืคืขืœ ืืช ื”ืงื•ืฉื—ื” ื‘ืืžื•ืœื˜ื•ืจ Kopycat

ืื ืขืจืš ื”ื“ื’ืœ ื”ื ื•ื›ื—ื™ ืขืกื•ืง ืฉื•ื•ื” ืœ-1, ืื– ืขืœื™ืš ืœื‘ืฆืข ืืช ื”ืคื•ื ืงืฆื™ื” skip_dma ื‘ืฉื•ืจืช ื”ืชืกืจื™ื˜:

ืงืจื ืฃ ื‘ืชื•ืš ื—ืชื•ืœ - ื”ืคืขืœ ืืช ื”ืงื•ืฉื—ื” ื‘ืืžื•ืœื˜ื•ืจ Kopycat

ืื ืืชื” ืžืคืขื™ืœ ืืช ื”ืงื•ืฉื—ื” ืœื‘ื™ืฆื•ืข, ื ื™ืชืŸ ืœืจืื•ืช ืืช ื”ื”ืคืขืœื” ืฉืœ ืงื•ื“ ื”ืžื˜ืคืœ ื‘ื ืงื•ื“ืช ื”ืคืกื™ืงื” ื‘ื—ืœื•ืŸ IDA ืชึฐืคื•ึผืงึธื” ืœืคื™ ืงื• Skipping wait ws2812.... ื›ืขืช ื”ืงื•ืฉื—ื” ืœื ืชื—ื›ื” ืœืื™ืคื•ืก ื”ื“ื’ืœ ืขืกื•ืง.

ืื™ื ื˜ืจืืงืฆื™ื” ืขื ื”ืืžื•ืœื˜ื•ืจ

ืœื ืกื‘ื™ืจ ืฉื”ืืžื•ืœืฆื™ื” ืœืฉื ื—ื™ืงื•ื™ ืชื’ืจื•ื ืœืขื•ื ื’ ื•ืฉืžื—ื”. ื–ื” ื”ืจื‘ื” ื™ื•ืชืจ ืžืขื ื™ื™ืŸ ืื ื”ืืžื•ืœื˜ื•ืจ ืขื•ื–ืจ ืœื—ื•ืงืจ ืœืจืื•ืช ืืช ื”ื ืชื•ื ื™ื ื‘ื–ื™ื›ืจื•ืŸ ืื• ืœื‘ืกืก ืืช ื”ืื™ื ื˜ืจืืงืฆื™ื” ืฉืœ ืฉืจืฉื•ืจื™ื.

ืื ื• ื ืจืื” ืœืš ื›ื™ืฆื“ ืœื™ืฆื•ืจ ืื™ื ื˜ืจืืงืฆื™ื” ื“ื™ื ืžื™ืช ื‘ื™ืŸ ืžืฉื™ืžื•ืช RTOS. ืชื—ื™ืœื” ืขืœื™ืš ืœื”ืฉื”ื•ืช ืืช ื‘ื™ืฆื•ืข ื”ืงื•ื“ ืื ื”ื•ื ืคื•ืขืœ. ืื ืืชื” ื”ื•ืœืš ืœืคื•ื ืงืฆื™ื” bluetooth_task_entry ืœืขื ืฃ ื”ืขื™ื‘ื•ื“ ืฉืœ ืคืงื•ื“ืช "LED" (ื›ืชื•ื‘ืช 0x080057B8), ื•ืื– ืชื•ื›ืœ ืœืจืื•ืช ืžื” ื ื•ืฆืจ ืœืจืืฉื•ื ื” ื•ืœืื—ืจ ืžื›ืŸ ื ืฉืœื— ืœืชื•ืจ ื”ืžืขืจื›ืช ledControlQueueHandle ื”ื•ื“ืขื” ื›ืœืฉื”ื™.

ืงืจื ืฃ ื‘ืชื•ืš ื—ืชื•ืœ - ื”ืคืขืœ ืืช ื”ืงื•ืฉื—ื” ื‘ืืžื•ืœื˜ื•ืจ Kopycat

ืขืœื™ืš ืœื”ื’ื“ื™ืจ ื ืงื•ื“ืช ืขืฆื™ืจื” ื›ื“ื™ ืœื’ืฉืช ืœืžืฉืชื ื” 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 ืฉืœ ื”ื—ื•ืžืจื” ื•ืขื ืคืจื™ืกืช ื”ื–ื™ื›ืจื•ืŸ; ื‘ื’ืœืœ ื–ื”, ื ืงื•ื“ื•ืช ื”ืฉื‘ื™ืจื” ื•ื”ืฉืœื‘ื™ื ืœื ืคื•ืขืœื™ื (ืคืงื•ื“ื” ds). ืื ื• ืžืงื•ื•ื™ื ืฉื–ื” ื™ืชื•ืงืŸ ื‘ืงืจื•ื‘.

ืจื™ืฆื” ืขื Eclipse

ืื—ืช ื”ืืคืฉืจื•ื™ื•ืช ืœืฉื™ืžื•ืฉ ื‘ืืžื•ืœื˜ื•ืจ ื”ื™ื ืื™ืชื•ืจ ื‘ืื’ื™ื ื‘ืงื•ืฉื—ื” ืฉืœ ื”ืžื›ืฉื™ืจ ื”ืžืคื•ืชื—. ืœืžืขืŸ ื”ื‘ื”ื™ืจื•ืช, ื ืฉืชืžืฉ ื’ื ื‘ืงื•ืฉื—ื” ืฉืœ Rhino. ืืชื” ื™ื›ื•ืœ ืœื”ื•ืจื™ื“ ืืช ืžืงื•ืจื•ืช ื”ืงื•ืฉื—ื” ืžื›ืืŸ.

ื ืฉืชืžืฉ ื‘-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 ืืชื” ืฆืจื™ืš ืœื”ื•ืกื™ืฃ ืชืฆื•ืจื” ื—ื“ืฉื”, ื•ืœืื—ืจ ืžื›ืŸ ื‘ื›ืจื˜ื™ืกื™ื™ื” "ืจืืฉื™" ืฆื™ื™ืŸ ืืช ื”ืคืจื•ื™ืงื˜ ื”ื ื•ื›ื—ื™ ื•ืืช ื”ื™ื™ืฉื•ื ืœืื™ืชื•ืจ ื‘ืื’ื™ื:

ืงืจื ืฃ ื‘ืชื•ืš ื—ืชื•ืœ - ื”ืคืขืœ ืืช ื”ืงื•ืฉื—ื” ื‘ืืžื•ืœื˜ื•ืจ Kopycat

ื‘ื›ืจื˜ื™ืกื™ื™ื” "Debugger" ืขืœื™ืš ืœืฆื™ื™ืŸ ืืช ืคืงื•ื“ืช GDB:
${openstm32_compiler_path}arm-none-eabi-gdb

ื•ื’ื ื”ื–ืŸ ืืช ื”ืคืจืžื˜ืจื™ื ืœื—ื™ื‘ื•ืจ ืœืฉืจืช GDB (ืžืืจื— ื•ื™ืฆื™ืื”):

ืงืจื ืฃ ื‘ืชื•ืš ื—ืชื•ืœ - ื”ืคืขืœ ืืช ื”ืงื•ืฉื—ื” ื‘ืืžื•ืœื˜ื•ืจ Kopycat

ื‘ื›ืจื˜ื™ืกื™ื™ื” "ืืชื—ื•ืœ", ืขืœื™ืš ืœืฆื™ื™ืŸ ืืช ื”ืคืจืžื˜ืจื™ื ื”ื‘ืื™ื:

  • ืชื™ื‘ืช ืกื™ืžื•ืŸ ืืคืฉืจ ื˜ืขืŸ ืชืžื•ื ื” (ื›ืš ืฉืชืžื•ื ืช ื”ืงื•ืฉื—ื” ื”ืžื•ืจื›ื‘ืช ืชื™ื˜ืขืŸ ืœืืžื•ืœื˜ื•ืจ);
  • ืชื™ื‘ืช ืกื™ืžื•ืŸ ืืคืฉืจ ื˜ืขืŸ ืกืžืœื™ื;
  • ื”ื•ืกืฃ ืคืงื•ื“ืช ื”ืคืขืœื”: set $pc = *0x08000004 (ื”ื’ื“ืจ ืืช ืื•ื’ืจ ื”ืžื—ืฉื‘ ืœืขืจืš ืžื”ื–ื™ื›ืจื•ืŸ ื‘ื›ืชื•ื‘ืช 0x08000004 - ื”ื›ืชื•ื‘ืช ืžืื•ื—ืกื ืช ืฉื ResetHandler).

ืฉื™ื ืœื‘, ืื ืื™ื ืš ืจื•ืฆื” ืœื”ื•ืจื™ื“ ืืช ืงื•ื‘ืฅ ื”ืงื•ืฉื—ื” ืžืืงืœื™ืคืก, ืื– ื”ืืคืฉืจื•ื™ื•ืช ื˜ืขืŸ ืชืžื•ื ื” ะธ ื”ืคืขืœ ืคืงื•ื“ื•ืช ืื™ืŸ ืฆื•ืจืš ืœืฆื™ื™ืŸ.

ืงืจื ืฃ ื‘ืชื•ืš ื—ืชื•ืœ - ื”ืคืขืœ ืืช ื”ืงื•ืฉื—ื” ื‘ืืžื•ืœื˜ื•ืจ Kopycat

ืœืื—ืจ ืœื—ื™ืฆื” ืขืœ ืื™ืชื•ืจ ื‘ืื’ื™ื, ืชื•ื›ืœ ืœืขื‘ื•ื“ ื‘ืžืฆื‘ ื ื™ืคื•ื™ ื‘ืื’ื™ื:

  • ื‘ื™ืฆื•ืข ืงื•ื“ ืฆืขื“ ืื—ืจ ืฆืขื“
    ืงืจื ืฃ ื‘ืชื•ืš ื—ืชื•ืœ - ื”ืคืขืœ ืืช ื”ืงื•ืฉื—ื” ื‘ืืžื•ืœื˜ื•ืจ Kopycat
  • ืื™ื ื˜ืจืืงืฆื™ื” ืขื ื ืงื•ื“ื•ืช ืฉื‘ื™ืจื”
    ืงืจื ืฃ ื‘ืชื•ืš ื—ืชื•ืœ - ื”ืคืขืœ ืืช ื”ืงื•ืฉื—ื” ื‘ืืžื•ืœื˜ื•ืจ Kopycat

ืฉื™ื ืœื‘. ืœืœื™ืงื•ื™ ื™ืฉ, ื”ืžืž... ื›ืžื” ืžื•ื–ืจื•ื™ื•ืช... ื•ืืชื” ืฆืจื™ืš ืœื—ื™ื•ืช ืื™ืชื. ืœื“ื•ื’ืžื”, ืื ื‘ืขืช ื”ืคืขืœืช ืžืืชืจ ื”ื‘ืื’ื™ื ืžื•ืคื™ืขื” ื”ื”ื•ื“ืขื” "ืื™ืŸ ืžืงื•ืจ ื–ืžื™ืŸ ืขื‘ื•ืจ "0x0", ืื– ื‘ืฆืข ืืช ื”ืคืงื•ื“ื” Step (F5)

ืงืจื ืฃ ื‘ืชื•ืš ื—ืชื•ืœ - ื”ืคืขืœ ืืช ื”ืงื•ืฉื—ื” ื‘ืืžื•ืœื˜ื•ืจ Kopycat

ื‘ืžืงื•ื ืžืกืงื ื”

ืืžื•ืœืฆื™ื” ืฉืœ ืงื•ื“ ืžืงื•ืจื™ ื”ื•ื ื“ื‘ืจ ืžืื•ื“ ืžืขื ื™ื™ืŸ. ื–ื” ื”ื•ืคืš ืœื”ื™ื•ืช ืืคืฉืจื™ ืขื‘ื•ืจ ืžืคืชื— ืžื›ืฉื™ืจื™ื ืœื ืคื•ืช ื‘ืื’ื™ื ื‘ืงื•ืฉื—ื” ืœืœื ืžื›ืฉื™ืจ ืืžื™ืชื™. ืขื‘ื•ืจ ื—ื•ืงืจ, ื–ื• ื”ื–ื“ืžื ื•ืช ืœื‘ืฆืข ื ื™ืชื•ื— ืงื•ื“ ื“ื™ื ืžื™, ืžื” ืฉืœื ืชืžื™ื“ ืืคืฉืจื™ ืืคื™ืœื• ืขื ืžื›ืฉื™ืจ.

ืื ื• ืจื•ืฆื™ื ืœืกืคืง ืœืžื•ืžื—ื™ื ื›ืœื™ ื ื•ื—, ืคืฉื•ื˜ ื‘ืžื™ื“ื” ื•ืœื ืœื•ืงื— ื”ืจื‘ื” ืžืืžืฅ ื•ื–ืžืŸ ืœื”ืชืงื™ืŸ ื•ืœื”ืคืขื™ืœ.

ื›ืชื•ื‘ ื‘ื”ืขืจื•ืช ืขืœ ื”ื—ื•ื•ื™ื” ืฉืœืš ื‘ืฉื™ืžื•ืฉ ื‘ืืžื•ืœื˜ื•ืจื™ื ืฉืœ ื—ื•ืžืจื”. ืื ื• ืžื–ืžื™ื ื™ื ืืชื›ื ืœื“ื•ืŸ ื•ื ืฉืžื— ืœืขื ื•ืช ืขืœ ืฉืืœื•ืช.

ืจืง ืžืฉืชืžืฉื™ื ืจืฉื•ืžื™ื ื™ื›ื•ืœื™ื ืœื”ืฉืชืชืฃ ื‘ืกืงืจ. ืœื”ืชื—ื‘ืจื‘ื‘ืงืฉื”.

ื‘ืฉื‘ื™ืœ ืžื” ืืชื” ืžืฉืชืžืฉ ื‘ืืžื•ืœื˜ื•ืจ?

  • ืื ื™ ืžืคืชื— (ื‘ืื’ื™ื) ืงื•ืฉื—ื”

  • ืื ื™ ื—ื•ืงืจ ืงื•ืฉื—ื”

  • ืื ื™ ืžืฉื™ืง ืžืฉื—ืงื™ื (Dendi, Sega, PSP)

  • ืžืฉื”ื• ืื—ืจ (ื›ืชื•ื‘ ื‘ืชื’ื•ื‘ื•ืช)

7 ืžืฉืชืžืฉื™ื ื”ืฆื‘ื™ืขื•. 2 ืžืฉืชืžืฉื™ื ื ืžื ืขื•.

ื‘ืื™ื–ื• ืชื•ื›ื ื” ืืชื” ืžืฉืชืžืฉ ื›ื“ื™ ืœื—ืงื•ืช ืงื•ื“ ืžืงื•ืจื™?

  • QEMU

  • ืžื ื•ืข ื—ื“ ืงืจืŸ

  • ืคืจื•ื˜ืื•ืก

  • ืžืฉื”ื• ืื—ืจ (ื›ืชื•ื‘ ื‘ืชื’ื•ื‘ื•ืช)

6 ืžืฉืชืžืฉื™ื ื”ืฆื‘ื™ืขื•. 2 ืžืฉืชืžืฉื™ื ื ืžื ืขื•.

ืžื” ืชืจืฆื” ืœืฉืคืจ ื‘ืืžื•ืœื˜ื•ืจ ืฉื‘ื• ืืชื” ืžืฉืชืžืฉ?

  • ืื ื™ ืจื•ืฆื” ืžื”ื™ืจื•ืช

  • ืื ื™ ืจื•ืฆื” ืงืœื•ืช ื”ืชืงื ื”/ื”ืฉืงื”

  • ืื ื™ ืจื•ืฆื” ืืคืฉืจื•ื™ื•ืช ื ื•ืกืคื•ืช ืœืื™ื ื˜ืจืืงืฆื™ื” ืขื ื”ืืžื•ืœื˜ื•ืจ (API, hooks)

  • ืื ื™ ืžืจื•ืฆื” ืžื”ื›ืœ

  • ืžืฉื”ื• ืื—ืจ (ื›ืชื•ื‘ ื‘ืชื’ื•ื‘ื•ืช)

8 ืžืฉืชืžืฉื™ื ื”ืฆื‘ื™ืขื•. ืžืฉืชืžืฉ ืื—ื“ ื ืžื ืข.

ืžืงื•ืจ: www.habr.com

ื”ื•ืกืคืช ืชื’ื•ื‘ื”