diff --git a/applications/main/bad_kb/helpers/ducky_script.c b/applications/main/bad_kb/helpers/ducky_script.c index 578c0db00..6b212a68d 100644 --- a/applications/main/bad_kb/helpers/ducky_script.c +++ b/applications/main/bad_kb/helpers/ducky_script.c @@ -382,6 +382,10 @@ static int32_t ducky_script_execute_next(BadKbScript* bad_kb, File* script_file) delay_val = ducky_parse_line(bad_kb, bad_kb->line_prev); if(delay_val == SCRIPT_STATE_NEXT_LINE) { // Empty line 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 bad_kb->st.error_line = bad_kb->st.line_cur - 1; FURI_LOG_E(WORKER_TAG, "Unknown command at line %u", bad_kb->st.line_cur - 1U); @@ -419,6 +423,8 @@ static int32_t ducky_script_execute_next(BadKbScript* bad_kb, File* script_file) 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) { bad_kb->st.error_line = bad_kb->st.line_cur; FURI_LOG_E(WORKER_TAG, "Unknown command at line %u", bad_kb->st.line_cur); @@ -657,6 +663,9 @@ static int32_t bad_kb_worker(void* context) { delay_val = bad_kb->defdelay; bad_kb->string_print_pos = 0; worker_state = BadKbStateStringDelay; + } else if(delay_val == SCRIPT_STATE_WAIT_FOR_BTN) { // set state to wait for user input + worker_state = BadKbStateWaitForBtn; + bad_kb->st.state = BadKbStateWaitForBtn; // Show long delays } else if(delay_val > 1000) { bad_kb->st.state = BadKbStateDelay; // Show long delays bad_kb->st.delay_remain = delay_val / 1000; @@ -664,6 +673,23 @@ static int32_t bad_kb_worker(void* context) { } else { furi_check((flags & FuriFlagError) == 0); } + } else if(worker_state == BadKbStateWaitForBtn) { // 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 = BadKbStateRunning; + } else if(flags & WorkerEvtDisconnect) { + worker_state = BadKbStateNotConnected; // USB disconnected + furi_hal_hid_kb_release_all(); + } + bad_kb->st.state = worker_state; + continue; + } } else if(worker_state == BadKbStateStringDelay) { // State: print string with delays uint32_t flags = furi_thread_flags_wait( WorkerEvtEnd | WorkerEvtToggle | WorkerEvtDisconnect, diff --git a/applications/main/bad_kb/helpers/ducky_script.h b/applications/main/bad_kb/helpers/ducky_script.h index fe3aaef2b..6f5e03e0b 100644 --- a/applications/main/bad_kb/helpers/ducky_script.h +++ b/applications/main/bad_kb/helpers/ducky_script.h @@ -32,6 +32,7 @@ typedef enum { BadKbStateRunning, BadKbStateDelay, BadKbStateStringDelay, + BadKbStateWaitForBtn, BadKbStateDone, BadKbStateScriptError, BadKbStateFileError, diff --git a/applications/main/bad_kb/helpers/ducky_script_commands.c b/applications/main/bad_kb/helpers/ducky_script_commands.c index dc3d27e2e..ef8da0b8a 100644 --- a/applications/main/bad_kb/helpers/ducky_script_commands.c +++ b/applications/main/bad_kb/helpers/ducky_script_commands.c @@ -160,6 +160,14 @@ static int32_t ducky_fnc_release(BadKbScript* bad_kb, const char* line, int32_t return 0; } +static int32_t ducky_fnc_waitforbutton(BadKbScript* bad_kb, const char* line, int32_t param) { + UNUSED(param); + UNUSED(bad_kb); + UNUSED(line); + + return SCRIPT_STATE_WAIT_FOR_BTN; +} + static const DuckyCmd ducky_commands[] = { {"REM ", NULL, -1}, {"ID ", NULL, -1}, @@ -177,8 +185,12 @@ static const DuckyCmd ducky_commands[] = { {"ALTCODE ", ducky_fnc_altstring, -1}, {"HOLD ", ducky_fnc_hold, -1}, {"RELEASE ", ducky_fnc_release, -1}, + {"WAIT_FOR_BUTTON_PRESS", ducky_fnc_waitforbutton, -1}, }; +#define TAG "BadKB" +#define WORKER_TAG TAG "Worker" + int32_t ducky_execute_cmd(BadKbScript* bad_kb, const char* line) { for(size_t i = 0; i < COUNT_OF(ducky_commands); i++) { if(strncmp(line, ducky_commands[i].name, strlen(ducky_commands[i].name)) == 0) { diff --git a/applications/main/bad_kb/helpers/ducky_script_i.h b/applications/main/bad_kb/helpers/ducky_script_i.h index e73927119..646355c9c 100644 --- a/applications/main/bad_kb/helpers/ducky_script_i.h +++ b/applications/main/bad_kb/helpers/ducky_script_i.h @@ -13,6 +13,7 @@ extern "C" { #define SCRIPT_STATE_NEXT_LINE (-3) #define SCRIPT_STATE_CMD_UNKNOWN (-4) #define SCRIPT_STATE_STRING_START (-5) +#define SCRIPT_STATE_WAIT_FOR_BTN (-6) uint16_t ducky_get_keycode(BadKbScript* bad_kb, const char* param, bool accept_chars); diff --git a/applications/main/bad_kb/views/bad_kb_view.c b/applications/main/bad_kb/views/bad_kb_view.c index 45113c34d..4cba891f1 100644 --- a/applications/main/bad_kb/views/bad_kb_view.c +++ b/applications/main/bad_kb/views/bad_kb_view.c @@ -61,6 +61,8 @@ static void bad_kb_draw_callback(Canvas* canvas, void* _model) { elements_button_left(canvas, "Config"); } else if((model->state.state == BadKbStateRunning) || (model->state.state == BadKbStateDelay)) { elements_button_center(canvas, "Stop"); + } else if(model->state.state == BadKbStateWaitForBtn) { + elements_button_center(canvas, "Press to continue"); } else if(model->state.state == BadKbStateWillRun) { elements_button_center(canvas, "Cancel"); }