Если вы хотите эмулировать при помощи Pi Zero сетевой адаптер, клавиатуру, накопитель и все прочее, причем одновременно — все это можно сделать. На помощь приходит LibComposite, правда, в этом случае нужно помнить, что под Windows решения нет, способ подходит только для Linux или Mac OS X. Детальное описание действий пользователя для достижения результата, описанного в заголовке — в продолжении (источник).

Шаг 0 — конфигурируем SD карту


Скачиваем и устанавливаем последний дистрибутив Raspbian Jessie на подходящую SD карту (должна быть достаточно емкой), и увеличиваем корневой раздел.

Шаг 1 — Ядро


Нужно использовать Kernel 4.4, который не идет по умолчанию с дистрибутивом Rasbian. Но обновиться достаточно легко, нужно лишь выполнить вот эту консольную команду:

sudo BRANCH=next rpi-update

После этого выполняем вот что:

echo «dtoverlay=dwc2» | sudo tee -a /boot/config.txt
echo «dwc2» | sudo tee -a /etc/modules


И, наконец, активируем драйвер libcomposite:

sudo echo «libcomposite» | sudo tee -a /etc/modules

Шаг 2 — конфигурируем устройства


Теперь нужно определиться с тем, какое устройство эмулировать — сетевую карту, клавиатуру, или все это вместе?

Настраиваем это при помощи ConfigFS, виртуальной файловой системе в /sys/. Она автоматически монтируется при старте «малинки», поэтому в дальнейшем можно с ней работать.
Есть отличный пример для девайса, названного USBArmory, пример этот здесь. На базе него будет показываться и все остальное.

Создаем конфигурационный скрипт

Запускать его придется при каждом старте устройства. Создаем файл isticktoit_usb in /usr/bin/, используя любимый текстовый редактор. Пишем вот, что:
sudo touch /usr/bin/isticktoit_usb #create the file
sudo chmod +x /usr/bin/isticktoit_usb #make it executable
sudo nano /usr/bin/isticktoit_usb #edit the file


После этого скрипт необходимо запускать автоматически на старте. Для лучшей производительности, можно создать systemd unit файл, но пока обойдемся rc.local. (это часть старой системы sysvinit, но она выполняется на raspberry pi по умолчанию).

Открываем под рутом /etc/rc.local и добавляем такую строчку (перед!!!) строкой, содержащей слово «exit»:

sudo nano /etc/rc.local
/etc/rc.local…
/usr/bin/isticktoit_usb # libcomposite configuration
exit


Создаем гаджет

Это глобальная конфигурация, поэтому все равно, сколько USB гаджетов вы хотели бы задействовать. Можете менять серийный номер, производителя и название продукта в этом блоке.

/usr/bin/isticktoit_usbcd /sys/kernel/config/usb_gadget/
mkdir -p isticktoit
cd isticktoit
echo 0x1d6b > idVendor # Linux Foundation
echo 0x0104 > idProduct # Multifunction Composite Gadget
echo 0x0100 > bcdDevice # v1.0.0
echo 0x0200 > bcdUSB # USB2
mkdir -p strings/0x409
echo «fedcba9876543210» > strings/0x409/serialnumber
echo «Tobias Girstmair» > strings/0x409/manufacturer
echo «iSticktoit.net USB Device» > strings/0x409/product
mkdir -p configs/c.1/strings/0x409
echo «Config 1: ECM network» > configs/c.1/strings/0x409/configuration
echo 250 > configs/c.1/MaxPower
# Add functions here
# see gadget configurations below
# End functions
ls /sys/class/udc > UDC


Ethernet адаптер

Прежде всего, давайте добавим вот что в наш конфигурационный файл:

sudo nano /usr/bin/isticktoit_usb
/usr/bin/isticktoit_usb# Add functions here
mkdir -p functions/ecm.usb0
# first byte of address must be even
HOST=«48:6f:73:74:50:43» # «HostPC»
SELF=«42:61:64:55:53:42» # «BadUSB»
echo $HOST > functions/ecm.usb0/host_addr
echo $SELF > functions/ecm.usb0/dev_addr
ln -s functions/ecm.usb0 configs/c.1/
# End functions
ls /sys/class/udc > UDC
#put this at the very end of the file:
ifconfig $N 10.0.0.1 netmask 255.255.255.252 up
route add -net default gw 10.0.0.2


Сохраняем и выходим, затем переходим к host PC:
Если есть проблемы с автоматическим подключением, отключаемся и выполняем вот, что:

dmesg|grep cdc_ether
[13890.668557] cdc_ether 1-1:1.2 eth0: register 'cdc_ether' at usb-0000:00:14.0-1, CDC Ethernet Device, 48:6f:73:74:50:43
[13890.674117] usbcore: registered new interface driver cdc_ether
[13890.687619] cdc_ether 1-1:1.2 enp0s20u1i2: renamed from eth0


Переименовать адаптер можно и после, пока же назовем его enp0s20u1i2

sudo ifconfig enp0s20u1i2 10.0.0.2 netmask 255.255.255.252 up

И подключаемся через ssh к PI:

ssh 10.0.0.1 -l pi

Клавиатура, мышь, джойстик (HID)

sudo nano /usr/bin/isticktoit_usb
/usr/bin/isticktoit_usb# Add functions here
mkdir -p functions/hid.usb0
echo 1 > functions/hid.0/protocol
echo 1 > functions/hid.0/subclass
echo 8 > functions/hid.0/report_length
echo -ne \\x05\\x01\\x09\\x06\\xa1\\x01\\x05\\x07\\x19\\xe0\\x29\\xe7\\x15\\x00\\x25\\x01\\x75\\x01\\x95\\x08\\x81\\x02\\x95\\x01\\x75\\x08\\x81\\x03\\x95\\x05\\x75\\x01\\x05\\x08\\x19\\x01\\x29\\x05\\x91\\x02\\x95\\x01\\x75\\x03\\x91\\x03\\x95\\x06\\x75\\x08\\x15\\x00\\x25\\x65\\x05\\x07\\x19\\x00\\x29\\x65\\x81\\x00\\xc0 > functions/hid.0/report_desc
ln -s functions/hid.usb0 configs/c.1/
# End functions


Вот самый простой способ отправить нажатие кнопок клавиатуры в файл девайса:
echo "\0\0\x4\0\0\0\0\0" > /dev/hidg0 #press the A-button
echo "\0\0\0\0\0\0\0\0" > /dev/hidg0 #release all keys


Но это не самый практичный способ, поэтому стоит воспользоваться вот этим примером, и загрузить его на свой ПК. Затем извлекаем его на SD карту «малинки» и запускаем.

На Pi:
cd PATH_TO_HARDPASS_REPO
make #compile the program
echo -n «hello world!» | sudo ./scan /dev/hidg0 1 2


Здесь ‚1‘ означает американскую раскладку клавиатуры, а «2» — немецко-австрийскую. второй номер нужен для ввода символов, которых нет на вашей клавиатуре (2=Linux, 3=Windows (правда, нет драйверов под эту ОС)).

Накопитель

Это сделать сложнее. Вы можете использовать только файл образа диска. В примере создается очень небольшой файл образа диска для сохранения конфигурации ethernet хоста.
Для начала давайте сделаем диск. Это довольно длительный процесс, туториал здесь.
Затем снова переходим к конфигурации:

sudo nano /usr/bin/isticktoit_usb
/usr/bin/isticktoit_usb# Add functions here
FILE=/home/pi/usbdisk.img
mkdir -p ${FILE/img/d}
mount -o loop,ro,offset=1048576 -t ext4 $FILE ${FILE/img/d}
mkdir -p functions/mass_storage.usb0
echo 1 > functions/mass_storage.usb0/stall
echo 0 > functions/mass_storage.usb0/lun.0/cdrom
echo 0 > functions/mass_storage.usb0/lun.0/ro
echo 0 > functions/mass_storage.usb0/lun.0/nofua
echo $FILE > functions/mass_storage.usb0/lun.0/file
ln -s functions/mass_storage.usb0 configs/c.1/
# End functions

После этого должен быть доступен сьемный диск в FAT32 формате, который будет показан после следующего подключения Pi к основному ПК. Для получения доступа к файлам, сохраненным на Pi, можно выполнить unmount и затем переподключить его еще где-то.

Что еще?



Всего есть около 20 USB гаджетов, которые могут быть эмулированы ядром Linux. Вот здесь больше информации об этом!

Полезные ссылки:
Tutorial by gbaman
libcomposite in the Kernel documentation
–> hardpass – PiZero project (Keyboad emulation) < — USBArmory Wiki Page

Комментарии (13)


  1. lolipop
    27.02.2016 17:56

    Это я еще на n900 так делал.


  1. vblats
    27.02.2016 18:56

    Хм. А где фотки и видео процесса?
    Интересно посмотреть как marks шлет коды нажатий через USB-порт с малинки на домашний комп.


  1. ifaustrue
    27.02.2016 20:20

    Умеет эмулировать WiFi адаптер?


  1. theendcomplete
    27.02.2016 21:26
    +1

    шаг 0 — найти Pi Zero в наличии и за адекватные деньги)


    1. t3sc0
      29.02.2016 15:51

      зашёл сюда в надежде увидеть ссылки со статусом "in stock" :)


      1. theendcomplete
        01.03.2016 10:25

        да, я тоже очень на это надеялся(


  1. FianlQ
    27.02.2016 21:26

    Клавиатура, мышь, джойстик (HID)
    А одновременно, с одного порта можно настроить и мышь и клавиатуру?


  1. DigitalSpirit
    27.02.2016 21:26

    А IDE или SATA устройство через GPIO на нём можно cэмулировать?
    Виртуальный IDE CDROM был бы полезен для старых машин без загрузки с USB


  1. BubaVV
    27.02.2016 23:12

    А есть ли способ подключить к нему ноутбучную клавиатуру без контроллера?


  1. LexS007
    28.02.2016 14:17

    Спасибо. Полезная статья.


  1. Uranium
    29.02.2016 17:17

    А как физически делается подключение? Неужели через GPIO? Или, может, у этой версии малинки порт питания может работать как USB device port?


    1. Uranium
      29.02.2016 17:54

      Все, я сам нашел ответ на вопрос: https://www.raspberrypi.org/forums/viewtopic.php?f=29&t=129653


  1. kav4ik
    29.02.2016 22:02

    А можно ли с помощью данного решения сделать что нибудь подобное Zalman VE300?