bash-scripts/usbgadget.sh
2023-12-31 10:55:53 -07:00

143 lines
4.3 KiB
Bash

#!/bin/bash -e
set -x
#set -euo pipefail
GADGET_NAME="g1"
LANGUAGE="0x409" # English
CONFIGFS="/sys/kernel/config/usb_gadget/"
ID_VENDOR="0x1d6b"
ID_PRODUCT="0x0104"
SERIAL="$(grep Serial /proc/cpuinfo | sed 's/Serial\s*: 0000\(\w*\)/\1/')"
MAC="$(echo ${SERIAL} | sed 's/\(\w\w\)/:\1/g' | cut -b 2-)"
MAC_HOST="12$(echo ${MAC} | cut -b 3-)"
MAC_DEV="02$(echo ${MAC} | cut -b 3-)"
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root"
exit 1
fi
if [ ! -d $CONFIGFS ]; then
modprobe libcomposite
fi
# Enter ConfigFS
cd $CONFIGFS
# Cleaning
#echo "Cleaning up existing gadget"
#echo "Stopping getty"
#systemctl stop getty@ttyGS0.service
#echo "Removing config-level functions"
find ./$GADGET_NAME/configs/*/* -maxdepth 0 -type l -exec rm {} \; || true
#echo "Removing config-level strings"
find ./$GADGET_NAME/configs/*/strings/* -maxdepth 0 -type d -exec rmdir {} \; || true
#echo "Removing config-level OS descriptors"
find ./$GADGET_NAME/os_desc/* -maxdepth 0 -type l -exec rm {} \; || true
#echo "Removing gadget-level functions"
find ./$GADGET_NAME/functions/* -maxdepth 0 -type d -exec rmdir {} \; || true
#echo "Removing gadget-level strings"
find ./$GADGET_NAME/strings/* -maxdepth 0 -type d -exec rmdir {} \; || true
#echo "Removing gadget-level configs"
find ./$GADGET_NAME/configs/* -maxdepth 0 -type d -exec rmdir {} \; || true
#echo "Removing gadget"
rmdir ./$GADGET_NAME || true
#echo "Starting getty"
#systemctl start getty@ttyGS0.service
mkdir ./$GADGET_NAME && cd ./$GADGET_NAME
# Basic info
echo $ID_VENDOR > idVendor # Linux Foundation
echo $ID_PRODUCT > idProduct # Multifunction Composite Gadget
echo 0x0100 > bcdDevice # v1.0.0
echo 0x0200 > bcdUSB # USB 2.0
#echo "Configuring gadget as composite device"
# https://msdn.microsoft.com/en-us/library/windows/hardware/ff540054(v=vs.85).aspx
echo 0xEF > bDeviceClass
echo 0x02 > bDeviceSubClass
echo 0x01 > bDeviceProtocol
#echo "Configuring OS descriptors"
# https://msdn.microsoft.com/en-us/library/hh881271.aspx
# OS descriptors
# WIndows extensions to force config
echo 1 > os_desc/use
echo 0xcd > os_desc/b_vendor_code
echo MSFT100 > os_desc/qw_sign
mkdir -p strings/$LANGUAGE
echo "7777777" > strings/$LANGUAGE/serialnumber
echo "eXander" > strings/$LANGUAGE/manufacturer
echo "exander's Gadget" > strings/$LANGUAGE/product
# Config #1 for OSX / Linux
mkdir -p configs/c.1/strings/$LANGUAGE
echo 250 > configs/c.1/MaxPower
echo "Config 1" > configs/c.1/strings/$LANGUAGE/configuration
mkdir -p functions/acm.usb0 # serial
mkdir -p functions/rndis.usb0 # network Flippin' Windows
#mkdir -p functions/ecm.usb0 # OSX / Linux
mkdir -p functions/hid.usb0 # keyboard
# https://msdn.microsoft.com/en-us/windows/hardware/gg463179.aspx
echo RNDIS > functions/rndis.usb0/os_desc/interface.rndis/compatible_id
echo 5162001 > functions/rndis.usb0/os_desc/interface.rndis/sub_compatible_id
echo $MAC_HOST > functions/rndis.usb0/host_addr
echo $MAC_DEV > functions/rndis.usb0/dev_addr
#echo $MAC_HOST > functions/ecm.usb0/host_addr
#echo $MAC_DEV > functions/ecm.usb0/dev_addr
# Set up the rndis device only first
ln -s functions/rndis.usb0 configs/c.1
# Tell Windows to use config #2
ln -s configs/c.1 os_desc
#ln -s configs/c.1 os_desc/c.1
# Show Windows the RNDIS device with
# bDeviceClass 0x02
# bDeviceSubClass 0x02
ls /sys/class/udc/ > UDC
# Give it time to install
sleep 5
# Yank it back
echo "" > UDC
# Setup keyboard
echo 1 > functions/hid.usb0/protocol
echo 1 > functions/hid.usb0/subclass
echo 8 > functions/hid.usb0/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.usb0/report_desc
ln -s functions/acm.usb0 configs/c.1/
#ln -s functions/ecm.usb0 configs/c.1/
ln -s functions/hid.usb0 configs/c.1/
# Reset bDeviceClass to 0x00
# This is essential to make it work in Windows 10
# Basically forces it to use device information
# in the descriptors versus assuming a particular class.
echo "0x00" > bDeviceClass
# Re-attach the gadget
udevadm settle -t 5 || :
ls /sys/class/udc/ > UDC
# BOOM!