MX
2023-04-27 00:13:28 +03:00
parent 451ec9cba0
commit 10c4cd0f41
43 changed files with 6966 additions and 29 deletions

View File

@@ -3,3 +3,12 @@ ADD_SCENE(wifi_marauder, console_output, ConsoleOutput)
ADD_SCENE(wifi_marauder, text_input, TextInput)
ADD_SCENE(wifi_marauder, settings_init, SettingsInit)
ADD_SCENE(wifi_marauder, log_viewer, LogViewer)
ADD_SCENE(wifi_marauder, user_input, UserInput)
ADD_SCENE(wifi_marauder, script_select, ScriptSelect)
ADD_SCENE(wifi_marauder, script_options, ScriptOptions)
ADD_SCENE(wifi_marauder, script_edit, ScriptEdit)
ADD_SCENE(wifi_marauder, script_settings, ScriptSettings)
ADD_SCENE(wifi_marauder, script_confirm_delete, ScriptConfirmDelete)
ADD_SCENE(wifi_marauder, script_stage_edit, ScriptStageEdit)
ADD_SCENE(wifi_marauder, script_stage_add, ScriptStageAdd)
ADD_SCENE(wifi_marauder, script_stage_edit_list, ScriptStageEditList)

View File

@@ -1,5 +1,34 @@
#include "../wifi_marauder_app_i.h"
char* _wifi_marauder_get_prefix_from_cmd(const char* command) {
int end = strcspn(command, " ");
char* prefix = (char*)malloc(sizeof(char) * (end + 1));
strncpy(prefix, command, end);
prefix[end] = '\0';
return prefix;
}
bool _wifi_marauder_is_save_pcaps_enabled(WifiMarauderApp* app) {
if(!app->ok_to_save_pcaps) {
return false;
}
// If it is a script that contains a sniff function
if(app->script != NULL) {
return wifi_marauder_script_has_stage(app->script, WifiMarauderScriptStageTypeSniffRaw) ||
wifi_marauder_script_has_stage(
app->script, WifiMarauderScriptStageTypeSniffBeacon) ||
wifi_marauder_script_has_stage(
app->script, WifiMarauderScriptStageTypeSniffDeauth) ||
wifi_marauder_script_has_stage(app->script, WifiMarauderScriptStageTypeSniffEsp) ||
wifi_marauder_script_has_stage(
app->script, WifiMarauderScriptStageTypeSniffPmkid) ||
wifi_marauder_script_has_stage(app->script, WifiMarauderScriptStageTypeSniffPwn);
}
// If it is a sniff function
return app->is_command && app->selected_tx_string &&
strncmp("sniff", app->selected_tx_string, strlen("sniff")) == 0;
}
void wifi_marauder_console_output_handle_rx_data_cb(uint8_t* buf, size_t len, void* context) {
furi_assert(context);
WifiMarauderApp* app = context;
@@ -34,23 +63,29 @@ void wifi_marauder_console_output_handle_rx_packets_cb(uint8_t* buf, size_t len,
void wifi_marauder_scene_console_output_on_enter(void* context) {
WifiMarauderApp* app = context;
// Reset text box and set font
TextBox* text_box = app->text_box;
text_box_reset(app->text_box);
text_box_reset(text_box);
text_box_set_font(text_box, TextBoxFontText);
// Set focus on start or end
if(app->focus_console_start) {
text_box_set_focus(text_box, TextBoxFocusStart);
} else {
text_box_set_focus(text_box, TextBoxFocusEnd);
}
// Set command-related messages
if(app->is_command) {
furi_string_reset(app->text_box_store);
app->text_box_store_strlen = 0;
// Help message
if(0 == strncmp("help", app->selected_tx_string, strlen("help"))) {
const char* help_msg = "Marauder companion " WIFI_MARAUDER_APP_VERSION "\n";
furi_string_cat_str(app->text_box_store, help_msg);
app->text_box_store_strlen += strlen(help_msg);
}
// Stopscan message
if(app->show_stopscan_tip) {
const char* help_msg = "Press BACK to send stopscan\n";
furi_string_cat_str(app->text_box_store, help_msg);
@@ -58,13 +93,14 @@ void wifi_marauder_scene_console_output_on_enter(void* context) {
}
}
// Set starting text - for "View Log from end", this will just be what was already in the text box store
// Set starting text
text_box_set_text(app->text_box, furi_string_get_cstr(app->text_box_store));
// Set scene state and switch view
scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneConsoleOutput, 0);
view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewConsoleOutput);
// Register callback to receive data
// Register callbacks to receive data
wifi_marauder_uart_set_handle_rx_data_cb(
app->uart,
wifi_marauder_console_output_handle_rx_data_cb); // setup callback for general log rx thread
@@ -73,25 +109,53 @@ void wifi_marauder_scene_console_output_on_enter(void* context) {
wifi_marauder_console_output_handle_rx_packets_cb); // setup callback for packets rx thread
// Get ready to send command
if(app->is_command && app->selected_tx_string) {
if((app->is_command && app->selected_tx_string) || app->script) {
const char* prefix =
strlen(app->selected_tx_string) > 0 ?
_wifi_marauder_get_prefix_from_cmd(app->selected_tx_string) : // Function name
app->script->name; // Script name
// Create files *before* sending command
// (it takes time to iterate through the directory)
if(app->ok_to_save_logs) {
app->is_writing_log = true;
wifi_marauder_create_log_file(app);
strcpy(
app->log_file_path,
sequential_file_resolve_path(
app->storage, MARAUDER_APP_FOLDER_LOGS, prefix, "log"));
if(app->log_file_path != NULL) {
if(storage_file_open(
app->log_file, app->log_file_path, FSAM_WRITE, FSOM_CREATE_ALWAYS)) {
app->is_writing_log = true;
} else {
dialog_message_show_storage_error(app->dialogs, "Cannot open log file");
}
} else {
dialog_message_show_storage_error(app->dialogs, "Cannot resolve log path");
}
}
// If it is a sniff function, open the pcap file for recording
if(app->ok_to_save_pcaps &&
strncmp("sniff", app->selected_tx_string, strlen("sniff")) == 0) {
app->is_writing_pcap = true;
wifi_marauder_create_pcap_file(app);
// If it is a sniff function or script, open the pcap file for recording
if(_wifi_marauder_is_save_pcaps_enabled(app)) {
if(sequential_file_open(
app->storage, app->capture_file, MARAUDER_APP_FOLDER_PCAPS, prefix, "pcap")) {
app->is_writing_pcap = true;
} else {
dialog_message_show_storage_error(app->dialogs, "Cannot open pcap file");
}
}
// Send command with newline '\n'
wifi_marauder_uart_tx(
(uint8_t*)(app->selected_tx_string), strlen(app->selected_tx_string));
wifi_marauder_uart_tx((uint8_t*)("\n"), 1);
if(app->selected_tx_string) {
wifi_marauder_uart_tx(
(uint8_t*)(app->selected_tx_string), strlen(app->selected_tx_string));
wifi_marauder_uart_tx((uint8_t*)("\n"), 1);
}
// Run the script if the file with the script has been opened
if(app->script != NULL) {
app->script_worker = wifi_marauder_script_worker_alloc();
wifi_marauder_script_worker_start(app->script_worker, app->script);
}
}
}
@@ -113,14 +177,18 @@ bool wifi_marauder_scene_console_output_on_event(void* context, SceneManagerEven
void wifi_marauder_scene_console_output_on_exit(void* context) {
WifiMarauderApp* app = context;
// Automatically stop the scan when exiting view
if(app->is_command) {
wifi_marauder_uart_tx((uint8_t*)("stopscan\n"), strlen("stopscan\n"));
furi_delay_ms(50);
}
// Unregister rx callback
wifi_marauder_uart_set_handle_rx_data_cb(app->uart, NULL);
wifi_marauder_uart_set_handle_rx_data_cb(app->lp_uart, NULL);
// Automatically stop the scan when exiting view
if(app->is_command) {
wifi_marauder_uart_tx((uint8_t*)("stopscan\n"), strlen("stopscan\n"));
}
wifi_marauder_script_worker_free(app->script_worker);
app->script_worker = NULL;
app->is_writing_pcap = false;
if(app->capture_file && storage_file_is_open(app->capture_file)) {

View File

@@ -0,0 +1,83 @@
#include "../wifi_marauder_app_i.h"
void wifi_marauder_scene_script_confirm_delete_widget_callback(
GuiButtonType result,
InputType type,
void* context) {
WifiMarauderApp* app = context;
if(type == InputTypeShort) {
view_dispatcher_send_custom_event(app->view_dispatcher, result);
}
}
void wifi_marauder_scene_script_confirm_delete_on_enter(void* context) {
WifiMarauderApp* app = context;
widget_add_button_element(
app->widget,
GuiButtonTypeLeft,
"No",
wifi_marauder_scene_script_confirm_delete_widget_callback,
app);
widget_add_button_element(
app->widget,
GuiButtonTypeRight,
"Yes",
wifi_marauder_scene_script_confirm_delete_widget_callback,
app);
widget_add_string_element(
app->widget, 0, 0, AlignLeft, AlignTop, FontPrimary, "Are you sure?");
widget_add_text_box_element(
app->widget,
0,
12,
128,
38,
AlignCenter,
AlignCenter,
"The script will be\npermanently deleted",
false);
view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewWidget);
}
bool wifi_marauder_scene_script_confirm_delete_on_event(void* context, SceneManagerEvent event) {
WifiMarauderApp* app = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
// get which button press: "Yes" or "No"
if(event.event == GuiButtonTypeRight) {
// Yes
if(app->script != NULL) {
char script_path[256];
snprintf(
script_path,
sizeof(script_path),
"%s/%s.json",
MARAUDER_APP_FOLDER_SCRIPTS,
app->script->name);
storage_simply_remove(app->storage, script_path);
wifi_marauder_script_free(app->script);
app->script = NULL;
DialogMessage* message = dialog_message_alloc();
dialog_message_set_text(message, "Deleted!", 88, 32, AlignCenter, AlignCenter);
dialog_message_set_icon(message, &I_DolphinCommon_56x48, 5, 6);
dialog_message_set_buttons(message, NULL, "Ok", NULL);
dialog_message_show(app->dialogs, message);
dialog_message_free(message);
}
}
scene_manager_previous_scene(app->scene_manager);
consumed = true;
}
return consumed;
}
void wifi_marauder_scene_script_confirm_delete_on_exit(void* context) {
WifiMarauderApp* app = context;
widget_reset(app->widget);
}

View File

@@ -0,0 +1,125 @@
#include "../wifi_marauder_app_i.h"
static void wifi_marauder_scene_script_edit_callback(void* context, uint32_t index) {
WifiMarauderApp* app = context;
WifiMarauderScriptStage* current_stage = app->script->first_stage;
uint32_t stage_index = 0;
while(current_stage != NULL && stage_index < index) {
current_stage = current_stage->next_stage;
stage_index++;
}
app->script_edit_selected_stage = current_stage;
if(app->script_edit_selected_stage != NULL) {
scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptEdit, index);
scene_manager_next_scene(app->scene_manager, WifiMarauderSceneScriptStageEdit);
}
}
static void wifi_marauder_scene_script_edit_add_callback(void* context, uint32_t index) {
WifiMarauderApp* app = context;
scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptEdit, index);
scene_manager_next_scene(app->scene_manager, WifiMarauderSceneScriptStageAdd);
}
void wifi_marauder_scene_script_edit_on_enter(void* context) {
WifiMarauderApp* app = context;
Submenu* submenu = app->submenu;
WifiMarauderScript* script = app->script;
submenu_set_header(submenu, script->name);
WifiMarauderScriptStage* current_stage = script->first_stage;
int stage_index = 0;
while(current_stage != NULL) {
switch(current_stage->type) {
case WifiMarauderScriptStageTypeScan:
submenu_add_item(
submenu, "Scan", stage_index, wifi_marauder_scene_script_edit_callback, app);
break;
case WifiMarauderScriptStageTypeSelect:
submenu_add_item(
submenu, "Select", stage_index, wifi_marauder_scene_script_edit_callback, app);
break;
case WifiMarauderScriptStageTypeDeauth:
submenu_add_item(
submenu, "Deauth", stage_index, wifi_marauder_scene_script_edit_callback, app);
break;
case WifiMarauderScriptStageTypeProbe:
submenu_add_item(
submenu, "Probe", stage_index, wifi_marauder_scene_script_edit_callback, app);
break;
case WifiMarauderScriptStageTypeSniffRaw:
submenu_add_item(
submenu, "Sniff raw", stage_index, wifi_marauder_scene_script_edit_callback, app);
break;
case WifiMarauderScriptStageTypeSniffBeacon:
submenu_add_item(
submenu,
"Sniff beacon",
stage_index,
wifi_marauder_scene_script_edit_callback,
app);
break;
case WifiMarauderScriptStageTypeSniffDeauth:
submenu_add_item(
submenu,
"Sniff deauth",
stage_index,
wifi_marauder_scene_script_edit_callback,
app);
break;
case WifiMarauderScriptStageTypeSniffEsp:
submenu_add_item(
submenu, "Sniff esp", stage_index, wifi_marauder_scene_script_edit_callback, app);
break;
case WifiMarauderScriptStageTypeSniffPmkid:
submenu_add_item(
submenu, "Sniff PMKID", stage_index, wifi_marauder_scene_script_edit_callback, app);
break;
case WifiMarauderScriptStageTypeSniffPwn:
submenu_add_item(
submenu, "Sniff pwn", stage_index, wifi_marauder_scene_script_edit_callback, app);
break;
case WifiMarauderScriptStageTypeBeaconList:
submenu_add_item(
submenu, "Beacon list", stage_index, wifi_marauder_scene_script_edit_callback, app);
break;
case WifiMarauderScriptStageTypeBeaconAp:
submenu_add_item(
submenu, "Beacon AP", stage_index, wifi_marauder_scene_script_edit_callback, app);
break;
case WifiMarauderScriptStageTypeExec:
submenu_add_item(
submenu,
"Custom command",
stage_index,
wifi_marauder_scene_script_edit_callback,
app);
break;
case WifiMarauderScriptStageTypeDelay:
submenu_add_item(
submenu, "Delay", stage_index, wifi_marauder_scene_script_edit_callback, app);
break;
}
current_stage = current_stage->next_stage;
stage_index++;
}
submenu_add_item(
submenu, "[+] ADD STAGE", stage_index++, wifi_marauder_scene_script_edit_add_callback, app);
submenu_set_selected_item(
submenu, scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneScriptEdit));
view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewSubmenu);
}
bool wifi_marauder_scene_script_edit_on_event(void* context, SceneManagerEvent event) {
UNUSED(context);
UNUSED(event);
return false;
}
void wifi_marauder_scene_script_edit_on_exit(void* context) {
WifiMarauderApp* app = context;
submenu_reset(app->submenu);
}

View File

@@ -0,0 +1,188 @@
#include "../wifi_marauder_app_i.h"
static void
wifi_marauder_scene_script_stage_edit_list_add_callback(void* context, uint32_t index) {
WifiMarauderApp* app = context;
// Creates new item
WifiMarauderScriptStageListItem* new_item =
(WifiMarauderScriptStageListItem*)malloc(sizeof(WifiMarauderScriptStageListItem));
new_item->value = malloc(64);
new_item->next_item = NULL;
if(app->script_stage_edit_first_item == NULL) {
app->script_stage_edit_first_item = new_item;
} else {
WifiMarauderScriptStageListItem* last_item = app->script_stage_edit_first_item;
while(last_item->next_item != NULL) {
last_item = last_item->next_item;
}
last_item->next_item = new_item;
}
scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptStageEditList, index);
app->user_input_type = WifiMarauderUserInputTypeString;
app->user_input_string_reference = &new_item->value;
scene_manager_next_scene(app->scene_manager, WifiMarauderSceneUserInput);
}
static void wifi_marauder_scene_script_stage_edit_list_deallocate_items(WifiMarauderApp* app) {
WifiMarauderScriptStageListItem* current_item = app->script_stage_edit_first_item;
while(current_item != NULL) {
WifiMarauderScriptStageListItem* next_item = current_item->next_item;
free(current_item->value);
free(current_item);
current_item = next_item;
}
app->script_stage_edit_first_item = NULL;
}
static void wifi_marauder_scene_script_stage_edit_list_save_strings(WifiMarauderApp* app) {
WifiMarauderScriptStageListItem* current_item = app->script_stage_edit_first_item;
int array_size = 0;
// Calculates the required array size
while(current_item != NULL) {
array_size++;
current_item = current_item->next_item;
}
// Reallocate the array of strings if necessary
if(*app->script_stage_edit_string_count_reference < array_size) {
*app->script_stage_edit_strings_reference =
realloc(*app->script_stage_edit_strings_reference, array_size * sizeof(char*));
}
// Fills the array of strings
current_item = app->script_stage_edit_first_item;
int i = 0;
while(current_item != NULL) {
char* current_str = malloc(strlen(current_item->value) + 1);
strncpy(current_str, current_item->value, strlen(current_item->value) + 1);
(*app->script_stage_edit_strings_reference)[i] = current_str;
current_item = current_item->next_item;
i++;
}
*app->script_stage_edit_string_count_reference = array_size;
}
static void wifi_marauder_scene_script_stage_edit_list_save_numbers(WifiMarauderApp* app) {
WifiMarauderScriptStageListItem* current_item = app->script_stage_edit_first_item;
int array_size = 0;
// Calculates the required array size
while(current_item != NULL) {
array_size++;
current_item = current_item->next_item;
}
// Reallocate the array of integers if necessary
if(*app->script_stage_edit_number_count_reference < array_size) {
*app->script_stage_edit_numbers_reference =
realloc(*app->script_stage_edit_numbers_reference, array_size * sizeof(int));
}
// Fills the array of integers
current_item = app->script_stage_edit_first_item;
int i = 0;
while(current_item != NULL) {
(*app->script_stage_edit_numbers_reference)[i] = atoi(current_item->value);
current_item = current_item->next_item;
i++;
}
*app->script_stage_edit_number_count_reference = array_size;
}
static void
wifi_marauder_scene_script_stage_edit_list_save_callback(void* context, uint32_t index) {
UNUSED(index);
WifiMarauderApp* app = context;
if(app->script_stage_edit_strings_reference != NULL &&
app->script_stage_edit_string_count_reference != NULL) {
wifi_marauder_scene_script_stage_edit_list_save_strings(app);
}
if(app->script_stage_edit_numbers_reference != NULL &&
app->script_stage_edit_number_count_reference != NULL) {
wifi_marauder_scene_script_stage_edit_list_save_numbers(app);
}
wifi_marauder_scene_script_stage_edit_list_deallocate_items(app);
scene_manager_previous_scene(app->scene_manager);
}
static void
wifi_marauder_scene_script_stage_edit_list_clear_callback(void* context, uint32_t index) {
UNUSED(index);
WifiMarauderApp* app = context;
wifi_marauder_scene_script_stage_edit_list_deallocate_items(app);
submenu_reset(app->submenu);
submenu_add_item(
app->submenu,
"[+] ADD ITEM",
99,
wifi_marauder_scene_script_stage_edit_list_add_callback,
app);
submenu_add_item(
app->submenu,
"[*] SAVE ITEMS",
99,
wifi_marauder_scene_script_stage_edit_list_save_callback,
app);
submenu_add_item(
app->submenu,
"[-] CLEAR LIST",
99,
wifi_marauder_scene_script_stage_edit_list_clear_callback,
app);
}
void wifi_marauder_scene_script_stage_edit_list_on_enter(void* context) {
WifiMarauderApp* app = context;
int item_index = 0;
WifiMarauderScriptStageListItem* current_item = app->script_stage_edit_first_item;
while(current_item != NULL) {
submenu_add_item(app->submenu, current_item->value, item_index++, NULL, app);
current_item = current_item->next_item;
}
submenu_add_item(
app->submenu,
"[+] ADD ITEM",
99,
wifi_marauder_scene_script_stage_edit_list_add_callback,
app);
submenu_add_item(
app->submenu,
"[*] SAVE ITEMS",
99,
wifi_marauder_scene_script_stage_edit_list_save_callback,
app);
submenu_add_item(
app->submenu,
"[-] CLEAR LIST",
99,
wifi_marauder_scene_script_stage_edit_list_clear_callback,
app);
submenu_set_selected_item(
app->submenu,
scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneScriptStageEditList));
view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewSubmenu);
}
bool wifi_marauder_scene_script_stage_edit_list_on_event(void* context, SceneManagerEvent event) {
UNUSED(context);
UNUSED(event);
return false;
}
void wifi_marauder_scene_script_stage_edit_list_on_exit(void* context) {
WifiMarauderApp* app = context;
submenu_reset(app->submenu);
}

View File

@@ -0,0 +1,111 @@
#include "../wifi_marauder_app_i.h"
enum SubmenuIndex {
SubmenuIndexRun,
SubmenuIndexSettings,
SubmenuIndexEditStages,
SubmenuIndexSave,
SubmenuIndexDelete
};
void wifi_marauder_scene_script_options_save_script(WifiMarauderApp* app) {
char script_path[256];
snprintf(
script_path,
sizeof(script_path),
"%s/%s.json",
MARAUDER_APP_FOLDER_SCRIPTS,
app->script->name);
wifi_marauder_script_save_json(app->storage, script_path, app->script);
DialogMessage* message = dialog_message_alloc();
dialog_message_set_text(message, "Saved!", 88, 32, AlignCenter, AlignCenter);
dialog_message_set_icon(message, &I_DolphinCommon_56x48, 5, 6);
dialog_message_set_buttons(message, NULL, "Ok", NULL);
dialog_message_show(app->dialogs, message);
dialog_message_free(message);
}
static void wifi_marauder_scene_script_options_callback(void* context, uint32_t index) {
WifiMarauderApp* app = context;
switch(index) {
case SubmenuIndexRun:
scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptOptions, index);
scene_manager_next_scene(app->scene_manager, WifiMarauderSceneConsoleOutput);
break;
case SubmenuIndexSettings:
scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptOptions, index);
scene_manager_next_scene(app->scene_manager, WifiMarauderSceneScriptSettings);
break;
case SubmenuIndexEditStages:
scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptOptions, index);
scene_manager_next_scene(app->scene_manager, WifiMarauderSceneScriptEdit);
break;
case SubmenuIndexSave:
wifi_marauder_scene_script_options_save_script(app);
break;
case SubmenuIndexDelete:
scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptOptions, index);
scene_manager_next_scene(app->scene_manager, WifiMarauderSceneScriptConfirmDelete);
break;
}
}
void wifi_marauder_scene_script_options_on_enter(void* context) {
WifiMarauderApp* app = context;
// If returning after confirming script deletion
if(app->script == NULL) {
scene_manager_previous_scene(app->scene_manager);
return;
}
Submenu* submenu = app->submenu;
submenu_set_header(submenu, app->script->name);
submenu_add_item(
submenu, "[>] RUN", SubmenuIndexRun, wifi_marauder_scene_script_options_callback, app);
submenu_add_item(
submenu,
"[S] SETTINGS",
SubmenuIndexSettings,
wifi_marauder_scene_script_options_callback,
app);
submenu_add_item(
submenu,
"[+] EDIT STAGES",
SubmenuIndexEditStages,
wifi_marauder_scene_script_options_callback,
app);
submenu_add_item(
submenu, "[*] SAVE", SubmenuIndexSave, wifi_marauder_scene_script_options_callback, app);
submenu_add_item(
submenu,
"[X] DELETE",
SubmenuIndexDelete,
wifi_marauder_scene_script_options_callback,
app);
submenu_set_selected_item(
submenu,
scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneScriptOptions));
view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewSubmenu);
}
bool wifi_marauder_scene_script_options_on_event(void* context, SceneManagerEvent event) {
WifiMarauderApp* app = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeBack) {
wifi_marauder_script_free(app->script);
app->script = NULL;
}
return consumed;
}
void wifi_marauder_scene_script_options_on_exit(void* context) {
WifiMarauderApp* app = context;
submenu_reset(app->submenu);
}

View File

@@ -0,0 +1,90 @@
#include "../wifi_marauder_app_i.h"
static void wifi_marauder_scene_script_select_callback(void* context, uint32_t index) {
WifiMarauderApp* app = context;
char script_path[256];
snprintf(
script_path,
sizeof(script_path),
"%s/%s.json",
MARAUDER_APP_FOLDER_SCRIPTS,
furi_string_get_cstr(app->script_list[index]));
app->script = wifi_marauder_script_parse_json(app->storage, script_path);
if(app->script) {
scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptSelect, index);
scene_manager_next_scene(app->scene_manager, WifiMarauderSceneScriptOptions);
}
}
static void wifi_marauder_scene_script_select_add_callback(void* context, uint32_t index) {
WifiMarauderApp* app = context;
scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptSelect, index);
app->user_input_type = WifiMarauderUserInputTypeFileName;
app->user_input_file_dir = strdup(MARAUDER_APP_FOLDER_SCRIPTS);
app->user_input_file_extension = strdup("json");
scene_manager_next_scene(app->scene_manager, WifiMarauderSceneUserInput);
}
void wifi_marauder_scene_script_select_on_enter(void* context) {
WifiMarauderApp* app = context;
Submenu* submenu = app->submenu;
File* dir_scripts = storage_file_alloc(app->storage);
if(storage_dir_open(dir_scripts, MARAUDER_APP_FOLDER_SCRIPTS)) {
FileInfo file_info;
char file_path[255];
app->script_list_count = 0;
// Goes through the files in the folder counting the ones that end with the json extension
while(storage_dir_read(dir_scripts, &file_info, file_path, 255)) {
app->script_list_count++;
}
if(app->script_list_count > 0) {
submenu_set_header(submenu, "Select a script:");
app->script_list = malloc(app->script_list_count * sizeof(FuriString*));
storage_dir_close(dir_scripts);
storage_dir_open(dir_scripts, MARAUDER_APP_FOLDER_SCRIPTS);
// Read the files again from the beginning, adding the scripts in the list
int script_index = 0;
while(storage_dir_read(dir_scripts, &file_info, file_path, 255)) {
app->script_list[script_index] = furi_string_alloc();
path_extract_filename_no_ext(file_path, app->script_list[script_index]);
submenu_add_item(
submenu,
furi_string_get_cstr(app->script_list[script_index]),
script_index,
wifi_marauder_scene_script_select_callback,
app);
script_index++;
}
} else {
submenu_set_header(submenu, "No script found");
}
submenu_add_item(
submenu, "[+] ADD SCRIPT", 99, wifi_marauder_scene_script_select_add_callback, app);
storage_dir_close(dir_scripts);
}
storage_file_free(dir_scripts);
submenu_set_selected_item(
submenu, scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneScriptSelect));
view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewSubmenu);
}
bool wifi_marauder_scene_script_select_on_event(void* context, SceneManagerEvent event) {
UNUSED(context);
UNUSED(event);
return false;
}
void wifi_marauder_scene_script_select_on_exit(void* context) {
WifiMarauderApp* app = context;
submenu_reset(app->submenu);
for(int i = 0; i < app->script_list_count; i++) {
furi_string_free(app->script_list[i]);
}
free(app->script_list);
}

View File

@@ -0,0 +1,87 @@
#include "../wifi_marauder_app_i.h"
enum ScriptSettingsOption {
ScriptSettingsOptionRepeat,
ScriptSettingsOptionSavePcap,
ScriptSettingsOptionEnableLed
};
const char* option_values[3] = {"No", "Yes", "Default"};
static void wifi_marauder_scene_script_settings_enter_callback(void* context, uint32_t index) {
WifiMarauderApp* app = context;
// Accept script repeat value
if(index == ScriptSettingsOptionRepeat) {
scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptSettings, index);
app->user_input_type = WifiMarauderUserInputTypeNumber;
app->user_input_number_reference = &app->script->repeat;
scene_manager_next_scene(app->scene_manager, WifiMarauderSceneUserInput);
}
}
static void wifi_marauder_scene_script_settings_change_callback(VariableItem* item) {
WifiMarauderApp* app = variable_item_get_context(item);
uint8_t current_option = variable_item_list_get_selected_item_index(app->var_item_list);
uint8_t option_value_index = variable_item_get_current_value_index(item);
switch(current_option) {
case ScriptSettingsOptionSavePcap:
variable_item_set_current_value_text(item, option_values[option_value_index]);
app->script->save_pcap = option_value_index;
break;
case ScriptSettingsOptionEnableLed:
variable_item_set_current_value_text(item, option_values[option_value_index]);
app->script->enable_led = option_value_index;
break;
}
}
void wifi_marauder_scene_script_settings_on_enter(void* context) {
WifiMarauderApp* app = context;
VariableItemList* var_item_list = app->var_item_list;
variable_item_list_set_enter_callback(
app->var_item_list, wifi_marauder_scene_script_settings_enter_callback, app);
// Script repeat option
VariableItem* repeat_item = variable_item_list_add(app->var_item_list, "Repeat", 1, NULL, app);
char repeat_str[32];
snprintf(repeat_str, sizeof(repeat_str), "%d", app->script->repeat);
variable_item_set_current_value_text(repeat_item, repeat_str);
// Save PCAP option
VariableItem* save_pcap_item = variable_item_list_add(
app->var_item_list,
"Save PCAP",
3,
wifi_marauder_scene_script_settings_change_callback,
app);
variable_item_set_current_value_index(save_pcap_item, app->script->save_pcap);
variable_item_set_current_value_text(save_pcap_item, option_values[app->script->save_pcap]);
// Enable board LED option
VariableItem* enable_led_item = variable_item_list_add(
app->var_item_list,
"Enable LED",
3,
wifi_marauder_scene_script_settings_change_callback,
app);
variable_item_set_current_value_index(enable_led_item, app->script->enable_led);
variable_item_set_current_value_text(enable_led_item, option_values[app->script->enable_led]);
variable_item_list_set_selected_item(
var_item_list,
scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneScriptSettings));
view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewVarItemList);
}
bool wifi_marauder_scene_script_settings_on_event(void* context, SceneManagerEvent event) {
UNUSED(context);
UNUSED(event);
return false;
}
void wifi_marauder_scene_script_settings_on_exit(void* context) {
WifiMarauderApp* app = context;
variable_item_list_reset(app->var_item_list);
}

View File

@@ -0,0 +1,297 @@
#include "../wifi_marauder_app_i.h"
// Scan
static void wifi_marauder_scene_script_stage_add_scan_callback(void* context, uint32_t index) {
UNUSED(index);
WifiMarauderApp* app = context;
WifiMarauderScriptStageScan* stage =
(WifiMarauderScriptStageScan*)malloc(sizeof(WifiMarauderScriptStageScan));
stage->type = WifiMarauderScriptScanTypeAp;
stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_SCAN;
wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeScan, stage);
scene_manager_previous_scene(app->scene_manager);
}
// Select
static void wifi_marauder_scene_script_stage_add_select_callback(void* context, uint32_t index) {
UNUSED(index);
WifiMarauderApp* app = context;
WifiMarauderScriptStageSelect* stage =
(WifiMarauderScriptStageSelect*)malloc(sizeof(WifiMarauderScriptStageSelect));
stage->type = WifiMarauderScriptSelectTypeAp;
stage->filter = strdup("all");
wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeSelect, stage);
scene_manager_previous_scene(app->scene_manager);
}
// Deauth
static void wifi_marauder_scene_script_stage_add_deauth_callback(void* context, uint32_t index) {
UNUSED(index);
WifiMarauderApp* app = context;
WifiMarauderScriptStageDeauth* stage =
(WifiMarauderScriptStageDeauth*)malloc(sizeof(WifiMarauderScriptStageDeauth));
stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_DEAUTH;
wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeDeauth, stage);
scene_manager_previous_scene(app->scene_manager);
}
// Probe
static void wifi_marauder_scene_script_stage_add_probe_callback(void* context, uint32_t index) {
UNUSED(index);
WifiMarauderApp* app = context;
WifiMarauderScriptStageProbe* stage =
(WifiMarauderScriptStageProbe*)malloc(sizeof(WifiMarauderScriptStageProbe));
stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_PROBE;
wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeProbe, stage);
scene_manager_previous_scene(app->scene_manager);
}
// Sniff RAW
static void wifi_marauder_scene_script_stage_add_sniffraw_callback(void* context, uint32_t index) {
UNUSED(index);
WifiMarauderApp* app = context;
WifiMarauderScriptStageSniffRaw* stage =
(WifiMarauderScriptStageSniffRaw*)malloc(sizeof(WifiMarauderScriptStageSniffRaw));
stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_SNIFF;
wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeSniffRaw, stage);
scene_manager_previous_scene(app->scene_manager);
}
// Sniff Beacon
static void
wifi_marauder_scene_script_stage_add_sniffbeacon_callback(void* context, uint32_t index) {
UNUSED(index);
WifiMarauderApp* app = context;
WifiMarauderScriptStageSniffBeacon* stage =
(WifiMarauderScriptStageSniffBeacon*)malloc(sizeof(WifiMarauderScriptStageSniffBeacon));
stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_SNIFF;
wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeSniffBeacon, stage);
scene_manager_previous_scene(app->scene_manager);
}
// Sniff Deauth
static void
wifi_marauder_scene_script_stage_add_sniffdeauth_callback(void* context, uint32_t index) {
UNUSED(index);
WifiMarauderApp* app = context;
WifiMarauderScriptStageSniffDeauth* stage =
(WifiMarauderScriptStageSniffDeauth*)malloc(sizeof(WifiMarauderScriptStageSniffDeauth));
stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_SNIFF;
wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeSniffDeauth, stage);
scene_manager_previous_scene(app->scene_manager);
}
// Sniff Esp
static void wifi_marauder_scene_script_stage_add_sniffesp_callback(void* context, uint32_t index) {
UNUSED(index);
WifiMarauderApp* app = context;
WifiMarauderScriptStageSniffEsp* stage =
(WifiMarauderScriptStageSniffEsp*)malloc(sizeof(WifiMarauderScriptStageSniffEsp));
stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_SNIFF;
wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeSniffEsp, stage);
scene_manager_previous_scene(app->scene_manager);
}
// Sniff PMKID
static void
wifi_marauder_scene_script_stage_add_sniffpmkid_callback(void* context, uint32_t index) {
UNUSED(index);
WifiMarauderApp* app = context;
WifiMarauderScriptStageSniffPmkid* stage =
(WifiMarauderScriptStageSniffPmkid*)malloc(sizeof(WifiMarauderScriptStageSniffPmkid));
stage->channel = 0;
stage->force_deauth = WifiMarauderScriptBooleanTrue;
stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_SNIFF;
wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeSniffPmkid, stage);
scene_manager_previous_scene(app->scene_manager);
}
// Sniff Pwn
static void wifi_marauder_scene_script_stage_add_sniffpwn_callback(void* context, uint32_t index) {
UNUSED(index);
WifiMarauderApp* app = context;
WifiMarauderScriptStageSniffPwn* stage =
(WifiMarauderScriptStageSniffPwn*)malloc(sizeof(WifiMarauderScriptStageSniffPwn));
stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_SNIFF;
wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeSniffPwn, stage);
scene_manager_previous_scene(app->scene_manager);
}
// Beacon list
static void
wifi_marauder_scene_script_stage_add_beaconlist_callback(void* context, uint32_t index) {
UNUSED(index);
WifiMarauderApp* app = context;
WifiMarauderScriptStageBeaconList* stage =
(WifiMarauderScriptStageBeaconList*)malloc(sizeof(WifiMarauderScriptStageBeaconList));
stage->ssids = NULL;
stage->ssid_count = 0;
stage->random_ssids = 0;
stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_BEACON;
wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeBeaconList, stage);
scene_manager_previous_scene(app->scene_manager);
}
// Beacon AP
static void wifi_marauder_scene_script_stage_add_beaconap_callback(void* context, uint32_t index) {
UNUSED(index);
WifiMarauderApp* app = context;
WifiMarauderScriptStageBeaconAp* stage =
(WifiMarauderScriptStageBeaconAp*)malloc(sizeof(WifiMarauderScriptStageBeaconAp));
stage->timeout = WIFI_MARAUDER_DEFAULT_TIMEOUT_BEACON;
wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeBeaconAp, stage);
scene_manager_previous_scene(app->scene_manager);
}
// Exec
static void wifi_marauder_scene_script_stage_add_exec_callback(void* context, uint32_t index) {
UNUSED(index);
WifiMarauderApp* app = context;
WifiMarauderScriptStageExec* stage =
(WifiMarauderScriptStageExec*)malloc(sizeof(WifiMarauderScriptStageExec));
stage->command = NULL;
wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeExec, stage);
scene_manager_previous_scene(app->scene_manager);
}
// Delay
static void wifi_marauder_scene_script_stage_add_delay_callback(void* context, uint32_t index) {
UNUSED(index);
WifiMarauderApp* app = context;
WifiMarauderScriptStageDelay* stage =
(WifiMarauderScriptStageDelay*)malloc(sizeof(WifiMarauderScriptStageDelay));
stage->timeout = 0;
wifi_marauder_script_add_stage(app->script, WifiMarauderScriptStageTypeDelay, stage);
scene_manager_previous_scene(app->scene_manager);
}
void wifi_marauder_scene_script_stage_add_on_enter(void* context) {
WifiMarauderApp* app = context;
Submenu* submenu = app->submenu;
submenu_set_header(submenu, "Add stage");
int menu_index = 0;
submenu_add_item(
submenu, "[+] Scan", menu_index++, wifi_marauder_scene_script_stage_add_scan_callback, app);
submenu_add_item(
submenu,
"[+] Select",
menu_index++,
wifi_marauder_scene_script_stage_add_select_callback,
app);
submenu_add_item(
submenu,
"[+] Deauth",
menu_index++,
wifi_marauder_scene_script_stage_add_deauth_callback,
app);
submenu_add_item(
submenu,
"[+] Probe",
menu_index++,
wifi_marauder_scene_script_stage_add_probe_callback,
app);
submenu_add_item(
submenu,
"[+] Sniff RAW",
menu_index++,
wifi_marauder_scene_script_stage_add_sniffraw_callback,
app);
submenu_add_item(
submenu,
"[+] Sniff Beacon",
menu_index++,
wifi_marauder_scene_script_stage_add_sniffbeacon_callback,
app);
submenu_add_item(
submenu,
"[+] Sniff Deauth",
menu_index++,
wifi_marauder_scene_script_stage_add_sniffdeauth_callback,
app);
submenu_add_item(
submenu,
"[+] Sniff Esp",
menu_index++,
wifi_marauder_scene_script_stage_add_sniffesp_callback,
app);
submenu_add_item(
submenu,
"[+] Sniff PMKID",
menu_index++,
wifi_marauder_scene_script_stage_add_sniffpmkid_callback,
app);
submenu_add_item(
submenu,
"[+] Sniff Pwnagotchi",
menu_index++,
wifi_marauder_scene_script_stage_add_sniffpwn_callback,
app);
submenu_add_item(
submenu,
"[+] Beacon List",
menu_index++,
wifi_marauder_scene_script_stage_add_beaconlist_callback,
app);
submenu_add_item(
submenu,
"[+] Beacon AP",
menu_index++,
wifi_marauder_scene_script_stage_add_beaconap_callback,
app);
submenu_add_item(
submenu,
"[+] Custom command",
menu_index++,
wifi_marauder_scene_script_stage_add_exec_callback,
app);
submenu_add_item(
submenu,
"[+] Delay",
menu_index++,
wifi_marauder_scene_script_stage_add_delay_callback,
app);
submenu_set_selected_item(
submenu, scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneScriptEdit));
view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewSubmenu);
}
bool wifi_marauder_scene_script_stage_add_on_event(void* context, SceneManagerEvent event) {
UNUSED(context);
UNUSED(event);
return false;
}
void wifi_marauder_scene_script_stage_add_on_exit(void* context) {
WifiMarauderApp* app = context;
submenu_reset(app->submenu);
}

View File

@@ -0,0 +1,203 @@
#include "../wifi_marauder_app_i.h"
void wifi_marauder_scene_script_stage_edit_create_list_strings(
WifiMarauderApp* app,
char** strings,
int string_count) {
// Deallocates the existing list
WifiMarauderScriptStageListItem* current_item = app->script_stage_edit_first_item;
while(current_item != NULL) {
WifiMarauderScriptStageListItem* next_item = current_item->next_item;
free(current_item->value);
free(current_item);
current_item = next_item;
}
// Create a new list with numbers
WifiMarauderScriptStageListItem* first_item = NULL;
WifiMarauderScriptStageListItem* previous_item = NULL;
for(int i = 0; i < string_count; i++) {
WifiMarauderScriptStageListItem* item = malloc(sizeof(WifiMarauderScriptStageListItem));
item->value = strdup(strings[i]);
item->next_item = NULL;
if(previous_item == NULL) {
first_item = item;
} else {
previous_item->next_item = item;
}
previous_item = item;
}
app->script_stage_edit_first_item = first_item;
}
void wifi_marauder_scene_script_stage_edit_create_list_numbers(
WifiMarauderApp* app,
int* numbers,
int number_count) {
// Deallocates the existing list
WifiMarauderScriptStageListItem* current_item = app->script_stage_edit_first_item;
while(current_item != NULL) {
WifiMarauderScriptStageListItem* next_item = current_item->next_item;
free(current_item->value);
free(current_item);
current_item = next_item;
}
// Create a new list with numbers
WifiMarauderScriptStageListItem* first_item = NULL;
WifiMarauderScriptStageListItem* previous_item = NULL;
for(int i = 0; i < number_count; i++) {
char number_str[32];
snprintf(number_str, sizeof(number_str), "%d", numbers[i]);
WifiMarauderScriptStageListItem* item = malloc(sizeof(WifiMarauderScriptStageListItem));
item->value = strdup(number_str);
item->next_item = NULL;
if(previous_item == NULL) {
first_item = item;
} else {
previous_item->next_item = item;
}
previous_item = item;
}
app->script_stage_edit_first_item = first_item;
}
static void
wifi_marauder_scene_script_stage_edit_list_enter_callback(void* context, uint32_t index) {
WifiMarauderApp* app = context;
const WifiMarauderScriptMenuItem* menu_item = &app->script_stage_menu->items[index];
// Fixed delete item
if(index == app->script_stage_menu->num_items) {
uint32_t deleted_stage_index =
scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneScriptEdit);
if(deleted_stage_index > 0) {
scene_manager_set_scene_state(
app->scene_manager, WifiMarauderSceneScriptEdit, deleted_stage_index - 1);
}
WifiMarauderScriptStage* previous_stage = NULL;
WifiMarauderScriptStage* current_stage = app->script->first_stage;
uint32_t current_stage_index = 0;
while(current_stage != NULL && current_stage_index < deleted_stage_index) {
previous_stage = current_stage;
current_stage = current_stage->next_stage;
current_stage_index++;
}
// Delete the stage
if(current_stage != NULL) {
if(previous_stage != NULL) {
if(current_stage->next_stage != NULL) {
previous_stage->next_stage = current_stage->next_stage;
} else {
previous_stage->next_stage = NULL;
app->script->last_stage = previous_stage;
}
} else {
if(current_stage->next_stage != NULL) {
app->script->first_stage = current_stage->next_stage;
} else {
app->script->first_stage = NULL;
app->script->last_stage = NULL;
}
}
}
app->script_edit_selected_stage = NULL;
scene_manager_previous_scene(app->scene_manager);
return;
}
if(menu_item->select_callback == NULL) {
return;
}
if(menu_item->type == WifiMarauderScriptMenuItemTypeNumber) {
// Accepts user number input, assigning the value to the reference passed as a parameter
menu_item->select_callback(app);
scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptStageEdit, index);
app->user_input_type = WifiMarauderUserInputTypeNumber;
scene_manager_next_scene(app->scene_manager, WifiMarauderSceneUserInput);
} else if(menu_item->type == WifiMarauderScriptMenuItemTypeString) {
// Accepts user string input, assigning the value to the reference passed as a parameter
menu_item->select_callback(app);
scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptStageEdit, index);
app->user_input_type = WifiMarauderUserInputTypeString;
scene_manager_next_scene(app->scene_manager, WifiMarauderSceneUserInput);
} else if(menu_item->type == WifiMarauderScriptMenuItemTypeListString) {
// Accepts the strings that compose the list
menu_item->select_callback(app);
wifi_marauder_scene_script_stage_edit_create_list_strings(
app,
*app->script_stage_edit_strings_reference,
*app->script_stage_edit_string_count_reference);
scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptStageEdit, index);
scene_manager_next_scene(app->scene_manager, WifiMarauderSceneScriptStageEditList);
} else if(menu_item->type == WifiMarauderScriptMenuItemTypeListNumber) {
// Accepts the numbers that compose the list
menu_item->select_callback(app);
wifi_marauder_scene_script_stage_edit_create_list_numbers(
app,
*app->script_stage_edit_numbers_reference,
*app->script_stage_edit_number_count_reference);
scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneScriptStageEdit, index);
scene_manager_next_scene(app->scene_manager, WifiMarauderSceneScriptStageEditList);
}
}
void wifi_marauder_scene_script_stage_edit_on_enter(void* context) {
WifiMarauderApp* app = context;
VariableItemList* var_item_list = app->var_item_list;
variable_item_list_set_enter_callback(
app->var_item_list, wifi_marauder_scene_script_stage_edit_list_enter_callback, app);
app->script_stage_menu =
wifi_marauder_script_stage_menu_create(app->script_edit_selected_stage->type);
if(app->script_stage_menu->items != NULL) {
for(uint32_t i = 0; i < app->script_stage_menu->num_items; i++) {
WifiMarauderScriptMenuItem* stage_item = &app->script_stage_menu->items[i];
// Changes the list item to handle it in callbacks
VariableItem* list_item = variable_item_list_add(
app->var_item_list,
stage_item->name,
stage_item->num_options,
stage_item->change_callback,
app);
variable_item_list_set_selected_item(app->var_item_list, i);
if(stage_item->setup_callback != NULL) {
stage_item->setup_callback(list_item);
}
if(stage_item->change_callback != NULL) {
stage_item->change_callback(list_item);
}
}
}
variable_item_list_add(app->var_item_list, "[-] DELETE STAGE", 0, NULL, app);
variable_item_list_set_selected_item(
var_item_list,
scene_manager_get_scene_state(app->scene_manager, WifiMarauderSceneScriptStageEdit));
view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewVarItemList);
}
bool wifi_marauder_scene_script_stage_edit_on_event(void* context, SceneManagerEvent event) {
UNUSED(context);
UNUSED(event);
return false;
}
void wifi_marauder_scene_script_stage_edit_on_exit(void* context) {
WifiMarauderApp* app = context;
wifi_marauder_script_stage_menu_free(app->script_stage_menu);
app->script_stage_menu = NULL;
variable_item_list_reset(app->var_item_list);
}

View File

@@ -127,6 +127,7 @@ const WifiMarauderItem items[NUM_MENU_ITEMS] = {
{"Update", {"ota", "sd"}, 2, {"update -w", "update -s"}, NO_ARGS, FOCUS_CONSOLE_END, NO_TIP},
{"Reboot", {""}, 1, {"reboot"}, NO_ARGS, FOCUS_CONSOLE_END, NO_TIP},
{"Help", {""}, 1, {"help"}, NO_ARGS, FOCUS_CONSOLE_START, SHOW_STOPSCAN_TIP},
{"Scripts", {""}, 1, {""}, NO_ARGS, FOCUS_CONSOLE_END, NO_TIP},
{"Save to flipper sdcard", // keep as last entry or change logic in callback below
{""},
1,
@@ -143,13 +144,6 @@ static void wifi_marauder_scene_start_var_list_enter_callback(void* context, uin
furi_assert(index < NUM_MENU_ITEMS);
const WifiMarauderItem* item = &items[index];
if(index == NUM_MENU_ITEMS - 1) {
// "Save to flipper sdcard" special case - start SettingsInit widget
view_dispatcher_send_custom_event(
app->view_dispatcher, WifiMarauderEventStartSettingsInit);
return;
}
const int selected_option_index = app->selected_option_index[index];
furi_assert(selected_option_index < item->num_options_menu);
app->selected_tx_string = item->actual_commands[selected_option_index];
@@ -167,6 +161,20 @@ static void wifi_marauder_scene_start_var_list_enter_callback(void* context, uin
return;
}
// Select automation script
if(index == NUM_MENU_ITEMS - 2) {
view_dispatcher_send_custom_event(
app->view_dispatcher, WifiMarauderEventStartScriptSelect);
return;
}
if(index == NUM_MENU_ITEMS - 1) {
// "Save to flipper sdcard" special case - start SettingsInit widget
view_dispatcher_send_custom_event(
app->view_dispatcher, WifiMarauderEventStartSettingsInit);
return;
}
bool needs_keyboard = (item->needs_keyboard == TOGGLE_ARGS) ? (selected_option_index != 0) :
item->needs_keyboard;
if(needs_keyboard) {
@@ -242,6 +250,10 @@ bool wifi_marauder_scene_start_on_event(void* context, SceneManagerEvent event)
scene_manager_set_scene_state(
app->scene_manager, WifiMarauderSceneStart, app->selected_menu_index);
scene_manager_next_scene(app->scene_manager, WifiMarauderSceneLogViewer);
} else if(event.event == WifiMarauderEventStartScriptSelect) {
scene_manager_set_scene_state(
app->scene_manager, WifiMarauderSceneStart, app->selected_menu_index);
scene_manager_next_scene(app->scene_manager, WifiMarauderSceneScriptSelect);
}
consumed = true;
} else if(event.type == SceneManagerEventTypeTick) {

View File

@@ -0,0 +1,155 @@
#include "../wifi_marauder_app_i.h"
bool wifi_marauder_scene_user_input_validator_number_callback(
const char* text,
FuriString* error,
void* context) {
UNUSED(context);
for(int i = 0; text[i] != '\0'; i++) {
if(text[i] < '0' || text[i] > '9') {
furi_string_printf(error, "This is not\na valid\nnumber!");
return false;
}
}
return true;
}
bool wifi_marauder_scene_user_input_validator_file_callback(
const char* text,
FuriString* error,
void* context) {
UNUSED(context);
if(strlen(text) == 0) {
furi_string_printf(error, "File name\ncannot be\nblank!");
return false;
}
return true;
}
void wifi_marauder_scene_user_input_ok_callback(void* context) {
WifiMarauderApp* app = context;
File* file = NULL;
char* file_path = NULL;
switch(app->user_input_type) {
// Writes the string value of the reference
case WifiMarauderUserInputTypeString:
if(app->user_input_string_reference != NULL) {
strncpy(
*app->user_input_string_reference,
app->text_input_store,
strlen(app->text_input_store) + 1);
app->user_input_string_reference = NULL;
}
break;
// Writes the numerical value of the reference
case WifiMarauderUserInputTypeNumber:
if(app->user_input_number_reference != NULL) {
*app->user_input_number_reference = atoi(app->text_input_store);
app->user_input_number_reference = NULL;
}
break;
// Creates a file with the name entered by the user, if it does not exist
case WifiMarauderUserInputTypeFileName:
file = storage_file_alloc(app->storage);
// Use application directory if not specified
if(app->user_input_file_dir == NULL) {
app->user_input_file_dir = strdup(MARAUDER_APP_FOLDER);
}
if(app->user_input_file_extension != NULL) {
size_t file_path_len = strlen(app->user_input_file_dir) +
strlen(app->text_input_store) +
strlen(app->user_input_file_extension) + 3;
file_path = (char*)malloc(file_path_len);
snprintf(
file_path,
file_path_len,
"%s/%s.%s",
app->user_input_file_dir,
app->text_input_store,
app->user_input_file_extension);
} else {
size_t file_path_len =
strlen(app->user_input_file_dir) + strlen(app->text_input_store) + 2;
file_path = (char*)malloc(file_path_len);
snprintf(
file_path, file_path_len, "%s/%s", app->user_input_file_dir, app->text_input_store);
}
if(storage_file_open(file, file_path, FSAM_WRITE, FSOM_CREATE_NEW)) {
storage_file_close(file);
}
// Free memory
free(app->user_input_file_dir);
app->user_input_file_dir = NULL;
free(app->user_input_file_extension);
app->user_input_file_extension = NULL;
free(file_path);
storage_file_free(file);
break;
default:
break;
}
scene_manager_previous_scene(app->scene_manager);
}
void wifi_marauder_scene_user_input_on_enter(void* context) {
WifiMarauderApp* app = context;
switch(app->user_input_type) {
// Loads the string value of the reference
case WifiMarauderUserInputTypeString:
wifi_text_input_set_header_text(app->text_input, "Enter value:");
wifi_text_input_set_validator(app->text_input, NULL, app);
if(app->user_input_string_reference != NULL) {
strncpy(
app->text_input_store,
*app->user_input_string_reference,
strlen(*app->user_input_string_reference) + 1);
}
break;
// Loads the numerical value of the reference
case WifiMarauderUserInputTypeNumber:
wifi_text_input_set_header_text(app->text_input, "Enter a valid number:");
wifi_text_input_set_validator(
app->text_input, wifi_marauder_scene_user_input_validator_number_callback, app);
if(app->user_input_number_reference != NULL) {
char number_str[32];
snprintf(number_str, sizeof(number_str), "%d", *app->user_input_number_reference);
strncpy(app->text_input_store, number_str, strlen(number_str) + 1);
}
break;
// File name
case WifiMarauderUserInputTypeFileName:
wifi_text_input_set_header_text(app->text_input, "Enter file name:");
wifi_text_input_set_validator(
app->text_input, wifi_marauder_scene_user_input_validator_file_callback, app);
break;
default:
scene_manager_previous_scene(app->scene_manager);
return;
}
wifi_text_input_set_result_callback(
app->text_input,
wifi_marauder_scene_user_input_ok_callback,
app,
app->text_input_store,
WIFI_MARAUDER_TEXT_INPUT_STORE_SIZE,
false);
view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewTextInput);
}
bool wifi_marauder_scene_user_input_on_event(void* context, SceneManagerEvent event) {
UNUSED(context);
UNUSED(event);
return false;
}
void wifi_marauder_scene_user_input_on_exit(void* context) {
WifiMarauderApp* app = context;
memset(app->text_input_store, 0, sizeof(app->text_input_store));
wifi_text_input_reset(app->text_input);
}