1
mirror of https://github.com/DarkFlippers/unleashed-firmware.git synced 2025-12-12 04:34:43 +04:00

js add badusb layout support

by Willy-JL
This commit is contained in:
MX
2024-04-05 08:01:53 +03:00
parent 22cf19dcef
commit 6e4d32b941
2 changed files with 44 additions and 14 deletions

View File

@@ -3,7 +3,13 @@ let notify = require("notification");
let flipper = require("flipper"); let flipper = require("flipper");
let dialog = require("dialog"); let dialog = require("dialog");
badusb.setup({ vid: 0xAAAA, pid: 0xBBBB, mfr_name: "Flipper", prod_name: "Zero" }); badusb.setup({
vid: 0xAAAA,
pid: 0xBBBB,
mfr_name: "Flipper",
prod_name: "Zero",
layout_path: "/ext/badusb/assets/layouts/en-US.kl"
});
dialog.message("BadUSB demo", "Press OK to start"); dialog.message("BadUSB demo", "Press OK to start");
if (badusb.isConnected()) { if (badusb.isConnected()) {

View File

@@ -2,8 +2,11 @@
#include "../js_modules.h" #include "../js_modules.h"
#include <furi_hal.h> #include <furi_hal.h>
#define ASCII_TO_KEY(layout, x) (((uint8_t)x < 128) ? (layout[(uint8_t)x]) : HID_KEYBOARD_NONE)
typedef struct { typedef struct {
FuriHalUsbHidConfig* hid_cfg; FuriHalUsbHidConfig* hid_cfg;
uint16_t layout[128];
FuriHalUsbInterface* usb_if_prev; FuriHalUsbInterface* usb_if_prev;
uint8_t key_hold_cnt; uint8_t key_hold_cnt;
} JsBadusbInst; } JsBadusbInst;
@@ -88,7 +91,11 @@ static void js_badusb_quit_free(JsBadusbInst* badusb) {
} }
} }
static bool setup_parse_params(struct mjs* mjs, mjs_val_t arg, FuriHalUsbHidConfig* hid_cfg) { static bool setup_parse_params(
JsBadusbInst* badusb,
struct mjs* mjs,
mjs_val_t arg,
FuriHalUsbHidConfig* hid_cfg) {
if(!mjs_is_object(arg)) { if(!mjs_is_object(arg)) {
return false; return false;
} }
@@ -96,6 +103,7 @@ static bool setup_parse_params(struct mjs* mjs, mjs_val_t arg, FuriHalUsbHidConf
mjs_val_t pid_obj = mjs_get(mjs, arg, "pid", ~0); mjs_val_t pid_obj = mjs_get(mjs, arg, "pid", ~0);
mjs_val_t mfr_obj = mjs_get(mjs, arg, "mfr_name", ~0); mjs_val_t mfr_obj = mjs_get(mjs, arg, "mfr_name", ~0);
mjs_val_t prod_obj = mjs_get(mjs, arg, "prod_name", ~0); mjs_val_t prod_obj = mjs_get(mjs, arg, "prod_name", ~0);
mjs_val_t layout_obj = mjs_get(mjs, arg, "layout_path", ~0);
if(mjs_is_number(vid_obj) && mjs_is_number(pid_obj)) { if(mjs_is_number(vid_obj) && mjs_is_number(pid_obj)) {
hid_cfg->vid = mjs_get_int32(mjs, vid_obj); hid_cfg->vid = mjs_get_int32(mjs, vid_obj);
@@ -122,6 +130,22 @@ static bool setup_parse_params(struct mjs* mjs, mjs_val_t arg, FuriHalUsbHidConf
strlcpy(hid_cfg->product, str_temp, sizeof(hid_cfg->product)); strlcpy(hid_cfg->product, str_temp, sizeof(hid_cfg->product));
} }
if(mjs_is_string(layout_obj)) {
size_t str_len = 0;
const char* str_temp = mjs_get_string(mjs, &layout_obj, &str_len);
File* file = storage_file_alloc(furi_record_open(RECORD_STORAGE));
size_t size = sizeof(badusb->layout);
if((str_len == 0) || (str_temp == NULL) ||
!storage_file_open(file, str_temp, FSAM_READ, FSOM_OPEN_EXISTING) ||
storage_file_read(file, badusb->layout, size) != size) {
memcpy(badusb->layout, hid_asciimap, MIN(sizeof(hid_asciimap), size));
}
storage_file_free(file);
furi_record_close(RECORD_STORAGE);
}
return true; return true;
} }
@@ -144,7 +168,7 @@ static void js_badusb_setup(struct mjs* mjs) {
} else if(num_args == 1) { } else if(num_args == 1) {
badusb->hid_cfg = malloc(sizeof(FuriHalUsbHidConfig)); badusb->hid_cfg = malloc(sizeof(FuriHalUsbHidConfig));
// Parse argument object // Parse argument object
args_correct = setup_parse_params(mjs, mjs_arg(mjs, 0), badusb->hid_cfg); args_correct = setup_parse_params(badusb, mjs, mjs_arg(mjs, 0), badusb->hid_cfg);
} }
if(!args_correct) { if(!args_correct) {
mjs_prepend_errorf(mjs, MJS_BAD_ARGS_ERROR, ""); mjs_prepend_errorf(mjs, MJS_BAD_ARGS_ERROR, "");
@@ -191,9 +215,9 @@ static void js_badusb_is_connected(struct mjs* mjs) {
mjs_return(mjs, mjs_mk_boolean(mjs, is_connected)); mjs_return(mjs, mjs_mk_boolean(mjs, is_connected));
} }
uint16_t get_keycode_by_name(const char* key_name, size_t name_len) { uint16_t get_keycode_by_name(JsBadusbInst* badusb, const char* key_name, size_t name_len) {
if(name_len == 1) { // Single char if(name_len == 1) { // Single char
return (HID_ASCII_TO_KEY(key_name[0])); return (ASCII_TO_KEY(badusb->layout, key_name[0]));
} }
for(size_t i = 0; i < COUNT_OF(key_codes); i++) { for(size_t i = 0; i < COUNT_OF(key_codes); i++) {
@@ -210,7 +234,7 @@ uint16_t get_keycode_by_name(const char* key_name, size_t name_len) {
return HID_KEYBOARD_NONE; return HID_KEYBOARD_NONE;
} }
static bool parse_keycode(struct mjs* mjs, size_t nargs, uint16_t* keycode) { static bool parse_keycode(JsBadusbInst* badusb, struct mjs* mjs, size_t nargs, uint16_t* keycode) {
uint16_t key_tmp = 0; uint16_t key_tmp = 0;
for(size_t i = 0; i < nargs; i++) { for(size_t i = 0; i < nargs; i++) {
mjs_val_t arg = mjs_arg(mjs, i); mjs_val_t arg = mjs_arg(mjs, i);
@@ -221,7 +245,7 @@ static bool parse_keycode(struct mjs* mjs, size_t nargs, uint16_t* keycode) {
// String error // String error
return false; return false;
} }
uint16_t str_key = get_keycode_by_name(key_name, name_len); uint16_t str_key = get_keycode_by_name(badusb, key_name, name_len);
if(str_key == HID_KEYBOARD_NONE) { if(str_key == HID_KEYBOARD_NONE) {
// Unknown key code // Unknown key code
return false; return false;
@@ -259,7 +283,7 @@ static void js_badusb_press(struct mjs* mjs) {
uint16_t keycode = HID_KEYBOARD_NONE; uint16_t keycode = HID_KEYBOARD_NONE;
size_t num_args = mjs_nargs(mjs); size_t num_args = mjs_nargs(mjs);
if(num_args > 0) { if(num_args > 0) {
args_correct = parse_keycode(mjs, num_args, &keycode); args_correct = parse_keycode(badusb, mjs, num_args, &keycode);
} }
if(!args_correct) { if(!args_correct) {
mjs_prepend_errorf(mjs, MJS_BAD_ARGS_ERROR, ""); mjs_prepend_errorf(mjs, MJS_BAD_ARGS_ERROR, "");
@@ -285,7 +309,7 @@ static void js_badusb_hold(struct mjs* mjs) {
uint16_t keycode = HID_KEYBOARD_NONE; uint16_t keycode = HID_KEYBOARD_NONE;
size_t num_args = mjs_nargs(mjs); size_t num_args = mjs_nargs(mjs);
if(num_args > 0) { if(num_args > 0) {
args_correct = parse_keycode(mjs, num_args, &keycode); args_correct = parse_keycode(badusb, mjs, num_args, &keycode);
} }
if(!args_correct) { if(!args_correct) {
mjs_prepend_errorf(mjs, MJS_BAD_ARGS_ERROR, ""); mjs_prepend_errorf(mjs, MJS_BAD_ARGS_ERROR, "");
@@ -324,7 +348,7 @@ static void js_badusb_release(struct mjs* mjs) {
mjs_return(mjs, MJS_UNDEFINED); mjs_return(mjs, MJS_UNDEFINED);
return; return;
} else { } else {
args_correct = parse_keycode(mjs, num_args, &keycode); args_correct = parse_keycode(badusb, mjs, num_args, &keycode);
} }
if(!args_correct) { if(!args_correct) {
mjs_prepend_errorf(mjs, MJS_BAD_ARGS_ERROR, ""); mjs_prepend_errorf(mjs, MJS_BAD_ARGS_ERROR, "");
@@ -347,14 +371,14 @@ static void ducky_numlock_on() {
} }
// Simulate pressing a character using ALT+Numpad ASCII code // Simulate pressing a character using ALT+Numpad ASCII code
static void ducky_altchar(const char* ascii_code) { static void ducky_altchar(JsBadusbInst* badusb, const char* ascii_code) {
// Hold the ALT key // Hold the ALT key
furi_hal_hid_kb_press(KEY_MOD_LEFT_ALT); furi_hal_hid_kb_press(KEY_MOD_LEFT_ALT);
// Press the corresponding numpad key for each digit of the ASCII code // Press the corresponding numpad key for each digit of the ASCII code
for(size_t i = 0; ascii_code[i] != '\0'; i++) { 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 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)); uint16_t numpad_keycode = get_keycode_by_name(badusb, digitChar, strlen(digitChar));
if(numpad_keycode == HID_KEYBOARD_NONE) { if(numpad_keycode == HID_KEYBOARD_NONE) {
continue; // Skip if keycode not found continue; // Skip if keycode not found
} }
@@ -420,9 +444,9 @@ static void badusb_print(struct mjs* mjs, bool ln, bool alt) {
// Convert character to ascii numeric value // Convert character to ascii numeric value
char ascii_str[4]; char ascii_str[4];
snprintf(ascii_str, sizeof(ascii_str), "%u", (uint8_t)text_str[i]); snprintf(ascii_str, sizeof(ascii_str), "%u", (uint8_t)text_str[i]);
ducky_altchar(ascii_str); ducky_altchar(badusb, ascii_str);
} else { } else {
uint16_t keycode = HID_ASCII_TO_KEY(text_str[i]); uint16_t keycode = ASCII_TO_KEY(badusb->layout, text_str[i]);
furi_hal_hid_kb_press(keycode); furi_hal_hid_kb_press(keycode);
furi_hal_hid_kb_release(keycode); furi_hal_hid_kb_release(keycode);
} }