diff --git a/applications/system/js_app/examples/apps/Scripts/badusb_demo.js b/applications/system/js_app/examples/apps/Scripts/badusb_demo.js index bbeedd4457..8605020233 100644 --- a/applications/system/js_app/examples/apps/Scripts/badusb_demo.js +++ b/applications/system/js_app/examples/apps/Scripts/badusb_demo.js @@ -26,6 +26,12 @@ if (badusb.isConnected()) { badusb.println("Flipper Name: " + flipper.getName()); badusb.println("Battery level: " + to_string(flipper.getBatteryCharge()) + "%"); + // Alt+Numpad method works only on Windows!!! + badusb.altPrintln("This was printed with Alt+Numpad method!"); + + // There's also badusb.print() and badusb.altPrint() + // which don't add the return at the end + notify.success(); } else { print("USB not connected"); diff --git a/applications/system/js_app/modules/js_badusb.c b/applications/system/js_app/modules/js_badusb.c index 0ac5c47da2..389539be58 100644 --- a/applications/system/js_app/modules/js_badusb.c +++ b/applications/system/js_app/modules/js_badusb.c @@ -52,6 +52,17 @@ static const struct { {"F10", HID_KEYBOARD_F10}, {"F11", HID_KEYBOARD_F11}, {"F12", HID_KEYBOARD_F12}, + + {"NUM0", HID_KEYPAD_0}, + {"NUM1", HID_KEYPAD_1}, + {"NUM2", HID_KEYPAD_2}, + {"NUM3", HID_KEYPAD_3}, + {"NUM4", HID_KEYPAD_4}, + {"NUM5", HID_KEYPAD_5}, + {"NUM6", HID_KEYPAD_6}, + {"NUM7", HID_KEYPAD_7}, + {"NUM8", HID_KEYPAD_8}, + {"NUM9", HID_KEYPAD_9}, }; static void js_badusb_quit_free(JsBadusbInst* badusb) { @@ -314,7 +325,35 @@ static void js_badusb_release(struct mjs* mjs) { mjs_return(mjs, MJS_UNDEFINED); } -static void badusb_print(struct mjs* mjs, bool ln) { +// Make sure NUMLOCK is enabled for altchar +static void ducky_numlock_on() { + if((furi_hal_hid_get_led_state() & HID_KB_LED_NUM) == 0) { + furi_hal_hid_kb_press(HID_KEYBOARD_LOCK_NUM_LOCK); + furi_hal_hid_kb_release(HID_KEYBOARD_LOCK_NUM_LOCK); + } +} + +// Simulate pressing a character using ALT+Numpad ASCII code +static void ducky_altchar(const char* ascii_code) { + // Hold the ALT key + furi_hal_hid_kb_press(KEY_MOD_LEFT_ALT); + + // Press the corresponding numpad key for each digit of the ASCII code + for(size_t i = 0; ascii_code[i] != '\0'; i++) { + char digitChar[5] = {'N', 'U', 'M', ascii_code[i], '\0'}; // Construct the numpad key name + uint16_t numpad_keycode = get_keycode_by_name(digitChar, strlen(digitChar)); + if(numpad_keycode == HID_KEYBOARD_NONE) { + continue; // Skip if keycode not found + } + furi_hal_hid_kb_press(numpad_keycode); + furi_hal_hid_kb_release(numpad_keycode); + } + + // Release the ALT key + furi_hal_hid_kb_release(KEY_MOD_LEFT_ALT); +} + +static void badusb_print(struct mjs* mjs, bool ln, bool alt) { mjs_val_t obj_inst = mjs_get(mjs, mjs_get_this(mjs), INST_PROP_NAME, ~0); JsBadusbInst* badusb = mjs_get_ptr(mjs, obj_inst); furi_assert(badusb); @@ -360,10 +399,20 @@ static void badusb_print(struct mjs* mjs, bool ln) { return; } + if(alt) { + ducky_numlock_on(); + } for(size_t i = 0; i < text_len; i++) { - uint16_t keycode = HID_ASCII_TO_KEY(text_str[i]); - furi_hal_hid_kb_press(keycode); - furi_hal_hid_kb_release(keycode); + if(alt) { + // Convert character to ascii numeric value + char ascii_str[4]; + snprintf(ascii_str, sizeof(ascii_str), "%u", (uint8_t)text_str[i]); + ducky_altchar(ascii_str); + } else { + uint16_t keycode = HID_ASCII_TO_KEY(text_str[i]); + furi_hal_hid_kb_press(keycode); + furi_hal_hid_kb_release(keycode); + } if(delay_val > 0) { bool need_exit = js_delay_with_flags(mjs, delay_val); if(need_exit) { @@ -381,11 +430,19 @@ static void badusb_print(struct mjs* mjs, bool ln) { } static void js_badusb_print(struct mjs* mjs) { - badusb_print(mjs, false); + badusb_print(mjs, false, false); } static void js_badusb_println(struct mjs* mjs) { - badusb_print(mjs, true); + badusb_print(mjs, true, false); +} + +static void js_badusb_alt_print(struct mjs* mjs) { + badusb_print(mjs, false, true); +} + +static void js_badusb_alt_println(struct mjs* mjs) { + badusb_print(mjs, true, true); } static void* js_badusb_create(struct mjs* mjs, mjs_val_t* object) { @@ -400,6 +457,8 @@ static void* js_badusb_create(struct mjs* mjs, mjs_val_t* object) { mjs_set(mjs, badusb_obj, "release", ~0, MJS_MK_FN(js_badusb_release)); mjs_set(mjs, badusb_obj, "print", ~0, MJS_MK_FN(js_badusb_print)); mjs_set(mjs, badusb_obj, "println", ~0, MJS_MK_FN(js_badusb_println)); + mjs_set(mjs, badusb_obj, "altPrint", ~0, MJS_MK_FN(js_badusb_alt_print)); + mjs_set(mjs, badusb_obj, "altPrintln", ~0, MJS_MK_FN(js_badusb_alt_println)); *object = badusb_obj; return badusb; }