Badusb: show script errors on screen (#1506)
Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
		| @@ -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"); | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user