BdUSBadded WAIT_FOR_BUTTON_PRESS functionality (#2544)
Co-authored-by: p4p1 <p4p1@vivaldi.net> Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
		| @@ -283,6 +283,10 @@ static int32_t ducky_script_execute_next(BadUsbScript* bad_usb, File* script_fil | |||||||
|         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 == SCRIPT_STATE_NEXT_LINE) { // Empty line |         if(delay_val == SCRIPT_STATE_NEXT_LINE) { // Empty line | ||||||
|             return 0; |             return 0; | ||||||
|  |         } else if(delay_val == SCRIPT_STATE_STRING_START) { // Print string with delays | ||||||
|  |             return delay_val; | ||||||
|  |         } else if(delay_val == SCRIPT_STATE_WAIT_FOR_BTN) { // wait for button | ||||||
|  |             return delay_val; | ||||||
|         } else if(delay_val < 0) { // Script error |         } 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 %u", bad_usb->st.line_cur - 1U); |             FURI_LOG_E(WORKER_TAG, "Unknown command at line %u", bad_usb->st.line_cur - 1U); | ||||||
| @@ -320,6 +324,8 @@ static int32_t ducky_script_execute_next(BadUsbScript* bad_usb, File* script_fil | |||||||
|                     return 0; |                     return 0; | ||||||
|                 } else if(delay_val == SCRIPT_STATE_STRING_START) { // Print string with delays |                 } else if(delay_val == SCRIPT_STATE_STRING_START) { // Print string with delays | ||||||
|                     return delay_val; |                     return delay_val; | ||||||
|  |                 } else if(delay_val == SCRIPT_STATE_WAIT_FOR_BTN) { // wait for button | ||||||
|  |                     return delay_val; | ||||||
|                 } else if(delay_val < 0) { |                 } else 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 %u", bad_usb->st.line_cur); |                     FURI_LOG_E(WORKER_TAG, "Unknown command at line %u", bad_usb->st.line_cur); | ||||||
| @@ -509,6 +515,9 @@ static int32_t bad_usb_worker(void* context) { | |||||||
|                     delay_val = bad_usb->defdelay; |                     delay_val = bad_usb->defdelay; | ||||||
|                     bad_usb->string_print_pos = 0; |                     bad_usb->string_print_pos = 0; | ||||||
|                     worker_state = BadUsbStateStringDelay; |                     worker_state = BadUsbStateStringDelay; | ||||||
|  |                 } else if(delay_val == SCRIPT_STATE_WAIT_FOR_BTN) { // set state to wait for user input | ||||||
|  |                     worker_state = BadUsbStateWaitForBtn; | ||||||
|  |                     bad_usb->st.state = BadUsbStateWaitForBtn; // Show long delays | ||||||
|                 } else if(delay_val > 1000) { |                 } else if(delay_val > 1000) { | ||||||
|                     bad_usb->st.state = BadUsbStateDelay; // Show long delays |                     bad_usb->st.state = BadUsbStateDelay; // Show long delays | ||||||
|                     bad_usb->st.delay_remain = delay_val / 1000; |                     bad_usb->st.delay_remain = delay_val / 1000; | ||||||
| @@ -516,6 +525,23 @@ static int32_t bad_usb_worker(void* context) { | |||||||
|             } else { |             } else { | ||||||
|                 furi_check((flags & FuriFlagError) == 0); |                 furi_check((flags & FuriFlagError) == 0); | ||||||
|             } |             } | ||||||
|  |         } else if(worker_state == BadUsbStateWaitForBtn) { // State: Wait for button Press | ||||||
|  |             uint16_t delay_cur = (delay_val > 1000) ? (1000) : (delay_val); | ||||||
|  |             uint32_t flags = furi_thread_flags_wait( | ||||||
|  |                 WorkerEvtEnd | WorkerEvtToggle | WorkerEvtDisconnect, FuriFlagWaitAny, delay_cur); | ||||||
|  |             if(!(flags & FuriFlagError)) { | ||||||
|  |                 if(flags & WorkerEvtEnd) { | ||||||
|  |                     break; | ||||||
|  |                 } else if(flags & WorkerEvtToggle) { | ||||||
|  |                     delay_val = 0; | ||||||
|  |                     worker_state = BadUsbStateRunning; | ||||||
|  |                 } else if(flags & WorkerEvtDisconnect) { | ||||||
|  |                     worker_state = BadUsbStateNotConnected; // USB disconnected | ||||||
|  |                     furi_hal_hid_kb_release_all(); | ||||||
|  |                 } | ||||||
|  |                 bad_usb->st.state = worker_state; | ||||||
|  |                 continue; | ||||||
|  |             } | ||||||
|         } else if(worker_state == BadUsbStateStringDelay) { // State: print string with delays |         } else if(worker_state == BadUsbStateStringDelay) { // State: print string with delays | ||||||
|             uint32_t flags = furi_thread_flags_wait( |             uint32_t flags = furi_thread_flags_wait( | ||||||
|                 WorkerEvtEnd | WorkerEvtToggle | WorkerEvtDisconnect, |                 WorkerEvtEnd | WorkerEvtToggle | WorkerEvtDisconnect, | ||||||
|   | |||||||
| @@ -15,6 +15,7 @@ typedef enum { | |||||||
|     BadUsbStateRunning, |     BadUsbStateRunning, | ||||||
|     BadUsbStateDelay, |     BadUsbStateDelay, | ||||||
|     BadUsbStateStringDelay, |     BadUsbStateStringDelay, | ||||||
|  |     BadUsbStateWaitForBtn, | ||||||
|     BadUsbStateDone, |     BadUsbStateDone, | ||||||
|     BadUsbStateScriptError, |     BadUsbStateScriptError, | ||||||
|     BadUsbStateFileError, |     BadUsbStateFileError, | ||||||
|   | |||||||
| @@ -143,6 +143,14 @@ static int32_t ducky_fnc_release(BadUsbScript* bad_usb, const char* line, int32_ | |||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static int32_t ducky_fnc_waitforbutton(BadUsbScript* bad_usb, const char* line, int32_t param) { | ||||||
|  |     UNUSED(param); | ||||||
|  |     UNUSED(bad_usb); | ||||||
|  |     UNUSED(line); | ||||||
|  |  | ||||||
|  |     return SCRIPT_STATE_WAIT_FOR_BTN; | ||||||
|  | } | ||||||
|  |  | ||||||
| static const DuckyCmd ducky_commands[] = { | static const DuckyCmd ducky_commands[] = { | ||||||
|     {"REM ", NULL, -1}, |     {"REM ", NULL, -1}, | ||||||
|     {"ID ", NULL, -1}, |     {"ID ", NULL, -1}, | ||||||
| @@ -160,8 +168,12 @@ static const DuckyCmd ducky_commands[] = { | |||||||
|     {"ALTCODE ", ducky_fnc_altstring, -1}, |     {"ALTCODE ", ducky_fnc_altstring, -1}, | ||||||
|     {"HOLD ", ducky_fnc_hold, -1}, |     {"HOLD ", ducky_fnc_hold, -1}, | ||||||
|     {"RELEASE ", ducky_fnc_release, -1}, |     {"RELEASE ", ducky_fnc_release, -1}, | ||||||
|  |     {"WAIT_FOR_BUTTON_PRESS", ducky_fnc_waitforbutton, -1}, | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | #define TAG "BadUSB" | ||||||
|  | #define WORKER_TAG TAG "Worker" | ||||||
|  |  | ||||||
| int32_t ducky_execute_cmd(BadUsbScript* bad_usb, const char* line) { | int32_t ducky_execute_cmd(BadUsbScript* bad_usb, const char* line) { | ||||||
|     for(size_t i = 0; i < COUNT_OF(ducky_commands); i++) { |     for(size_t i = 0; i < COUNT_OF(ducky_commands); i++) { | ||||||
|         if(strncmp(line, ducky_commands[i].name, strlen(ducky_commands[i].name)) == 0) { |         if(strncmp(line, ducky_commands[i].name, strlen(ducky_commands[i].name)) == 0) { | ||||||
|   | |||||||
| @@ -13,6 +13,7 @@ extern "C" { | |||||||
| #define SCRIPT_STATE_NEXT_LINE (-3) | #define SCRIPT_STATE_NEXT_LINE (-3) | ||||||
| #define SCRIPT_STATE_CMD_UNKNOWN (-4) | #define SCRIPT_STATE_CMD_UNKNOWN (-4) | ||||||
| #define SCRIPT_STATE_STRING_START (-5) | #define SCRIPT_STATE_STRING_START (-5) | ||||||
|  | #define SCRIPT_STATE_WAIT_FOR_BTN (-6) | ||||||
|  |  | ||||||
| #define FILE_BUFFER_LEN 16 | #define FILE_BUFFER_LEN 16 | ||||||
|  |  | ||||||
|   | |||||||
| @@ -51,6 +51,8 @@ static void bad_usb_draw_callback(Canvas* canvas, void* _model) { | |||||||
|         elements_button_left(canvas, "Config"); |         elements_button_left(canvas, "Config"); | ||||||
|     } else if((model->state.state == BadUsbStateRunning) || (model->state.state == BadUsbStateDelay)) { |     } else if((model->state.state == BadUsbStateRunning) || (model->state.state == BadUsbStateDelay)) { | ||||||
|         elements_button_center(canvas, "Stop"); |         elements_button_center(canvas, "Stop"); | ||||||
|  |     } else if(model->state.state == BadUsbStateWaitForBtn) { | ||||||
|  |         elements_button_center(canvas, "Press to continue"); | ||||||
|     } else if(model->state.state == BadUsbStateWillRun) { |     } else if(model->state.state == BadUsbStateWillRun) { | ||||||
|         elements_button_center(canvas, "Cancel"); |         elements_button_center(canvas, "Cancel"); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -77,6 +77,13 @@ Up to 5 keys can be hold simultaneously. | |||||||
| | HOLD    | Special key or single character | Press and hold key untill RELEASE command | | | HOLD    | Special key or single character | Press and hold key untill RELEASE command | | ||||||
| | RELEASE | Special key or single character | Release key                               | | | RELEASE | Special key or single character | Release key                               | | ||||||
|  |  | ||||||
|  | ## Wait for button press | ||||||
|  |  | ||||||
|  | Will wait indefinitely for a button to be pressed | ||||||
|  | | Command               | Parameters   | Notes                                                                 | | ||||||
|  | | --------------------- | ------------ | --------------------------------------------------------------------- | | ||||||
|  | | WAIT_FOR_BUTTON_PRESS | None         | Will wait for the user to press a button to continue script execution | | ||||||
|  |  | ||||||
|  |  | ||||||
| ## String | ## String | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user