16
16
#define SCRIPT_STATE_END (-2)
17
17
#define SCRIPT_STATE_NEXT_LINE (-3)
18
18
19
+ #define BADUSB_ASCII_TO_KEY (script , x ) \
20
+ (((uint8_t)x < 128) ? (script->layout[(uint8_t)x]) : HID_KEYBOARD_NONE)
21
+
19
22
typedef enum {
20
23
WorkerEvtToggle = (1 << 0 ),
21
24
WorkerEvtEnd = (1 << 1 ),
@@ -28,6 +31,7 @@ struct BadUsbScript {
28
31
BadUsbState st ;
29
32
string_t file_path ;
30
33
uint32_t defdelay ;
34
+ uint16_t layout [128 ];
31
35
FuriThread * thread ;
32
36
uint8_t file_buf [FILE_BUFFER_LEN + 1 ];
33
37
uint8_t buf_start ;
@@ -203,10 +207,10 @@ static bool ducky_altstring(const char* param) {
203
207
return state ;
204
208
}
205
209
206
- static bool ducky_string (const char * param ) {
210
+ static bool ducky_string (BadUsbScript * bad_usb , const char * param ) {
207
211
uint32_t i = 0 ;
208
212
while (param [i ] != '\0' ) {
209
- uint16_t keycode = HID_ASCII_TO_KEY ( param [i ]);
213
+ uint16_t keycode = BADUSB_ASCII_TO_KEY ( bad_usb , param [i ]);
210
214
if (keycode != HID_KEYBOARD_NONE ) {
211
215
furi_hal_hid_kb_press (keycode );
212
216
furi_hal_hid_kb_release (keycode );
@@ -216,7 +220,7 @@ static bool ducky_string(const char* param) {
216
220
return true;
217
221
}
218
222
219
- static uint16_t ducky_get_keycode (const char * param , bool accept_chars ) {
223
+ static uint16_t ducky_get_keycode (BadUsbScript * bad_usb , const char * param , bool accept_chars ) {
220
224
for (uint8_t i = 0 ; i < (sizeof (ducky_keys ) / sizeof (ducky_keys [0 ])); i ++ ) {
221
225
uint8_t key_cmd_len = strlen (ducky_keys [i ].name );
222
226
if ((strncmp (param , ducky_keys [i ].name , key_cmd_len ) == 0 ) &&
@@ -225,7 +229,7 @@ static uint16_t ducky_get_keycode(const char* param, bool accept_chars) {
225
229
}
226
230
}
227
231
if ((accept_chars ) && (strlen (param ) > 0 )) {
228
- return (HID_ASCII_TO_KEY ( param [0 ]) & 0xFF );
232
+ return (BADUSB_ASCII_TO_KEY ( bad_usb , param [0 ]) & 0xFF );
229
233
}
230
234
return 0 ;
231
235
}
@@ -271,7 +275,7 @@ static int32_t ducky_parse_line(BadUsbScript* bad_usb, string_t line) {
271
275
} else if (strncmp (line_tmp , ducky_cmd_string , strlen (ducky_cmd_string )) == 0 ) {
272
276
// STRING
273
277
line_tmp = & line_tmp [ducky_get_command_len (line_tmp ) + 1 ];
274
- state = ducky_string (line_tmp );
278
+ state = ducky_string (bad_usb , line_tmp );
275
279
return (state ) ? (0 ) : SCRIPT_STATE_ERROR ;
276
280
} else if (strncmp (line_tmp , ducky_cmd_altchar , strlen (ducky_cmd_altchar )) == 0 ) {
277
281
// ALTCHAR
@@ -294,12 +298,12 @@ static int32_t ducky_parse_line(BadUsbScript* bad_usb, string_t line) {
294
298
return (state ) ? (0 ) : SCRIPT_STATE_ERROR ;
295
299
} else {
296
300
// Special keys + modifiers
297
- uint16_t key = ducky_get_keycode (line_tmp , false);
301
+ uint16_t key = ducky_get_keycode (bad_usb , line_tmp , false);
298
302
if (key == HID_KEYBOARD_NONE ) return SCRIPT_STATE_ERROR ;
299
303
if ((key & 0xFF00 ) != 0 ) {
300
304
// It's a modifier key
301
305
line_tmp = & line_tmp [ducky_get_command_len (line_tmp ) + 1 ];
302
- key |= ducky_get_keycode (line_tmp , true);
306
+ key |= ducky_get_keycode (bad_usb , line_tmp , true);
303
307
}
304
308
furi_hal_hid_kb_press (key );
305
309
furi_hal_hid_kb_release (key );
@@ -585,12 +589,19 @@ static int32_t bad_usb_worker(void* context) {
585
589
return 0 ;
586
590
}
587
591
592
+ static void bad_usb_script_set_default_keyboard_layout (BadUsbScript * bad_usb ) {
593
+ furi_assert (bad_usb );
594
+ memset (bad_usb -> layout , HID_KEYBOARD_NONE , sizeof (bad_usb -> layout ));
595
+ memcpy (bad_usb -> layout , hid_asciimap , MIN (sizeof (hid_asciimap ), sizeof (bad_usb -> layout )));
596
+ }
597
+
588
598
BadUsbScript * bad_usb_script_open (string_t file_path ) {
589
599
furi_assert (file_path );
590
600
591
601
BadUsbScript * bad_usb = malloc (sizeof (BadUsbScript ));
592
602
string_init (bad_usb -> file_path );
593
603
string_set (bad_usb -> file_path , file_path );
604
+ bad_usb_script_set_default_keyboard_layout (bad_usb );
594
605
595
606
bad_usb -> st .state = BadUsbStateInit ;
596
607
@@ -613,6 +624,30 @@ void bad_usb_script_close(BadUsbScript* bad_usb) {
613
624
free (bad_usb );
614
625
}
615
626
627
+ void bad_usb_script_set_keyboard_layout (BadUsbScript * bad_usb , string_t layout_path ) {
628
+ furi_assert (bad_usb );
629
+
630
+ if ((bad_usb -> st .state == BadUsbStateRunning ) || (bad_usb -> st .state == BadUsbStateDelay )) {
631
+ // do not update keyboard layout while a script is running
632
+ return ;
633
+ }
634
+
635
+ File * layout_file = storage_file_alloc (furi_record_open (RECORD_STORAGE ));
636
+ if (!string_empty_p (layout_path )) {
637
+ if (storage_file_open (
638
+ layout_file , string_get_cstr (layout_path ), FSAM_READ , FSOM_OPEN_EXISTING )) {
639
+ uint16_t layout [128 ];
640
+ if (storage_file_read (layout_file , layout , sizeof (layout )) == sizeof (layout )) {
641
+ memcpy (bad_usb -> layout , layout , sizeof (layout ));
642
+ }
643
+ }
644
+ storage_file_close (layout_file );
645
+ } else {
646
+ bad_usb_script_set_default_keyboard_layout (bad_usb );
647
+ }
648
+ storage_file_free (layout_file );
649
+ }
650
+
616
651
void bad_usb_script_toggle (BadUsbScript * bad_usb ) {
617
652
furi_assert (bad_usb );
618
653
furi_thread_flags_set (furi_thread_get_id (bad_usb -> thread ), WorkerEvtToggle );
0 commit comments