├── README.md ├── button.sh ├── button_setup.sh ├── hidnet.sh ├── hidonly.sh └── string2hid.c /README.md: -------------------------------------------------------------------------------- 1 | # hidemulation 2 | 3 | ## hid gadget: 4 | 5 | string2hid : takes a string and "types it" using /dev/hidgX (should work on any device that offers a usb hid gadget) 6 | 7 | ## usbarmory specifics: 8 | 9 | hidonly.sh : switches the usbarmory to be usb hid gadget 10 | 11 | hidnet.sh : switches the usbarmory to be a usb hid and usb ethernet gadget 12 | 13 | button_setup.sh : switches pin 3 and 4 to in and out 14 | 15 | button.sh : checks if pin 3 and 4 are connected 16 | -------------------------------------------------------------------------------- /button.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # Collin Mulliner 5 | # 6 | 7 | echo out > /sys/class/gpio/gpio154/direction 8 | echo in > /sys/class/gpio/gpio155/direction 9 | echo 1 > /sys/class/gpio/gpio154/value 10 | 11 | value=1 12 | counter=0 13 | while [ $value -eq "1" ]; do 14 | echo 0 > /sys/class/gpio/gpio154/value 15 | value=`cat /sys/class/gpio/gpio155/value` 16 | if [ "${value}" == "0" ]; then 17 | #echo "button press" 18 | exit 0 19 | break 20 | #else 21 | # echo "." 22 | fi 23 | sleep 1; 24 | counter=$((counter + 1)) 25 | if [ $counter -eq 10 ]; then 26 | #echo "button expired" 27 | break 28 | fi 29 | done 30 | exit 1 31 | -------------------------------------------------------------------------------- /button_setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # Collin Mulliner 5 | # 6 | 7 | echo 154 > /sys/class/gpio/export 8 | echo out > /sys/class/gpio/gpio154/direction 9 | chmod 666 /sys/class/gpio/gpio154/direction 10 | chmod 666 /sys/class/gpio/gpio154/value 11 | 12 | echo 155 > /sys/class/gpio/export 13 | echo in > /sys/class/gpio/gpio155/direction 14 | chmod 666 /sys/class/gpio/gpio155/direction 15 | chmod 666 /sys/class/gpio/gpio155/value 16 | -------------------------------------------------------------------------------- /hidnet.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # Collin Mulliner 5 | # 6 | 7 | modprobe -r g_ether usb_f_ecm u_ether 8 | modprobe usb_f_hid 9 | modprobe usb_f_ecm 10 | 11 | cd /sys/kernel/config/ 12 | mkdir usb_gadget/g1 13 | cd usb_gadget/g1 14 | mkdir configs/c.1 15 | mkdir functions/hid.usb0 16 | mkdir functions/ecm.usb0 17 | echo 1 > functions/hid.usb0/protocol 18 | echo 1 > functions/hid.usb0/subclass 19 | echo 8 > functions/hid.usb0/report_length 20 | 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 21 | mkdir strings/0x409 22 | mkdir configs/c.1/strings/0x409 23 | echo 0x1d6b > idVendor # Linux Foundation 24 | echo 0x0104 > idProduct # Multifunction Composite Gadget 25 | echo 0x0100 > bcdDevice # v1.0.0 26 | echo 0x0200 > bcdUSB # USB2 27 | echo "deadbeef9876543210" > strings/0x409/serialnumber 28 | echo "USBArmory" > strings/0x409/manufacturer 29 | echo "USBArmory Network + Keyboard" > strings/0x409/product 30 | echo "Conf1" > configs/c.1/strings/0x409/configuration 31 | echo 120 > configs/c.1/MaxPower 32 | ln -s functions/hid.usb0 configs/c.1/ 33 | ln -s functions/ecm.usb0 configs/c.1/ 34 | echo ci_hdrc.0 > UDC 35 | -------------------------------------------------------------------------------- /hidonly.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # Collin Mulliner 5 | # 6 | 7 | modprobe -r g_ether usb_f_ecm u_ether 8 | modprobe usb_f_hid 9 | 10 | cd /sys/kernel/config/ 11 | mkdir usb_gadget/g1 12 | cd usb_gadget/g1 13 | mkdir configs/c.1 14 | mkdir functions/hid.usb0 15 | echo 1 > functions/hid.usb0/protocol 16 | echo 1 > functions/hid.usb0/subclass 17 | echo 8 > functions/hid.usb0/report_length 18 | 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 19 | mkdir strings/0x409 20 | mkdir configs/c.1/strings/0x409 21 | echo 0x6240 > idProduct 22 | echo 0x046d > idVendor 23 | echo 0x0100 > bcdDevice # v1.0.0 24 | echo 0x0200 > bcdUSB # USB2 25 | echo "fedcba9876543210" > strings/0x409/serialnumber 26 | echo "Logitech" > strings/0x409/manufacturer 27 | echo "Keyboard" > strings/0x409/product 28 | echo "Conf1" > configs/c.1/strings/0x409/configuration 29 | echo 120 > configs/c.1/MaxPower 30 | ln -s functions/hid.usb0 configs/c.1 31 | echo ci_hdrc.0 > UDC 32 | -------------------------------------------------------------------------------- /string2hid.c: -------------------------------------------------------------------------------- 1 | /* 2 | * string 2 hid event 3 | * 4 | * program will take a string and generate HID events for each character 5 | * HID events will be written to /dev/hidg0 (can be changed via argument 2) 6 | * 7 | * note: \ needs to be escaped with \\ 8 | * enter key can be produced via \n 9 | * ctrl, alt, tab, backspace, esc, delete, win, shift via: c,a,t,b,e,d,g,s 10 | * delay input by 1 second via \- 11 | * 12 | * multiple keys at the same time: 13 | * enclose the key sequnce (upto 6) in escaped double quotes (\") 14 | * 15 | * examples: 16 | * string2hid abc123 17 | * will type abc123 18 | * string2hid "ls -la\n" 19 | * will type ls -la (and press enter) 20 | * string2hid "bla*" /dev/hidg1 21 | * will type bla* using /dev/hidg1 (default is hidg0) 22 | * string2hid "\\\"\a\t\\\"" 23 | * will press alt + tab 24 | * string2hid "\\\"\af\\\"\-\-test\n" 25 | * will press alt + f sleep for 2 seconds and type "test" + enter 26 | * 27 | * 28 | * Collin Mulliner (collin AT mulliner.org) 29 | * http://www.mulliner.org/ 30 | * 31 | * license: GPLv3 32 | * 33 | */ 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | 44 | struct key_t { 45 | char k; 46 | char c; 47 | char mod; 48 | }; 49 | 50 | static struct key_t keys_num[] = { 51 | {.k = '0', .c = 0x27, .mod=0x00}, 52 | {.k = '1', .c = 0x1e, .mod=0x00}, 53 | {.k = '2', .c = 0x1f, .mod=0x00}, 54 | {.k = '3', .c = 0x20, .mod=0x00}, 55 | {.k = '4', .c = 0x21, .mod=0x00}, 56 | {.k = '5', .c = 0x22, .mod=0x00}, 57 | {.k = '6', .c = 0x23, .mod=0x00}, 58 | {.k = '7', .c = 0x24, .mod=0x00}, 59 | {.k = '8', .c = 0x25, .mod=0x00}, 60 | {.k = '9', .c = 0x26, .mod=0x00}, 61 | }; 62 | 63 | static struct key_t keys_special[] = { 64 | {.k = '!', .c = 0x1e, .mod=0x20}, 65 | {.k = '@', .c = 0x1f, .mod=0x20}, 66 | {.k = '#', .c = 0x20, .mod=0x20}, 67 | {.k = '$', .c = 0x21, .mod=0x20}, 68 | {.k = '%', .c = 0x22, .mod=0x20}, 69 | {.k = '^', .c = 0x23, .mod=0x20}, 70 | {.k = '&', .c = 0x24, .mod=0x20}, 71 | {.k = '*', .c = 0x25, .mod=0x20}, 72 | {.k = '(', .c = 0x26, .mod=0x20}, 73 | {.k = ')', .c = 0x27, .mod=0x20}, 74 | {.k = '-', .c = 0x2d, .mod=0x00}, 75 | {.k = '_', .c = 0x2d, .mod=0x20}, 76 | {.k = '+', .c = 0x2e, .mod=0x20}, 77 | {.k = '=', .c = 0x2e, .mod=0x00}, 78 | {.k = '[', .c = 0x2f, .mod=0x00}, 79 | {.k = '{', .c = 0x2f, .mod=0x20}, 80 | {.k = ']', .c = 0x30, .mod=0x00}, 81 | {.k = '}', .c = 0x30, .mod=0x20}, 82 | {.k = '\\', .c = 0x31, .mod=0x00}, 83 | {.k = '|', .c = 0x31, .mod=0x20}, 84 | {.k = ';', .c = 0x33, .mod=0x00}, 85 | {.k = ':', .c = 0x33, .mod=0x20}, 86 | {.k = '\'', .c = 0x34, .mod=0x00}, 87 | {.k = '"', .c = 0x34, .mod=0x20}, 88 | {.k = ',', .c = 0x36, .mod=0x00}, 89 | {.k = '<', .c = 0x36, .mod=0x20}, 90 | {.k = '.', .c = 0x37, .mod=0x00}, 91 | {.k = '>', .c = 0x37, .mod=0x20}, 92 | {.k = '/', .c = 0x38, .mod=0x00}, 93 | {.k = '?', .c = 0x38, .mod=0x20}, 94 | {.k = '`', .c = 0x35, .mod=0x00}, 95 | {.k = '~', .c = 0x35, .mod=0x20}, 96 | {.k = ' ', .c = 0x2c, .mod=0x00}, 97 | {.k = 'n', .c = 0x28, .mod=0x00}, // enter 98 | {.k = 'c', .c = 0x00, .mod=0x01}, // ctrl 99 | {.k = 's', .c = 0x00, .mod=0x02}, // shift 100 | {.k = 'a', .c = 0x00, .mod=0x04}, // alt 101 | {.k = 'g', .c = 0x00, .mod=0x08}, // gui/win 102 | {.k = 't', .c = 0x2B, .mod=0x00}, // tab 103 | {.k = 'd', .c = 0x4C, .mod=0x00}, // delete 104 | {.k = 'b', .c = 0x2A, .mod=0x00}, // backspace 105 | {.k = 'e', .c = 0x29, .mod=0x00}, // esc 106 | {.k = 0, .c = 0x00, .mod=0x00} 107 | }; 108 | 109 | int char2event(char *report, char *input_chars, int input_length) 110 | { 111 | memset(report, 0x00, 8); 112 | char input; 113 | int index = 2; 114 | int ic; 115 | 116 | for (ic = 0; ic < input_length; ic++) { 117 | input = input_chars[ic]; 118 | char lower = tolower(input); 119 | if (lower >= 'a' && lower <= 'z') { 120 | report[index] = lower - ('a' - 4); 121 | index++; 122 | if (lower != input) { 123 | report[0] = 0x22; 124 | } 125 | } 126 | else if (lower >= '0' && lower <= '9') { 127 | report[index] = keys_num[lower - '0'].c; 128 | index++; 129 | } 130 | else { 131 | int i; 132 | if (input == '\\') { 133 | ic++; 134 | input = input_chars[ic]; 135 | } 136 | for (i = 0; i < sizeof(keys_special); i++) { 137 | if (input == keys_special[i].k) { 138 | if (keys_special[i].c != 0) { 139 | report[index] = keys_special[i].c; 140 | } 141 | report[0] |= keys_special[i].mod; 142 | index++; 143 | break; 144 | } 145 | if (keys_special[i].k == 0) 146 | break; 147 | } 148 | } 149 | if (report[2] == 0 && report[0] == 0) { 150 | printf("error for >%c<\n", input); 151 | return 0; 152 | } 153 | } 154 | 155 | return 1; 156 | } 157 | 158 | int main(int argc, char **argv) 159 | { 160 | char report[8]; 161 | int fd = -1; 162 | 163 | if (argc <= 1) { 164 | printf("syntax: %s [/dev/hidgX] (\\ needs to be escaped with a \\, enter key is produced via \\n)\n", argv[0]); 165 | return 0; 166 | } 167 | 168 | //printf("string >%s<\n", argv[1]); 169 | 170 | char *filename = "/dev/hidg0"; 171 | 172 | if (argc > 2) 173 | filename = argv[2]; 174 | 175 | if ((fd = open(filename, O_RDWR, 0666)) == -1) { 176 | perror(filename); 177 | return 3; 178 | } 179 | 180 | int i; 181 | //printf("input = %s\n", argv[1]); 182 | for (i = 0; i < strlen(argv[1]); i++) { 183 | if (argv[1][i] == '\\') { 184 | i++; 185 | if (argv[1][i] == '-') { 186 | sleep(1); 187 | continue; 188 | } 189 | else if (argv[1][i] == '"') { 190 | int m = i + 1; 191 | int ml = 0; 192 | while (1) { 193 | if (argv[1][m + ml] == '\\') { 194 | printf("bs\n"); 195 | if (argv[1][m + ml + 1] == '"') { 196 | break; 197 | } 198 | } 199 | ml++; 200 | } 201 | char2event(report, &argv[1][m], ml); 202 | i = i + ml + 2; 203 | } 204 | else { 205 | char2event(report, &argv[1][i-1], 2); 206 | } 207 | } 208 | else { 209 | char2event(report, &argv[1][i], 1); 210 | } 211 | //printf("%0.2x %0.2x\n", report[0], report[2]); 212 | // send key 213 | if (write(fd, report, 8) != 8) { 214 | perror(filename); 215 | return 2; 216 | } 217 | // clear key ... no key pressed after 218 | memset(report, 0x0, sizeof(report)); 219 | if (write(fd, report, 8) != 8) { 220 | perror(filename); 221 | return 4; 222 | } 223 | } 224 | 225 | close(fd); 226 | } 227 | --------------------------------------------------------------------------------