From 74f6ee1e7ceac5d2405cb00c64928d4c55296c03 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Mon, 7 Jul 2025 17:55:14 +0300 Subject: [PATCH] badusb fix modifier keys with HOLD/RELEASE commands by WillyJL --- CHANGELOG.md | 1 + applications/main/bad_usb/helpers/ducky_script.c | 13 ++++++++++--- .../main/bad_usb/helpers/ducky_script_commands.c | 4 ++-- applications/main/bad_usb/helpers/ducky_script_i.h | 4 +++- .../main/bad_usb/helpers/ducky_script_keycodes.c | 12 ++++++++++++ 5 files changed, 28 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5116f3154..beab8f799 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,7 @@ - SmartRider parser (by @jaylikesbunda) * Apps: **Check out more Apps updates and fixes by following** [this link](https://github.com/xMasterX/all-the-plugins/commits/dev) ## Other changes +* BadUSB: Fix modifier keys with HOLD/RELEASE commands (by @WillyJL) * Docs: Update doorhan programming instructions (by @li0ard) * FuriHalSerial: Fix RXFNE interrupt hang, aka freezing with UART output when Expansion Modules are enabled (by @WillyJL) * Expansion: add is_connected api (by @HaxSam & @WillyJL) diff --git a/applications/main/bad_usb/helpers/ducky_script.c b/applications/main/bad_usb/helpers/ducky_script.c index 43621de78..4b427b759 100644 --- a/applications/main/bad_usb/helpers/ducky_script.c +++ b/applications/main/bad_usb/helpers/ducky_script.c @@ -50,13 +50,20 @@ bool ducky_is_line_end(const char chr) { return (chr == ' ') || (chr == '\0') || (chr == '\r') || (chr == '\n'); } -uint16_t ducky_get_keycode(BadUsbScript* bad_usb, const char* param, bool accept_chars) { +uint16_t ducky_get_keycode(BadUsbScript* bad_usb, const char* param, bool accept_modifiers) { uint16_t keycode = ducky_get_keycode_by_name(param); if(keycode != HID_KEYBOARD_NONE) { return keycode; } - if((accept_chars) && (strlen(param) > 0)) { + if(accept_modifiers) { + uint16_t keycode = ducky_get_modifier_keycode_by_name(param); + if(keycode != HID_KEYBOARD_NONE) { + return keycode; + } + } + + if(strlen(param) > 0) { return BADUSB_ASCII_TO_KEY(bad_usb, param[0]) & 0xFF; } return 0; @@ -213,7 +220,7 @@ static int32_t ducky_parse_line(BadUsbScript* bad_usb, FuriString* line) { // Main key char next_char = *line_cstr; - key = modifiers | ducky_get_keycode(bad_usb, line_cstr, true); + key = modifiers | ducky_get_keycode(bad_usb, line_cstr, false); if(key == 0 && next_char) ducky_error(bad_usb, "No keycode defined for %s", line_cstr); diff --git a/applications/main/bad_usb/helpers/ducky_script_commands.c b/applications/main/bad_usb/helpers/ducky_script_commands.c index 6c6fe36c7..dbf9c1aef 100644 --- a/applications/main/bad_usb/helpers/ducky_script_commands.c +++ b/applications/main/bad_usb/helpers/ducky_script_commands.c @@ -92,7 +92,7 @@ static int32_t ducky_fnc_sysrq(BadUsbScript* bad_usb, const char* line, int32_t UNUSED(param); line = &line[ducky_get_command_len(line) + 1]; - uint16_t key = ducky_get_keycode(bad_usb, line, true); + uint16_t key = ducky_get_keycode(bad_usb, line, false); bad_usb->hid->kb_press(bad_usb->hid_inst, KEY_MOD_LEFT_ALT | HID_KEYBOARD_PRINT_SCREEN); bad_usb->hid->kb_press(bad_usb->hid_inst, key); bad_usb->hid->release_all(bad_usb->hid_inst); @@ -196,7 +196,7 @@ static int32_t ducky_fnc_globe(BadUsbScript* bad_usb, const char* line, int32_t UNUSED(param); line = &line[ducky_get_command_len(line) + 1]; - uint16_t key = ducky_get_keycode(bad_usb, line, true); + uint16_t key = ducky_get_keycode(bad_usb, line, false); if(key == HID_KEYBOARD_NONE) { return ducky_error(bad_usb, "No keycode defined for %s", line); } diff --git a/applications/main/bad_usb/helpers/ducky_script_i.h b/applications/main/bad_usb/helpers/ducky_script_i.h index d735a8407..e5e0d645c 100644 --- a/applications/main/bad_usb/helpers/ducky_script_i.h +++ b/applications/main/bad_usb/helpers/ducky_script_i.h @@ -50,7 +50,7 @@ struct BadUsbScript { size_t string_print_pos; }; -uint16_t ducky_get_keycode(BadUsbScript* bad_usb, const char* param, bool accept_chars); +uint16_t ducky_get_keycode(BadUsbScript* bad_usb, const char* param, bool accept_modifiers); uint32_t ducky_get_command_len(const char* line); @@ -58,6 +58,8 @@ bool ducky_is_line_end(const char chr); uint16_t ducky_get_next_modifier_keycode_by_name(const char** param); +uint16_t ducky_get_modifier_keycode_by_name(const char* param); + uint16_t ducky_get_keycode_by_name(const char* param); uint16_t ducky_get_media_keycode_by_name(const char* param); diff --git a/applications/main/bad_usb/helpers/ducky_script_keycodes.c b/applications/main/bad_usb/helpers/ducky_script_keycodes.c index ce957bb4e..77cc324d3 100644 --- a/applications/main/bad_usb/helpers/ducky_script_keycodes.c +++ b/applications/main/bad_usb/helpers/ducky_script_keycodes.c @@ -131,6 +131,18 @@ uint16_t ducky_get_next_modifier_keycode_by_name(const char** param) { return HID_KEYBOARD_NONE; } +uint16_t ducky_get_modifier_keycode_by_name(const char* param) { + for(size_t i = 0; i < COUNT_OF(ducky_modifier_keys); i++) { + size_t key_cmd_len = strlen(ducky_modifier_keys[i].name); + if((strncmp(param, ducky_modifier_keys[i].name, key_cmd_len) == 0) && + (ducky_is_line_end(param[key_cmd_len]))) { + return ducky_modifier_keys[i].keycode; + } + } + + return HID_KEYBOARD_NONE; +} + uint16_t ducky_get_keycode_by_name(const char* param) { for(size_t i = 0; i < COUNT_OF(ducky_keys); i++) { size_t key_cmd_len = strlen(ducky_keys[i].name);