Просмотр исходного кода

Badusb: show script errors on screen (#1506)

Co-authored-by: あく <alleteam@gmail.com>
Thibaut CHARLES 3 лет назад
Родитель
Сommit
ede3bac799

+ 35 - 4
applications/main/bad_usb/bad_usb_script.c

@@ -231,7 +231,8 @@ static uint16_t ducky_get_keycode(const char* param, bool accept_chars) {
     return 0;
 }
 
-static int32_t ducky_parse_line(BadUsbScript* bad_usb, FuriString* line) {
+static int32_t
+    ducky_parse_line(BadUsbScript* bad_usb, FuriString* line, char* error, size_t error_len) {
     uint32_t line_len = furi_string_size(line);
     const char* line_tmp = furi_string_get_cstr(line);
     bool state = false;
@@ -261,6 +262,9 @@ static int32_t ducky_parse_line(BadUsbScript* bad_usb, FuriString* line) {
         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) ||
@@ -268,17 +272,26 @@ static int32_t ducky_parse_line(BadUsbScript* bad_usb, FuriString* line) {
         // 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_string, strlen(ducky_cmd_string)) == 0) {
         // STRING
         line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1];
         state = ducky_string(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) ||
@@ -287,11 +300,17 @@ static int32_t ducky_parse_line(BadUsbScript* bad_usb, FuriString* 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;
     } 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
@@ -304,7 +323,12 @@ static int32_t ducky_parse_line(BadUsbScript* bad_usb, FuriString* line) {
     } else {
         // Special keys + modifiers
         uint16_t key = ducky_get_keycode(line_tmp, false);
-        if(key == HID_KEYBOARD_NONE) return SCRIPT_STATE_ERROR;
+        if(key == HID_KEYBOARD_NONE) {
+            if(error != NULL) {
+                snprintf(error, error_len, "No keycode defined for %s", line_tmp);
+            }
+            return SCRIPT_STATE_ERROR;
+        }
         if((key & 0xFF00) != 0) {
             // It's a modifier key
             line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1];
@@ -314,6 +338,9 @@ static int32_t ducky_parse_line(BadUsbScript* bad_usb, FuriString* line) {
         furi_hal_hid_kb_release(key);
         return (0);
     }
+    if(error != NULL) {
+        strncpy(error, "Unknown error", error_len);
+    }
     return SCRIPT_STATE_ERROR;
 }
 
@@ -392,7 +419,8 @@ static int32_t ducky_script_execute_next(BadUsbScript* bad_usb, File* script_fil
 
     if(bad_usb->repeat_cnt > 0) {
         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, bad_usb->st.error, sizeof(bad_usb->st.error));
         if(delay_val == SCRIPT_STATE_NEXT_LINE) { // Empty line
             return 0;
         } else if(delay_val < 0) { // Script error
@@ -426,7 +454,9 @@ static int32_t ducky_script_execute_next(BadUsbScript* bad_usb, File* script_fil
                 bad_usb->st.line_cur++;
                 bad_usb->buf_len = bad_usb->buf_len + bad_usb->buf_start - (i + 1);
                 bad_usb->buf_start = i + 1;
-                delay_val = ducky_parse_line(bad_usb, bad_usb->line);
+                delay_val = ducky_parse_line(
+                    bad_usb, bad_usb->line, bad_usb->st.error, sizeof(bad_usb->st.error));
+
                 if(delay_val < 0) {
                     bad_usb->st.error_line = bad_usb->st.line_cur;
                     FURI_LOG_E(WORKER_TAG, "Unknown command at line %u", bad_usb->st.line_cur);
@@ -602,6 +632,7 @@ BadUsbScript* bad_usb_script_open(FuriString* file_path) {
     furi_string_set(bad_usb->file_path, file_path);
 
     bad_usb->st.state = BadUsbStateInit;
+    bad_usb->st.error[0] = '\0';
 
     bad_usb->thread = furi_thread_alloc();
     furi_thread_set_name(bad_usb->thread, "BadUsbWorker");

+ 1 - 0
applications/main/bad_usb/bad_usb_script.h

@@ -25,6 +25,7 @@ typedef struct {
     uint16_t line_nb;
     uint32_t delay_remain;
     uint16_t error_line;
+    char error[64];
 } BadUsbState;
 
 BadUsbScript* bad_usb_script_open(FuriString* file_path);

+ 1 - 0
applications/main/bad_usb/views/bad_usb_view.c

@@ -53,6 +53,7 @@ static void bad_usb_draw_callback(Canvas* canvas, void* _model) {
         canvas_draw_str_aligned(
             canvas, 127, 46, AlignRight, AlignBottom, furi_string_get_cstr(disp_str));
         furi_string_reset(disp_str);
+        canvas_draw_str_aligned(canvas, 127, 56, AlignRight, AlignBottom, model->state.error);
     } else if(model->state.state == BadUsbStateIdle) {
         canvas_draw_icon(canvas, 4, 22, &I_Smile_18x18);
         canvas_set_font(canvas, FontBigNumbers);