BadUSB: fix \r\n line endings (#1017)
* fix to support badusb scripts with \r\n line endings * forgotten todo removed * get rid of magic numbers Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
parent
1251c0af83
commit
b3ccdf74c8
@ -12,12 +12,15 @@
|
|||||||
#define WORKER_TAG TAG "Worker"
|
#define WORKER_TAG TAG "Worker"
|
||||||
#define FILE_BUFFER_LEN 16
|
#define FILE_BUFFER_LEN 16
|
||||||
|
|
||||||
|
#define SCRIPT_STATE_ERROR (-1)
|
||||||
|
#define SCRIPT_STATE_END (-2)
|
||||||
|
#define SCRIPT_STATE_NEXT_LINE (-3)
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
WorkerEvtReserved = (1 << 0),
|
WorkerEvtToggle = (1 << 0),
|
||||||
WorkerEvtToggle = (1 << 1),
|
WorkerEvtEnd = (1 << 1),
|
||||||
WorkerEvtEnd = (1 << 2),
|
WorkerEvtConnect = (1 << 2),
|
||||||
WorkerEvtConnect = (1 << 3),
|
WorkerEvtDisconnect = (1 << 3),
|
||||||
WorkerEvtDisconnect = (1 << 4),
|
|
||||||
} WorkerEvtFlags;
|
} WorkerEvtFlags;
|
||||||
|
|
||||||
struct BadUsbScript {
|
struct BadUsbScript {
|
||||||
@ -138,6 +141,10 @@ static uint32_t ducky_get_command_len(const char* line) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool ducky_is_line_end(const char chr) {
|
||||||
|
return ((chr == ' ') || (chr == '\0') || (chr == '\r') || (chr == '\n'));
|
||||||
|
}
|
||||||
|
|
||||||
static void ducky_numlock_on() {
|
static void ducky_numlock_on() {
|
||||||
if((furi_hal_hid_get_led_state() & HID_KB_LED_NUM) == 0) {
|
if((furi_hal_hid_get_led_state() & HID_KB_LED_NUM) == 0) {
|
||||||
furi_hal_hid_kb_press(KEY_NUM_LOCK);
|
furi_hal_hid_kb_press(KEY_NUM_LOCK);
|
||||||
@ -163,7 +170,7 @@ static bool ducky_altchar(const char* charcode) {
|
|||||||
|
|
||||||
furi_hal_hid_kb_press(KEY_MOD_LEFT_ALT);
|
furi_hal_hid_kb_press(KEY_MOD_LEFT_ALT);
|
||||||
|
|
||||||
while((charcode[i] != ' ') && (charcode[i] != '\n') && (charcode[i] != '\0')) {
|
while(!ducky_is_line_end(charcode[i])) {
|
||||||
state = ducky_numpad_press(charcode[i]);
|
state = ducky_numpad_press(charcode[i]);
|
||||||
if(state == false) break;
|
if(state == false) break;
|
||||||
i++;
|
i++;
|
||||||
@ -196,8 +203,11 @@ static bool ducky_altstring(const char* param) {
|
|||||||
static bool ducky_string(const char* param) {
|
static bool ducky_string(const char* param) {
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
while(param[i] != '\0') {
|
while(param[i] != '\0') {
|
||||||
furi_hal_hid_kb_press(HID_ASCII_TO_KEY(param[i]));
|
uint16_t keycode = HID_ASCII_TO_KEY(param[i]);
|
||||||
furi_hal_hid_kb_release(HID_ASCII_TO_KEY(param[i]));
|
if(keycode != KEY_NONE) {
|
||||||
|
furi_hal_hid_kb_press(keycode);
|
||||||
|
furi_hal_hid_kb_release(keycode);
|
||||||
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -207,8 +217,7 @@ static uint16_t ducky_get_keycode(const char* param, bool accept_chars) {
|
|||||||
for(uint8_t i = 0; i < (sizeof(ducky_keys) / sizeof(ducky_keys[0])); i++) {
|
for(uint8_t i = 0; i < (sizeof(ducky_keys) / sizeof(ducky_keys[0])); i++) {
|
||||||
uint8_t key_cmd_len = strlen(ducky_keys[i].name);
|
uint8_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) &&
|
||||||
((param[key_cmd_len] == ' ') || (param[key_cmd_len] == '\n') ||
|
(ducky_is_line_end(param[key_cmd_len]))) {
|
||||||
(param[key_cmd_len] == '\0'))) {
|
|
||||||
return ducky_keys[i].keycode;
|
return ducky_keys[i].keycode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -228,7 +237,7 @@ static int32_t ducky_parse_line(BadUsbScript* bad_usb, string_t line) {
|
|||||||
line_tmp = &line_tmp[i];
|
line_tmp = &line_tmp[i];
|
||||||
break; // Skip spaces and tabs
|
break; // Skip spaces and tabs
|
||||||
}
|
}
|
||||||
if(i == line_len - 1) return 0; // Skip empty lines
|
if(i == line_len - 1) return SCRIPT_STATE_NEXT_LINE; // Skip empty lines
|
||||||
}
|
}
|
||||||
|
|
||||||
FURI_LOG_I(WORKER_TAG, "line:%s", line_tmp);
|
FURI_LOG_I(WORKER_TAG, "line:%s", line_tmp);
|
||||||
@ -245,25 +254,25 @@ static int32_t ducky_parse_line(BadUsbScript* bad_usb, string_t line) {
|
|||||||
if((state) && (delay_val > 0)) {
|
if((state) && (delay_val > 0)) {
|
||||||
return (int32_t)delay_val;
|
return (int32_t)delay_val;
|
||||||
}
|
}
|
||||||
return (-1);
|
return SCRIPT_STATE_ERROR;
|
||||||
} else if(
|
} else if(
|
||||||
(strncmp(line_tmp, ducky_cmd_defdelay_1, strlen(ducky_cmd_defdelay_1)) == 0) ||
|
(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)) {
|
(strncmp(line_tmp, ducky_cmd_defdelay_2, strlen(ducky_cmd_defdelay_2)) == 0)) {
|
||||||
// DEFAULT_DELAY
|
// DEFAULT_DELAY
|
||||||
line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1];
|
line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1];
|
||||||
state = ducky_get_number(line_tmp, &bad_usb->defdelay);
|
state = ducky_get_number(line_tmp, &bad_usb->defdelay);
|
||||||
return (state) ? (0) : (-1);
|
return (state) ? (0) : SCRIPT_STATE_ERROR;
|
||||||
} else if(strncmp(line_tmp, ducky_cmd_string, strlen(ducky_cmd_string)) == 0) {
|
} else if(strncmp(line_tmp, ducky_cmd_string, strlen(ducky_cmd_string)) == 0) {
|
||||||
// STRING
|
// STRING
|
||||||
line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1];
|
line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1];
|
||||||
state = ducky_string(line_tmp);
|
state = ducky_string(line_tmp);
|
||||||
return (state) ? (0) : (-1);
|
return (state) ? (0) : SCRIPT_STATE_ERROR;
|
||||||
} else if(strncmp(line_tmp, ducky_cmd_altchar, strlen(ducky_cmd_altchar)) == 0) {
|
} else if(strncmp(line_tmp, ducky_cmd_altchar, strlen(ducky_cmd_altchar)) == 0) {
|
||||||
// ALTCHAR
|
// ALTCHAR
|
||||||
line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1];
|
line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1];
|
||||||
ducky_numlock_on();
|
ducky_numlock_on();
|
||||||
state = ducky_altchar(line_tmp);
|
state = ducky_altchar(line_tmp);
|
||||||
return (state) ? (0) : (-1);
|
return (state) ? (0) : SCRIPT_STATE_ERROR;
|
||||||
} else if(
|
} else if(
|
||||||
(strncmp(line_tmp, ducky_cmd_altstr_1, strlen(ducky_cmd_altstr_1)) == 0) ||
|
(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)) {
|
(strncmp(line_tmp, ducky_cmd_altstr_2, strlen(ducky_cmd_altstr_2)) == 0)) {
|
||||||
@ -271,16 +280,16 @@ static int32_t ducky_parse_line(BadUsbScript* bad_usb, string_t line) {
|
|||||||
line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1];
|
line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1];
|
||||||
ducky_numlock_on();
|
ducky_numlock_on();
|
||||||
state = ducky_altstring(line_tmp);
|
state = ducky_altstring(line_tmp);
|
||||||
return (state) ? (0) : (-1);
|
return (state) ? (0) : SCRIPT_STATE_ERROR;
|
||||||
} else if(strncmp(line_tmp, ducky_cmd_repeat, strlen(ducky_cmd_repeat)) == 0) {
|
} else if(strncmp(line_tmp, ducky_cmd_repeat, strlen(ducky_cmd_repeat)) == 0) {
|
||||||
// REPEAT
|
// REPEAT
|
||||||
line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1];
|
line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1];
|
||||||
state = ducky_get_number(line_tmp, &bad_usb->repeat_cnt);
|
state = ducky_get_number(line_tmp, &bad_usb->repeat_cnt);
|
||||||
return (state) ? (0) : (-1);
|
return (state) ? (0) : SCRIPT_STATE_ERROR;
|
||||||
} else {
|
} else {
|
||||||
// Special keys + modifiers
|
// Special keys + modifiers
|
||||||
uint16_t key = ducky_get_keycode(line_tmp, false);
|
uint16_t key = ducky_get_keycode(line_tmp, false);
|
||||||
if(key == KEY_NONE) return (-1);
|
if(key == KEY_NONE) return SCRIPT_STATE_ERROR;
|
||||||
if((key & 0xFF00) != 0) {
|
if((key & 0xFF00) != 0) {
|
||||||
// It's a modifier key
|
// It's a modifier key
|
||||||
line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1];
|
line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1];
|
||||||
@ -290,7 +299,7 @@ static int32_t ducky_parse_line(BadUsbScript* bad_usb, string_t line) {
|
|||||||
furi_hal_hid_kb_release(key);
|
furi_hal_hid_kb_release(key);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
return (-1);
|
return SCRIPT_STATE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ducky_script_preload(BadUsbScript* bad_usb, File* script_file) {
|
static bool ducky_script_preload(BadUsbScript* bad_usb, File* script_file) {
|
||||||
@ -326,10 +335,12 @@ static int32_t ducky_script_execute_next(BadUsbScript* bad_usb, File* script_fil
|
|||||||
if(bad_usb->repeat_cnt > 0) {
|
if(bad_usb->repeat_cnt > 0) {
|
||||||
bad_usb->repeat_cnt--;
|
bad_usb->repeat_cnt--;
|
||||||
delay_val = ducky_parse_line(bad_usb, bad_usb->line_prev);
|
delay_val = ducky_parse_line(bad_usb, bad_usb->line_prev);
|
||||||
if(delay_val < 0) {
|
if(delay_val == SCRIPT_STATE_NEXT_LINE) { // Empty line
|
||||||
|
return 0;
|
||||||
|
} else if(delay_val < 0) { // Script error
|
||||||
bad_usb->st.error_line = bad_usb->st.line_cur - 1;
|
bad_usb->st.error_line = bad_usb->st.line_cur - 1;
|
||||||
FURI_LOG_E(WORKER_TAG, "Unknown command at line %lu", bad_usb->st.line_cur - 1);
|
FURI_LOG_E(WORKER_TAG, "Unknown command at line %lu", bad_usb->st.line_cur - 1);
|
||||||
return (-1);
|
return SCRIPT_STATE_ERROR;
|
||||||
} else {
|
} else {
|
||||||
return (delay_val + bad_usb->defdelay);
|
return (delay_val + bad_usb->defdelay);
|
||||||
}
|
}
|
||||||
@ -350,7 +361,7 @@ static int32_t ducky_script_execute_next(BadUsbScript* bad_usb, File* script_fil
|
|||||||
}
|
}
|
||||||
|
|
||||||
bad_usb->buf_start = 0;
|
bad_usb->buf_start = 0;
|
||||||
if(bad_usb->buf_len == 0) return (-2);
|
if(bad_usb->buf_len == 0) return SCRIPT_STATE_END;
|
||||||
}
|
}
|
||||||
for(uint8_t i = bad_usb->buf_start; i < (bad_usb->buf_start + bad_usb->buf_len); i++) {
|
for(uint8_t i = bad_usb->buf_start; i < (bad_usb->buf_start + bad_usb->buf_len); i++) {
|
||||||
if(bad_usb->file_buf[i] == '\n' && string_size(bad_usb->line) > 0) {
|
if(bad_usb->file_buf[i] == '\n' && string_size(bad_usb->line) > 0) {
|
||||||
@ -361,7 +372,7 @@ static int32_t ducky_script_execute_next(BadUsbScript* bad_usb, File* script_fil
|
|||||||
if(delay_val < 0) {
|
if(delay_val < 0) {
|
||||||
bad_usb->st.error_line = bad_usb->st.line_cur;
|
bad_usb->st.error_line = bad_usb->st.line_cur;
|
||||||
FURI_LOG_E(WORKER_TAG, "Unknown command at line %lu", bad_usb->st.line_cur);
|
FURI_LOG_E(WORKER_TAG, "Unknown command at line %lu", bad_usb->st.line_cur);
|
||||||
return (-1);
|
return SCRIPT_STATE_ERROR;
|
||||||
} else {
|
} else {
|
||||||
return (delay_val + bad_usb->defdelay);
|
return (delay_val + bad_usb->defdelay);
|
||||||
}
|
}
|
||||||
@ -370,7 +381,7 @@ static int32_t ducky_script_execute_next(BadUsbScript* bad_usb, File* script_fil
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
bad_usb->buf_len = 0;
|
bad_usb->buf_len = 0;
|
||||||
if(bad_usb->file_end) return (-2);
|
if(bad_usb->file_end) return SCRIPT_STATE_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -479,11 +490,11 @@ static int32_t bad_usb_worker(void* context) {
|
|||||||
}
|
}
|
||||||
bad_usb->st.state = BadUsbStateRunning;
|
bad_usb->st.state = BadUsbStateRunning;
|
||||||
delay_val = ducky_script_execute_next(bad_usb, script_file);
|
delay_val = ducky_script_execute_next(bad_usb, script_file);
|
||||||
if(delay_val == -1) { // Script error
|
if(delay_val == SCRIPT_STATE_ERROR) { // Script error
|
||||||
delay_val = 0;
|
delay_val = 0;
|
||||||
worker_state = BadUsbStateScriptError;
|
worker_state = BadUsbStateScriptError;
|
||||||
bad_usb->st.state = worker_state;
|
bad_usb->st.state = worker_state;
|
||||||
} else if(delay_val == -2) { // End of script
|
} else if(delay_val == SCRIPT_STATE_END) { // End of script
|
||||||
delay_val = 0;
|
delay_val = 0;
|
||||||
worker_state = BadUsbStateIdle;
|
worker_state = BadUsbStateIdle;
|
||||||
bad_usb->st.state = BadUsbStateDone;
|
bad_usb->st.state = BadUsbStateDone;
|
||||||
|
Loading…
Reference in New Issue
Block a user