mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2025-12-12 12:42:30 +04:00
js add badusb layout support
by Willy-JL
This commit is contained in:
@@ -3,7 +3,13 @@ let notify = require("notification");
|
||||
let flipper = require("flipper");
|
||||
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");
|
||||
|
||||
if (badusb.isConnected()) {
|
||||
|
||||
@@ -2,8 +2,11 @@
|
||||
#include "../js_modules.h"
|
||||
#include <furi_hal.h>
|
||||
|
||||
#define ASCII_TO_KEY(layout, x) (((uint8_t)x < 128) ? (layout[(uint8_t)x]) : HID_KEYBOARD_NONE)
|
||||
|
||||
typedef struct {
|
||||
FuriHalUsbHidConfig* hid_cfg;
|
||||
uint16_t layout[128];
|
||||
FuriHalUsbInterface* usb_if_prev;
|
||||
uint8_t key_hold_cnt;
|
||||
} 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)) {
|
||||
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 mfr_obj = mjs_get(mjs, arg, "mfr_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)) {
|
||||
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));
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -144,7 +168,7 @@ static void js_badusb_setup(struct mjs* mjs) {
|
||||
} else if(num_args == 1) {
|
||||
badusb->hid_cfg = malloc(sizeof(FuriHalUsbHidConfig));
|
||||
// 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) {
|
||||
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));
|
||||
}
|
||||
|
||||
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
|
||||
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++) {
|
||||
@@ -210,7 +234,7 @@ uint16_t get_keycode_by_name(const char* key_name, size_t name_len) {
|
||||
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;
|
||||
for(size_t i = 0; i < nargs; 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
|
||||
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) {
|
||||
// Unknown key code
|
||||
return false;
|
||||
@@ -259,7 +283,7 @@ static void js_badusb_press(struct mjs* mjs) {
|
||||
uint16_t keycode = HID_KEYBOARD_NONE;
|
||||
size_t num_args = mjs_nargs(mjs);
|
||||
if(num_args > 0) {
|
||||
args_correct = parse_keycode(mjs, num_args, &keycode);
|
||||
args_correct = parse_keycode(badusb, mjs, num_args, &keycode);
|
||||
}
|
||||
if(!args_correct) {
|
||||
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;
|
||||
size_t num_args = mjs_nargs(mjs);
|
||||
if(num_args > 0) {
|
||||
args_correct = parse_keycode(mjs, num_args, &keycode);
|
||||
args_correct = parse_keycode(badusb, mjs, num_args, &keycode);
|
||||
}
|
||||
if(!args_correct) {
|
||||
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);
|
||||
return;
|
||||
} else {
|
||||
args_correct = parse_keycode(mjs, num_args, &keycode);
|
||||
args_correct = parse_keycode(badusb, mjs, num_args, &keycode);
|
||||
}
|
||||
if(!args_correct) {
|
||||
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
|
||||
static void ducky_altchar(const char* ascii_code) {
|
||||
static void ducky_altchar(JsBadusbInst* badusb, 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));
|
||||
uint16_t numpad_keycode = get_keycode_by_name(badusb, digitChar, strlen(digitChar));
|
||||
if(numpad_keycode == HID_KEYBOARD_NONE) {
|
||||
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
|
||||
char ascii_str[4];
|
||||
snprintf(ascii_str, sizeof(ascii_str), "%u", (uint8_t)text_str[i]);
|
||||
ducky_altchar(ascii_str);
|
||||
ducky_altchar(badusb, ascii_str);
|
||||
} 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_release(keycode);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user