* updated parser and added stringln, hold and release * removed unused code as requested from PR * BadUsb: tiny change to trigger rebuild Co-authored-by: p4p1 <p4p1@vivaldi.net> Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
		@@ -6,11 +6,11 @@
 | 
				
			|||||||
#include <furi_hal_usb_hid.h>
 | 
					#include <furi_hal_usb_hid.h>
 | 
				
			||||||
#include <storage/storage.h>
 | 
					#include <storage/storage.h>
 | 
				
			||||||
#include "bad_usb_script.h"
 | 
					#include "bad_usb_script.h"
 | 
				
			||||||
 | 
					#include "mnemonic.h"
 | 
				
			||||||
#include <dolphin/dolphin.h>
 | 
					#include <dolphin/dolphin.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define TAG "BadUSB"
 | 
					#define TAG "BadUSB"
 | 
				
			||||||
#define WORKER_TAG TAG "Worker"
 | 
					#define WORKER_TAG TAG "Worker"
 | 
				
			||||||
#define FILE_BUFFER_LEN 16
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SCRIPT_STATE_ERROR (-1)
 | 
					#define SCRIPT_STATE_ERROR (-1)
 | 
				
			||||||
#define SCRIPT_STATE_END (-2)
 | 
					#define SCRIPT_STATE_END (-2)
 | 
				
			||||||
@@ -26,24 +26,6 @@ typedef enum {
 | 
				
			|||||||
    WorkerEvtDisconnect = (1 << 3),
 | 
					    WorkerEvtDisconnect = (1 << 3),
 | 
				
			||||||
} WorkerEvtFlags;
 | 
					} WorkerEvtFlags;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct BadUsbScript {
 | 
					 | 
				
			||||||
    FuriHalUsbHidConfig hid_cfg;
 | 
					 | 
				
			||||||
    BadUsbState st;
 | 
					 | 
				
			||||||
    FuriString* file_path;
 | 
					 | 
				
			||||||
    uint32_t defdelay;
 | 
					 | 
				
			||||||
    uint16_t layout[128];
 | 
					 | 
				
			||||||
    uint32_t stringdelay;
 | 
					 | 
				
			||||||
    FuriThread* thread;
 | 
					 | 
				
			||||||
    uint8_t file_buf[FILE_BUFFER_LEN + 1];
 | 
					 | 
				
			||||||
    uint8_t buf_start;
 | 
					 | 
				
			||||||
    uint8_t buf_len;
 | 
					 | 
				
			||||||
    bool file_end;
 | 
					 | 
				
			||||||
    FuriString* line;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    FuriString* line_prev;
 | 
					 | 
				
			||||||
    uint32_t repeat_cnt;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
    char* name;
 | 
					    char* name;
 | 
				
			||||||
    uint16_t keycode;
 | 
					    uint16_t keycode;
 | 
				
			||||||
@@ -112,40 +94,21 @@ static const char ducky_cmd_comment[] = {"REM"};
 | 
				
			|||||||
static const char ducky_cmd_id[] = {"ID"};
 | 
					static const char ducky_cmd_id[] = {"ID"};
 | 
				
			||||||
static const char ducky_cmd_delay[] = {"DELAY "};
 | 
					static const char ducky_cmd_delay[] = {"DELAY "};
 | 
				
			||||||
static const char ducky_cmd_string[] = {"STRING "};
 | 
					static const char ducky_cmd_string[] = {"STRING "};
 | 
				
			||||||
 | 
					static const char ducky_cmd_stringln[] = {"STRINGLN "};
 | 
				
			||||||
static const char ducky_cmd_defdelay_1[] = {"DEFAULT_DELAY "};
 | 
					static const char ducky_cmd_defdelay_1[] = {"DEFAULT_DELAY "};
 | 
				
			||||||
static const char ducky_cmd_defdelay_2[] = {"DEFAULTDELAY "};
 | 
					static const char ducky_cmd_defdelay_2[] = {"DEFAULTDELAY "};
 | 
				
			||||||
static const char ducky_cmd_stringdelay_1[] = {"STRINGDELAY "};
 | 
					static const char ducky_cmd_stringdelay_1[] = {"STRINGDELAY "};
 | 
				
			||||||
static const char ducky_cmd_stringdelay_2[] = {"STRING_DELAY "};
 | 
					static const char ducky_cmd_stringdelay_2[] = {"STRING_DELAY "};
 | 
				
			||||||
static const char ducky_cmd_repeat[] = {"REPEAT "};
 | 
					static const char ducky_cmd_repeat[] = {"REPEAT "};
 | 
				
			||||||
static const char ducky_cmd_sysrq[] = {"SYSRQ "};
 | 
					static const char ducky_cmd_sysrq[] = {"SYSRQ "};
 | 
				
			||||||
 | 
					static const char ducky_cmd_hold[] = {"HOLD "};
 | 
				
			||||||
 | 
					static const char ducky_cmd_release[] = {"RELEASE "};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const char ducky_cmd_altchar[] = {"ALTCHAR "};
 | 
					static const char ducky_cmd_altchar[] = {"ALTCHAR "};
 | 
				
			||||||
static const char ducky_cmd_altstr_1[] = {"ALTSTRING "};
 | 
					static const char ducky_cmd_altstr_1[] = {"ALTSTRING "};
 | 
				
			||||||
static const char ducky_cmd_altstr_2[] = {"ALTCODE "};
 | 
					static const char ducky_cmd_altstr_2[] = {"ALTCODE "};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const uint8_t numpad_keys[10] = {
 | 
					uint32_t ducky_get_command_len(const char* line) {
 | 
				
			||||||
    HID_KEYPAD_0,
 | 
					 | 
				
			||||||
    HID_KEYPAD_1,
 | 
					 | 
				
			||||||
    HID_KEYPAD_2,
 | 
					 | 
				
			||||||
    HID_KEYPAD_3,
 | 
					 | 
				
			||||||
    HID_KEYPAD_4,
 | 
					 | 
				
			||||||
    HID_KEYPAD_5,
 | 
					 | 
				
			||||||
    HID_KEYPAD_6,
 | 
					 | 
				
			||||||
    HID_KEYPAD_7,
 | 
					 | 
				
			||||||
    HID_KEYPAD_8,
 | 
					 | 
				
			||||||
    HID_KEYPAD_9,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static bool ducky_get_number(const char* param, uint32_t* val) {
 | 
					 | 
				
			||||||
    uint32_t value = 0;
 | 
					 | 
				
			||||||
    if(sscanf(param, "%lu", &value) == 1) {
 | 
					 | 
				
			||||||
        *val = value;
 | 
					 | 
				
			||||||
        return true;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return false;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static uint32_t ducky_get_command_len(const char* line) {
 | 
					 | 
				
			||||||
    uint32_t len = strlen(line);
 | 
					    uint32_t len = strlen(line);
 | 
				
			||||||
    for(uint32_t i = 0; i < len; i++) {
 | 
					    for(uint32_t i = 0; i < len; i++) {
 | 
				
			||||||
        if(line[i] == ' ') return i;
 | 
					        if(line[i] == ' ') return i;
 | 
				
			||||||
@@ -153,84 +116,11 @@ static uint32_t ducky_get_command_len(const char* line) {
 | 
				
			|||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool ducky_is_line_end(const char chr) {
 | 
					bool ducky_is_line_end(const char chr) {
 | 
				
			||||||
    return ((chr == ' ') || (chr == '\0') || (chr == '\r') || (chr == '\n'));
 | 
					    return ((chr == ' ') || (chr == '\0') || (chr == '\r') || (chr == '\n'));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void ducky_numlock_on() {
 | 
					uint16_t ducky_get_keycode(BadUsbScript* bad_usb, const char* param, bool accept_chars) {
 | 
				
			||||||
    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);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static bool ducky_numpad_press(const char num) {
 | 
					 | 
				
			||||||
    if((num < '0') || (num > '9')) return false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    uint16_t key = numpad_keys[num - '0'];
 | 
					 | 
				
			||||||
    furi_hal_hid_kb_press(key);
 | 
					 | 
				
			||||||
    furi_hal_hid_kb_release(key);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return true;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static bool ducky_altchar(const char* charcode) {
 | 
					 | 
				
			||||||
    uint8_t i = 0;
 | 
					 | 
				
			||||||
    bool state = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    FURI_LOG_I(WORKER_TAG, "char %s", charcode);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    furi_hal_hid_kb_press(KEY_MOD_LEFT_ALT);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    while(!ducky_is_line_end(charcode[i])) {
 | 
					 | 
				
			||||||
        state = ducky_numpad_press(charcode[i]);
 | 
					 | 
				
			||||||
        if(state == false) break;
 | 
					 | 
				
			||||||
        i++;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    furi_hal_hid_kb_release(KEY_MOD_LEFT_ALT);
 | 
					 | 
				
			||||||
    return state;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static bool ducky_altstring(const char* param) {
 | 
					 | 
				
			||||||
    uint32_t i = 0;
 | 
					 | 
				
			||||||
    bool state = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    while(param[i] != '\0') {
 | 
					 | 
				
			||||||
        if((param[i] < ' ') || (param[i] > '~')) {
 | 
					 | 
				
			||||||
            i++;
 | 
					 | 
				
			||||||
            continue; // Skip non-printable chars
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        char temp_str[4];
 | 
					 | 
				
			||||||
        snprintf(temp_str, 4, "%u", param[i]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        state = ducky_altchar(temp_str);
 | 
					 | 
				
			||||||
        if(state == false) break;
 | 
					 | 
				
			||||||
        i++;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return state;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static bool ducky_string(BadUsbScript* bad_usb, const char* param) {
 | 
					 | 
				
			||||||
    uint32_t i = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    while(param[i] != '\0') {
 | 
					 | 
				
			||||||
        uint16_t keycode = BADUSB_ASCII_TO_KEY(bad_usb, param[i]);
 | 
					 | 
				
			||||||
        if(keycode != HID_KEYBOARD_NONE) {
 | 
					 | 
				
			||||||
            furi_hal_hid_kb_press(keycode);
 | 
					 | 
				
			||||||
            furi_hal_hid_kb_release(keycode);
 | 
					 | 
				
			||||||
            if(bad_usb->stringdelay > 0) {
 | 
					 | 
				
			||||||
                furi_delay_ms(bad_usb->stringdelay);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        i++;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    bad_usb->stringdelay = 0;
 | 
					 | 
				
			||||||
    return true;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static uint16_t ducky_get_keycode(BadUsbScript* bad_usb, const char* param, bool accept_chars) {
 | 
					 | 
				
			||||||
    for(size_t i = 0; i < (sizeof(ducky_keys) / sizeof(ducky_keys[0])); i++) {
 | 
					    for(size_t i = 0; i < (sizeof(ducky_keys) / sizeof(ducky_keys[0])); i++) {
 | 
				
			||||||
        size_t key_cmd_len = strlen(ducky_keys[i].name);
 | 
					        size_t key_cmd_len = strlen(ducky_keys[i].name);
 | 
				
			||||||
        if((strncmp(param, ducky_keys[i].name, key_cmd_len) == 0) &&
 | 
					        if((strncmp(param, ducky_keys[i].name, key_cmd_len) == 0) &&
 | 
				
			||||||
@@ -248,102 +138,52 @@ static int32_t
 | 
				
			|||||||
    ducky_parse_line(BadUsbScript* bad_usb, FuriString* line, char* error, size_t error_len) {
 | 
					    ducky_parse_line(BadUsbScript* bad_usb, FuriString* line, char* error, size_t error_len) {
 | 
				
			||||||
    uint32_t line_len = furi_string_size(line);
 | 
					    uint32_t line_len = furi_string_size(line);
 | 
				
			||||||
    const char* line_tmp = furi_string_get_cstr(line);
 | 
					    const char* line_tmp = furi_string_get_cstr(line);
 | 
				
			||||||
    bool state = false;
 | 
					    const char* ducky_cmd_table[] = {
 | 
				
			||||||
 | 
					        ducky_cmd_comment,
 | 
				
			||||||
 | 
					        ducky_cmd_id,
 | 
				
			||||||
 | 
					        ducky_cmd_delay,
 | 
				
			||||||
 | 
					        ducky_cmd_string,
 | 
				
			||||||
 | 
					        ducky_cmd_defdelay_1,
 | 
				
			||||||
 | 
					        ducky_cmd_defdelay_2,
 | 
				
			||||||
 | 
					        ducky_cmd_stringdelay_1,
 | 
				
			||||||
 | 
					        ducky_cmd_stringdelay_2,
 | 
				
			||||||
 | 
					        ducky_cmd_repeat,
 | 
				
			||||||
 | 
					        ducky_cmd_sysrq,
 | 
				
			||||||
 | 
					        ducky_cmd_altchar,
 | 
				
			||||||
 | 
					        ducky_cmd_altstr_1,
 | 
				
			||||||
 | 
					        ducky_cmd_altstr_2,
 | 
				
			||||||
 | 
					        ducky_cmd_stringln,
 | 
				
			||||||
 | 
					        ducky_cmd_hold,
 | 
				
			||||||
 | 
					        ducky_cmd_release,
 | 
				
			||||||
 | 
					        NULL};
 | 
				
			||||||
 | 
					    int32_t (*fnc_ptr[])(BadUsbScript*, FuriString*, const char*, char*, size_t) = {
 | 
				
			||||||
 | 
					        &ducky_fnc_noop,
 | 
				
			||||||
 | 
					        &ducky_fnc_noop,
 | 
				
			||||||
 | 
					        &ducky_fnc_delay,
 | 
				
			||||||
 | 
					        &ducky_fnc_string,
 | 
				
			||||||
 | 
					        &ducky_fnc_defdelay,
 | 
				
			||||||
 | 
					        &ducky_fnc_defdelay,
 | 
				
			||||||
 | 
					        &ducky_fnc_strdelay,
 | 
				
			||||||
 | 
					        &ducky_fnc_strdelay,
 | 
				
			||||||
 | 
					        &ducky_fnc_repeat,
 | 
				
			||||||
 | 
					        &ducky_fnc_sysrq,
 | 
				
			||||||
 | 
					        &ducky_fnc_altchar,
 | 
				
			||||||
 | 
					        &ducky_fnc_altstring,
 | 
				
			||||||
 | 
					        &ducky_fnc_altstring,
 | 
				
			||||||
 | 
					        &ducky_fnc_stringln,
 | 
				
			||||||
 | 
					        &ducky_fnc_hold,
 | 
				
			||||||
 | 
					        &ducky_fnc_release,
 | 
				
			||||||
 | 
					        NULL};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if(line_len == 0) {
 | 
					    if(line_len == 0) {
 | 
				
			||||||
        return SCRIPT_STATE_NEXT_LINE; // Skip empty lines
 | 
					        return SCRIPT_STATE_NEXT_LINE; // Skip empty lines
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    FURI_LOG_D(WORKER_TAG, "line:%s", line_tmp);
 | 
					    FURI_LOG_D(WORKER_TAG, "line:%s", line_tmp);
 | 
				
			||||||
 | 
					    // Ducky Lang Functions
 | 
				
			||||||
    // General commands
 | 
					    for(size_t i = 0; ducky_cmd_table[i]; i++) {
 | 
				
			||||||
    if(strncmp(line_tmp, ducky_cmd_comment, strlen(ducky_cmd_comment)) == 0) {
 | 
					        if(strncmp(line_tmp, ducky_cmd_table[i], strlen(ducky_cmd_table[i])) == 0)
 | 
				
			||||||
        // REM - comment line
 | 
					            return ((fnc_ptr[i])(bad_usb, line, line_tmp, error, error_len));
 | 
				
			||||||
        return (0);
 | 
					 | 
				
			||||||
    } else if(strncmp(line_tmp, ducky_cmd_id, strlen(ducky_cmd_id)) == 0) {
 | 
					 | 
				
			||||||
        // ID - executed in ducky_script_preload
 | 
					 | 
				
			||||||
        return (0);
 | 
					 | 
				
			||||||
    } else if(strncmp(line_tmp, ducky_cmd_delay, strlen(ducky_cmd_delay)) == 0) {
 | 
					 | 
				
			||||||
        // DELAY
 | 
					 | 
				
			||||||
        line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1];
 | 
					 | 
				
			||||||
        uint32_t delay_val = 0;
 | 
					 | 
				
			||||||
        state = ducky_get_number(line_tmp, &delay_val);
 | 
					 | 
				
			||||||
        if((state) && (delay_val > 0)) {
 | 
					 | 
				
			||||||
            return (int32_t)delay_val;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
        if(error != NULL) {
 | 
					 | 
				
			||||||
            snprintf(error, error_len, "Invalid number %s", line_tmp);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return SCRIPT_STATE_ERROR;
 | 
					 | 
				
			||||||
    } else if(
 | 
					 | 
				
			||||||
        (strncmp(line_tmp, ducky_cmd_defdelay_1, strlen(ducky_cmd_defdelay_1)) == 0) ||
 | 
					 | 
				
			||||||
        (strncmp(line_tmp, ducky_cmd_defdelay_2, strlen(ducky_cmd_defdelay_2)) == 0)) {
 | 
					 | 
				
			||||||
        // DEFAULT_DELAY
 | 
					 | 
				
			||||||
        line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1];
 | 
					 | 
				
			||||||
        state = ducky_get_number(line_tmp, &bad_usb->defdelay);
 | 
					 | 
				
			||||||
        if(!state && error != NULL) {
 | 
					 | 
				
			||||||
            snprintf(error, error_len, "Invalid number %s", line_tmp);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return (state) ? (0) : SCRIPT_STATE_ERROR;
 | 
					 | 
				
			||||||
    } else if(
 | 
					 | 
				
			||||||
        (strncmp(line_tmp, ducky_cmd_stringdelay_1, strlen(ducky_cmd_stringdelay_1)) == 0) ||
 | 
					 | 
				
			||||||
        (strncmp(line_tmp, ducky_cmd_stringdelay_2, strlen(ducky_cmd_stringdelay_2)) == 0)) {
 | 
					 | 
				
			||||||
        //STRINGDELAY, finally it's here
 | 
					 | 
				
			||||||
        line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1];
 | 
					 | 
				
			||||||
        state = ducky_get_number(line_tmp, &bad_usb->stringdelay);
 | 
					 | 
				
			||||||
        if((state) && (bad_usb->stringdelay > 0)) {
 | 
					 | 
				
			||||||
            return state;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if(error != NULL) {
 | 
					 | 
				
			||||||
            snprintf(error, error_len, "Invalid number %s", line_tmp);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return SCRIPT_STATE_ERROR;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    } else if(strncmp(line_tmp, ducky_cmd_string, strlen(ducky_cmd_string)) == 0) {
 | 
					 | 
				
			||||||
        // STRING
 | 
					 | 
				
			||||||
        line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1];
 | 
					 | 
				
			||||||
        state = ducky_string(bad_usb, line_tmp);
 | 
					 | 
				
			||||||
        if(!state && error != NULL) {
 | 
					 | 
				
			||||||
            snprintf(error, error_len, "Invalid string %s", line_tmp);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return (state) ? (0) : SCRIPT_STATE_ERROR;
 | 
					 | 
				
			||||||
    } else if(strncmp(line_tmp, ducky_cmd_altchar, strlen(ducky_cmd_altchar)) == 0) {
 | 
					 | 
				
			||||||
        // ALTCHAR
 | 
					 | 
				
			||||||
        line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1];
 | 
					 | 
				
			||||||
        ducky_numlock_on();
 | 
					 | 
				
			||||||
        state = ducky_altchar(line_tmp);
 | 
					 | 
				
			||||||
        if(!state && error != NULL) {
 | 
					 | 
				
			||||||
            snprintf(error, error_len, "Invalid altchar %s", line_tmp);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return (state) ? (0) : SCRIPT_STATE_ERROR;
 | 
					 | 
				
			||||||
    } else if(
 | 
					 | 
				
			||||||
        (strncmp(line_tmp, ducky_cmd_altstr_1, strlen(ducky_cmd_altstr_1)) == 0) ||
 | 
					 | 
				
			||||||
        (strncmp(line_tmp, ducky_cmd_altstr_2, strlen(ducky_cmd_altstr_2)) == 0)) {
 | 
					 | 
				
			||||||
        // ALTSTRING
 | 
					 | 
				
			||||||
        line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1];
 | 
					 | 
				
			||||||
        ducky_numlock_on();
 | 
					 | 
				
			||||||
        state = ducky_altstring(line_tmp);
 | 
					 | 
				
			||||||
        if(!state && error != NULL) {
 | 
					 | 
				
			||||||
            snprintf(error, error_len, "Invalid altstring %s", line_tmp);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return (state) ? (0) : SCRIPT_STATE_ERROR;
 | 
					 | 
				
			||||||
    } else if(strncmp(line_tmp, ducky_cmd_repeat, strlen(ducky_cmd_repeat)) == 0) {
 | 
					 | 
				
			||||||
        // REPEAT
 | 
					 | 
				
			||||||
        line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1];
 | 
					 | 
				
			||||||
        state = ducky_get_number(line_tmp, &bad_usb->repeat_cnt);
 | 
					 | 
				
			||||||
        if(!state && error != NULL) {
 | 
					 | 
				
			||||||
            snprintf(error, error_len, "Invalid number %s", line_tmp);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return (state) ? (0) : SCRIPT_STATE_ERROR;
 | 
					 | 
				
			||||||
    } else if(strncmp(line_tmp, ducky_cmd_sysrq, strlen(ducky_cmd_sysrq)) == 0) {
 | 
					 | 
				
			||||||
        // SYSRQ
 | 
					 | 
				
			||||||
        line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1];
 | 
					 | 
				
			||||||
        uint16_t key = ducky_get_keycode(bad_usb, line_tmp, true);
 | 
					 | 
				
			||||||
        furi_hal_hid_kb_press(KEY_MOD_LEFT_ALT | HID_KEYBOARD_PRINT_SCREEN);
 | 
					 | 
				
			||||||
        furi_hal_hid_kb_press(key);
 | 
					 | 
				
			||||||
        furi_hal_hid_kb_release_all();
 | 
					 | 
				
			||||||
        return (0);
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
    // Special keys + modifiers
 | 
					    // Special keys + modifiers
 | 
				
			||||||
    uint16_t key = ducky_get_keycode(bad_usb, line_tmp, false);
 | 
					    uint16_t key = ducky_get_keycode(bad_usb, line_tmp, false);
 | 
				
			||||||
    if(key == HID_KEYBOARD_NONE) {
 | 
					    if(key == HID_KEYBOARD_NONE) {
 | 
				
			||||||
@@ -360,7 +200,6 @@ static int32_t
 | 
				
			|||||||
    furi_hal_hid_kb_press(key);
 | 
					    furi_hal_hid_kb_press(key);
 | 
				
			||||||
    furi_hal_hid_kb_release(key);
 | 
					    furi_hal_hid_kb_release(key);
 | 
				
			||||||
    return (0);
 | 
					    return (0);
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool ducky_set_usb_id(BadUsbScript* bad_usb, const char* line) {
 | 
					static bool ducky_set_usb_id(BadUsbScript* bad_usb, const char* line) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,8 +5,9 @@ extern "C" {
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <furi.h>
 | 
					#include <furi.h>
 | 
				
			||||||
 | 
					#include <furi_hal.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct BadUsbScript BadUsbScript;
 | 
					#define FILE_BUFFER_LEN 16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef enum {
 | 
					typedef enum {
 | 
				
			||||||
    BadUsbStateInit,
 | 
					    BadUsbStateInit,
 | 
				
			||||||
@@ -29,6 +30,24 @@ typedef struct {
 | 
				
			|||||||
    char error[64];
 | 
					    char error[64];
 | 
				
			||||||
} BadUsbState;
 | 
					} BadUsbState;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct BadUsbScript {
 | 
				
			||||||
 | 
					    FuriHalUsbHidConfig hid_cfg;
 | 
				
			||||||
 | 
					    BadUsbState st;
 | 
				
			||||||
 | 
					    FuriString* file_path;
 | 
				
			||||||
 | 
					    uint32_t defdelay;
 | 
				
			||||||
 | 
					    uint16_t layout[128];
 | 
				
			||||||
 | 
					    uint32_t stringdelay;
 | 
				
			||||||
 | 
					    FuriThread* thread;
 | 
				
			||||||
 | 
					    uint8_t file_buf[FILE_BUFFER_LEN + 1];
 | 
				
			||||||
 | 
					    uint8_t buf_start;
 | 
				
			||||||
 | 
					    uint8_t buf_len;
 | 
				
			||||||
 | 
					    bool file_end;
 | 
				
			||||||
 | 
					    FuriString* line;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    FuriString* line_prev;
 | 
				
			||||||
 | 
					    uint32_t repeat_cnt;
 | 
				
			||||||
 | 
					} BadUsbScript;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
BadUsbScript* bad_usb_script_open(FuriString* file_path);
 | 
					BadUsbScript* bad_usb_script_open(FuriString* file_path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void bad_usb_script_close(BadUsbScript* bad_usb);
 | 
					void bad_usb_script_close(BadUsbScript* bad_usb);
 | 
				
			||||||
@@ -43,6 +62,12 @@ void bad_usb_script_toggle(BadUsbScript* bad_usb);
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
BadUsbState* bad_usb_script_get_state(BadUsbScript* bad_usb);
 | 
					BadUsbState* bad_usb_script_get_state(BadUsbScript* bad_usb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint16_t ducky_get_keycode(BadUsbScript* bad_usb, const char* param, bool accept_chars);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t ducky_get_command_len(const char* line);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool ducky_is_line_end(const char chr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										327
									
								
								applications/main/bad_usb/mnemonic.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										327
									
								
								applications/main/bad_usb/mnemonic.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,327 @@
 | 
				
			|||||||
 | 
					#include <furi_hal.h>
 | 
				
			||||||
 | 
					#include <furi_hal_usb_hid.h>
 | 
				
			||||||
 | 
					#include "mnemonic.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TAG "BadUSB"
 | 
				
			||||||
 | 
					#define WORKER_TAG TAG "Worker"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define FILE_BUFFER_LEN 16
 | 
				
			||||||
 | 
					#define SCRIPT_STATE_ERROR (-1)
 | 
				
			||||||
 | 
					#define SCRIPT_STATE_END (-2)
 | 
				
			||||||
 | 
					#define SCRIPT_STATE_NEXT_LINE (-3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define BADUSB_ASCII_TO_KEY(script, x) \
 | 
				
			||||||
 | 
					    (((uint8_t)x < 128) ? (script->layout[(uint8_t)x]) : HID_KEYBOARD_NONE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const uint8_t numpad_keys[10] = {
 | 
				
			||||||
 | 
					    HID_KEYPAD_0,
 | 
				
			||||||
 | 
					    HID_KEYPAD_1,
 | 
				
			||||||
 | 
					    HID_KEYPAD_2,
 | 
				
			||||||
 | 
					    HID_KEYPAD_3,
 | 
				
			||||||
 | 
					    HID_KEYPAD_4,
 | 
				
			||||||
 | 
					    HID_KEYPAD_5,
 | 
				
			||||||
 | 
					    HID_KEYPAD_6,
 | 
				
			||||||
 | 
					    HID_KEYPAD_7,
 | 
				
			||||||
 | 
					    HID_KEYPAD_8,
 | 
				
			||||||
 | 
					    HID_KEYPAD_9,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool ducky_get_number(const char* param, uint32_t* val) {
 | 
				
			||||||
 | 
					    uint32_t value = 0;
 | 
				
			||||||
 | 
					    if(sscanf(param, "%lu", &value) == 1) {
 | 
				
			||||||
 | 
					        *val = value;
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static bool ducky_numpad_press(const char num) {
 | 
				
			||||||
 | 
					    if((num < '0') || (num > '9')) return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint16_t key = numpad_keys[num - '0'];
 | 
				
			||||||
 | 
					    furi_hal_hid_kb_press(key);
 | 
				
			||||||
 | 
					    furi_hal_hid_kb_release(key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool ducky_altchar(const char* charcode) {
 | 
				
			||||||
 | 
					    uint8_t i = 0;
 | 
				
			||||||
 | 
					    bool state = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    FURI_LOG_I(WORKER_TAG, "char %s", charcode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    furi_hal_hid_kb_press(KEY_MOD_LEFT_ALT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while(!ducky_is_line_end(charcode[i])) {
 | 
				
			||||||
 | 
					        state = ducky_numpad_press(charcode[i]);
 | 
				
			||||||
 | 
					        if(state == false) break;
 | 
				
			||||||
 | 
					        i++;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    furi_hal_hid_kb_release(KEY_MOD_LEFT_ALT);
 | 
				
			||||||
 | 
					    return state;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool ducky_altstring(const char* param) {
 | 
				
			||||||
 | 
					    uint32_t i = 0;
 | 
				
			||||||
 | 
					    bool state = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while(param[i] != '\0') {
 | 
				
			||||||
 | 
					        if((param[i] < ' ') || (param[i] > '~')) {
 | 
				
			||||||
 | 
					            i++;
 | 
				
			||||||
 | 
					            continue; // Skip non-printable chars
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        char temp_str[4];
 | 
				
			||||||
 | 
					        snprintf(temp_str, 4, "%u", param[i]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        state = ducky_altchar(temp_str);
 | 
				
			||||||
 | 
					        if(state == false) break;
 | 
				
			||||||
 | 
					        i++;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return state;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool ducky_string(BadUsbScript* bad_usb, const char* param) {
 | 
				
			||||||
 | 
					    uint32_t i = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while(param[i] != '\0') {
 | 
				
			||||||
 | 
					        uint16_t keycode = BADUSB_ASCII_TO_KEY(bad_usb, param[i]);
 | 
				
			||||||
 | 
					        if(keycode != HID_KEYBOARD_NONE) {
 | 
				
			||||||
 | 
					            furi_hal_hid_kb_press(keycode);
 | 
				
			||||||
 | 
					            furi_hal_hid_kb_release(keycode);
 | 
				
			||||||
 | 
					            if(bad_usb->stringdelay > 0) {
 | 
				
			||||||
 | 
					                furi_delay_ms(bad_usb->stringdelay);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        i++;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    bad_usb->stringdelay = 0;
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int32_t ducky_fnc_noop(
 | 
				
			||||||
 | 
					    BadUsbScript* bad_usb,
 | 
				
			||||||
 | 
					    FuriString* line,
 | 
				
			||||||
 | 
					    const char* line_tmp,
 | 
				
			||||||
 | 
					    char* error,
 | 
				
			||||||
 | 
					    size_t error_len) {
 | 
				
			||||||
 | 
					    (void)bad_usb;
 | 
				
			||||||
 | 
					    (void)line;
 | 
				
			||||||
 | 
					    (void)line_tmp;
 | 
				
			||||||
 | 
					    (void)error;
 | 
				
			||||||
 | 
					    (void)error_len;
 | 
				
			||||||
 | 
					    return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int32_t ducky_fnc_delay(
 | 
				
			||||||
 | 
					    BadUsbScript* bad_usb,
 | 
				
			||||||
 | 
					    FuriString* line,
 | 
				
			||||||
 | 
					    const char* line_tmp,
 | 
				
			||||||
 | 
					    char* error,
 | 
				
			||||||
 | 
					    size_t error_len) {
 | 
				
			||||||
 | 
					    bool state = false;
 | 
				
			||||||
 | 
					    (void)bad_usb;
 | 
				
			||||||
 | 
					    (void)line;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1];
 | 
				
			||||||
 | 
					    uint32_t delay_val = 0;
 | 
				
			||||||
 | 
					    state = ducky_get_number(line_tmp, &delay_val);
 | 
				
			||||||
 | 
					    if((state) && (delay_val > 0)) {
 | 
				
			||||||
 | 
					        return (int32_t)delay_val;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if(error != NULL) {
 | 
				
			||||||
 | 
					        snprintf(error, error_len, "Invalid number %s", line_tmp);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return SCRIPT_STATE_ERROR;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int32_t ducky_fnc_defdelay(
 | 
				
			||||||
 | 
					    BadUsbScript* bad_usb,
 | 
				
			||||||
 | 
					    FuriString* line,
 | 
				
			||||||
 | 
					    const char* line_tmp,
 | 
				
			||||||
 | 
					    char* error,
 | 
				
			||||||
 | 
					    size_t error_len) {
 | 
				
			||||||
 | 
					    bool state = false;
 | 
				
			||||||
 | 
					    (void)line;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1];
 | 
				
			||||||
 | 
					    state = ducky_get_number(line_tmp, &bad_usb->defdelay);
 | 
				
			||||||
 | 
					    if(!state && error != NULL) {
 | 
				
			||||||
 | 
					        snprintf(error, error_len, "Invalid number %s", line_tmp);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return (state) ? (0) : SCRIPT_STATE_ERROR;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int32_t ducky_fnc_strdelay(
 | 
				
			||||||
 | 
					    BadUsbScript* bad_usb,
 | 
				
			||||||
 | 
					    FuriString* line,
 | 
				
			||||||
 | 
					    const char* line_tmp,
 | 
				
			||||||
 | 
					    char* error,
 | 
				
			||||||
 | 
					    size_t error_len) {
 | 
				
			||||||
 | 
					    bool state = false;
 | 
				
			||||||
 | 
					    (void)line;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1];
 | 
				
			||||||
 | 
					    state = ducky_get_number(line_tmp, &bad_usb->stringdelay);
 | 
				
			||||||
 | 
					    if((state) && (bad_usb->stringdelay > 0)) {
 | 
				
			||||||
 | 
					        return state;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if(error != NULL) {
 | 
				
			||||||
 | 
					        snprintf(error, error_len, "Invalid number %s", line_tmp);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return SCRIPT_STATE_ERROR;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int32_t ducky_fnc_string(
 | 
				
			||||||
 | 
					    BadUsbScript* bad_usb,
 | 
				
			||||||
 | 
					    FuriString* line,
 | 
				
			||||||
 | 
					    const char* line_tmp,
 | 
				
			||||||
 | 
					    char* error,
 | 
				
			||||||
 | 
					    size_t error_len) {
 | 
				
			||||||
 | 
					    bool state = false;
 | 
				
			||||||
 | 
					    (void)line;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1];
 | 
				
			||||||
 | 
					    state = ducky_string(bad_usb, line_tmp);
 | 
				
			||||||
 | 
					    if(!state && error != NULL) {
 | 
				
			||||||
 | 
					        snprintf(error, error_len, "Invalid string %s", line_tmp);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return (state) ? (0) : SCRIPT_STATE_ERROR;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int32_t ducky_fnc_repeat(
 | 
				
			||||||
 | 
					    BadUsbScript* bad_usb,
 | 
				
			||||||
 | 
					    FuriString* line,
 | 
				
			||||||
 | 
					    const char* line_tmp,
 | 
				
			||||||
 | 
					    char* error,
 | 
				
			||||||
 | 
					    size_t error_len) {
 | 
				
			||||||
 | 
					    bool state = false;
 | 
				
			||||||
 | 
					    (void)line;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1];
 | 
				
			||||||
 | 
					    state = ducky_get_number(line_tmp, &bad_usb->repeat_cnt);
 | 
				
			||||||
 | 
					    if(!state && error != NULL) {
 | 
				
			||||||
 | 
					        snprintf(error, error_len, "Invalid number %s", line_tmp);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return (state) ? (0) : SCRIPT_STATE_ERROR;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int32_t ducky_fnc_sysrq(
 | 
				
			||||||
 | 
					    BadUsbScript* bad_usb,
 | 
				
			||||||
 | 
					    FuriString* line,
 | 
				
			||||||
 | 
					    const char* line_tmp,
 | 
				
			||||||
 | 
					    char* error,
 | 
				
			||||||
 | 
					    size_t error_len) {
 | 
				
			||||||
 | 
					    (void)error;
 | 
				
			||||||
 | 
					    (void)error_len;
 | 
				
			||||||
 | 
					    (void)line;
 | 
				
			||||||
 | 
					    line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1];
 | 
				
			||||||
 | 
					    uint16_t key = ducky_get_keycode(bad_usb, line_tmp, true);
 | 
				
			||||||
 | 
					    furi_hal_hid_kb_press(KEY_MOD_LEFT_ALT | HID_KEYBOARD_PRINT_SCREEN);
 | 
				
			||||||
 | 
					    furi_hal_hid_kb_press(key);
 | 
				
			||||||
 | 
					    furi_hal_hid_kb_release_all();
 | 
				
			||||||
 | 
					    return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int32_t ducky_fnc_altchar(
 | 
				
			||||||
 | 
					    BadUsbScript* bad_usb,
 | 
				
			||||||
 | 
					    FuriString* line,
 | 
				
			||||||
 | 
					    const char* line_tmp,
 | 
				
			||||||
 | 
					    char* error,
 | 
				
			||||||
 | 
					    size_t error_len) {
 | 
				
			||||||
 | 
					    bool state = false;
 | 
				
			||||||
 | 
					    (void)bad_usb;
 | 
				
			||||||
 | 
					    (void)line;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1];
 | 
				
			||||||
 | 
					    ducky_numlock_on();
 | 
				
			||||||
 | 
					    state = ducky_altchar(line_tmp);
 | 
				
			||||||
 | 
					    if(!state && error != NULL) {
 | 
				
			||||||
 | 
					        snprintf(error, error_len, "Invalid altchar %s", line_tmp);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return (state) ? (0) : SCRIPT_STATE_ERROR;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int32_t ducky_fnc_altstring(
 | 
				
			||||||
 | 
					    BadUsbScript* bad_usb,
 | 
				
			||||||
 | 
					    FuriString* line,
 | 
				
			||||||
 | 
					    const char* line_tmp,
 | 
				
			||||||
 | 
					    char* error,
 | 
				
			||||||
 | 
					    size_t error_len) {
 | 
				
			||||||
 | 
					    bool state = false;
 | 
				
			||||||
 | 
					    (void)bad_usb;
 | 
				
			||||||
 | 
					    (void)line;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1];
 | 
				
			||||||
 | 
					    ducky_numlock_on();
 | 
				
			||||||
 | 
					    state = ducky_altstring(line_tmp);
 | 
				
			||||||
 | 
					    if(!state && error != NULL) {
 | 
				
			||||||
 | 
					        snprintf(error, error_len, "Invalid altstring %s", line_tmp);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return (state) ? (0) : SCRIPT_STATE_ERROR;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int32_t ducky_fnc_stringln(
 | 
				
			||||||
 | 
					    BadUsbScript* bad_usb,
 | 
				
			||||||
 | 
					    FuriString* line,
 | 
				
			||||||
 | 
					    const char* line_tmp,
 | 
				
			||||||
 | 
					    char* error,
 | 
				
			||||||
 | 
					    size_t error_len) {
 | 
				
			||||||
 | 
					    bool state = false;
 | 
				
			||||||
 | 
					    (void)line;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1];
 | 
				
			||||||
 | 
					    state = ducky_string(bad_usb, line_tmp);
 | 
				
			||||||
 | 
					    if(!state && error != NULL) {
 | 
				
			||||||
 | 
					        snprintf(error, error_len, "Invalid string %s", line_tmp);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    furi_hal_hid_kb_press(HID_KEYBOARD_RETURN);
 | 
				
			||||||
 | 
					    furi_hal_hid_kb_release(HID_KEYBOARD_RETURN);
 | 
				
			||||||
 | 
					    return (state) ? (0) : SCRIPT_STATE_ERROR;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int32_t ducky_fnc_hold(
 | 
				
			||||||
 | 
					    BadUsbScript* bad_usb,
 | 
				
			||||||
 | 
					    FuriString* line,
 | 
				
			||||||
 | 
					    const char* line_tmp,
 | 
				
			||||||
 | 
					    char* error,
 | 
				
			||||||
 | 
					    size_t error_len) {
 | 
				
			||||||
 | 
					    (void)line;
 | 
				
			||||||
 | 
					    line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1];
 | 
				
			||||||
 | 
					    uint16_t key = ducky_get_keycode(bad_usb, line_tmp, true);
 | 
				
			||||||
 | 
					    if(key == HID_KEYBOARD_NONE) {
 | 
				
			||||||
 | 
					        if(error != NULL) {
 | 
				
			||||||
 | 
					            snprintf(error, error_len, "No keycode defined for %s", line_tmp);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return SCRIPT_STATE_ERROR;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    furi_hal_hid_kb_press(key);
 | 
				
			||||||
 | 
					    return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int32_t ducky_fnc_release(
 | 
				
			||||||
 | 
					    BadUsbScript* bad_usb,
 | 
				
			||||||
 | 
					    FuriString* line,
 | 
				
			||||||
 | 
					    const char* line_tmp,
 | 
				
			||||||
 | 
					    char* error,
 | 
				
			||||||
 | 
					    size_t error_len) {
 | 
				
			||||||
 | 
					    (void)line;
 | 
				
			||||||
 | 
					    line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1];
 | 
				
			||||||
 | 
					    uint16_t key = ducky_get_keycode(bad_usb, line_tmp, true);
 | 
				
			||||||
 | 
					    if(key == HID_KEYBOARD_NONE) {
 | 
				
			||||||
 | 
					        if(error != NULL) {
 | 
				
			||||||
 | 
					            snprintf(error, error_len, "No keycode defined for %s", line_tmp);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return SCRIPT_STATE_ERROR;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    furi_hal_hid_kb_release(key);
 | 
				
			||||||
 | 
					    return (0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										96
									
								
								applications/main/bad_usb/mnemonic.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								applications/main/bad_usb/mnemonic.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,96 @@
 | 
				
			|||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					extern "C" {
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "bad_usb_script.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// A no opperation function
 | 
				
			||||||
 | 
					int32_t ducky_fnc_noop(
 | 
				
			||||||
 | 
					    BadUsbScript* bad_usb,
 | 
				
			||||||
 | 
					    FuriString* line,
 | 
				
			||||||
 | 
					    const char* line_tmp,
 | 
				
			||||||
 | 
					    char* error,
 | 
				
			||||||
 | 
					    size_t error_len);
 | 
				
			||||||
 | 
					// DELAY
 | 
				
			||||||
 | 
					int32_t ducky_fnc_delay(
 | 
				
			||||||
 | 
					    BadUsbScript* bad_usb,
 | 
				
			||||||
 | 
					    FuriString* line,
 | 
				
			||||||
 | 
					    const char* line_tmp,
 | 
				
			||||||
 | 
					    char* error,
 | 
				
			||||||
 | 
					    size_t error_len);
 | 
				
			||||||
 | 
					// DEFAULTDELAY
 | 
				
			||||||
 | 
					int32_t ducky_fnc_defdelay(
 | 
				
			||||||
 | 
					    BadUsbScript* bad_usb,
 | 
				
			||||||
 | 
					    FuriString* line,
 | 
				
			||||||
 | 
					    const char* line_tmp,
 | 
				
			||||||
 | 
					    char* error,
 | 
				
			||||||
 | 
					    size_t error_len);
 | 
				
			||||||
 | 
					// STRINGDELAY
 | 
				
			||||||
 | 
					int32_t ducky_fnc_strdelay(
 | 
				
			||||||
 | 
					    BadUsbScript* bad_usb,
 | 
				
			||||||
 | 
					    FuriString* line,
 | 
				
			||||||
 | 
					    const char* line_tmp,
 | 
				
			||||||
 | 
					    char* error,
 | 
				
			||||||
 | 
					    size_t error_len);
 | 
				
			||||||
 | 
					// STRING
 | 
				
			||||||
 | 
					int32_t ducky_fnc_string(
 | 
				
			||||||
 | 
					    BadUsbScript* bad_usb,
 | 
				
			||||||
 | 
					    FuriString* line,
 | 
				
			||||||
 | 
					    const char* line_tmp,
 | 
				
			||||||
 | 
					    char* error,
 | 
				
			||||||
 | 
					    size_t error_len);
 | 
				
			||||||
 | 
					// STRINGLN
 | 
				
			||||||
 | 
					int32_t ducky_fnc_stringln(
 | 
				
			||||||
 | 
					    BadUsbScript* bad_usb,
 | 
				
			||||||
 | 
					    FuriString* line,
 | 
				
			||||||
 | 
					    const char* line_tmp,
 | 
				
			||||||
 | 
					    char* error,
 | 
				
			||||||
 | 
					    size_t error_len);
 | 
				
			||||||
 | 
					// REPEAT
 | 
				
			||||||
 | 
					int32_t ducky_fnc_repeat(
 | 
				
			||||||
 | 
					    BadUsbScript* bad_usb,
 | 
				
			||||||
 | 
					    FuriString* line,
 | 
				
			||||||
 | 
					    const char* line_tmp,
 | 
				
			||||||
 | 
					    char* error,
 | 
				
			||||||
 | 
					    size_t error_len);
 | 
				
			||||||
 | 
					// SYSRQ
 | 
				
			||||||
 | 
					int32_t ducky_fnc_sysrq(
 | 
				
			||||||
 | 
					    BadUsbScript* bad_usb,
 | 
				
			||||||
 | 
					    FuriString* line,
 | 
				
			||||||
 | 
					    const char* line_tmp,
 | 
				
			||||||
 | 
					    char* error,
 | 
				
			||||||
 | 
					    size_t error_len);
 | 
				
			||||||
 | 
					// ALTCHAR
 | 
				
			||||||
 | 
					int32_t ducky_fnc_altchar(
 | 
				
			||||||
 | 
					    BadUsbScript* bad_usb,
 | 
				
			||||||
 | 
					    FuriString* line,
 | 
				
			||||||
 | 
					    const char* line_tmp,
 | 
				
			||||||
 | 
					    char* error,
 | 
				
			||||||
 | 
					    size_t error_len);
 | 
				
			||||||
 | 
					// ALTSTRING
 | 
				
			||||||
 | 
					int32_t ducky_fnc_altstring(
 | 
				
			||||||
 | 
					    BadUsbScript* bad_usb,
 | 
				
			||||||
 | 
					    FuriString* line,
 | 
				
			||||||
 | 
					    const char* line_tmp,
 | 
				
			||||||
 | 
					    char* error,
 | 
				
			||||||
 | 
					    size_t error_len);
 | 
				
			||||||
 | 
					// HOLD
 | 
				
			||||||
 | 
					int32_t ducky_fnc_hold(
 | 
				
			||||||
 | 
					    BadUsbScript* bad_usb,
 | 
				
			||||||
 | 
					    FuriString* line,
 | 
				
			||||||
 | 
					    const char* line_tmp,
 | 
				
			||||||
 | 
					    char* error,
 | 
				
			||||||
 | 
					    size_t error_len);
 | 
				
			||||||
 | 
					// RELEASE
 | 
				
			||||||
 | 
					int32_t ducky_fnc_release(
 | 
				
			||||||
 | 
					    BadUsbScript* bad_usb,
 | 
				
			||||||
 | 
					    FuriString* line,
 | 
				
			||||||
 | 
					    const char* line_tmp,
 | 
				
			||||||
 | 
					    char* error,
 | 
				
			||||||
 | 
					    size_t error_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
		Reference in New Issue
	
	Block a user