wifi_marauder_scene_console_output.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. #include "../wifi_marauder_app_i.h"
  2. char* _wifi_marauder_get_prefix_from_cmd(const char* command) {
  3. int end = strcspn(command, " ");
  4. char* prefix = (char*)malloc(sizeof(char) * (end + 1));
  5. strncpy(prefix, command, end);
  6. prefix[end] = '\0';
  7. return prefix;
  8. }
  9. bool _wifi_marauder_is_save_pcaps_enabled(WifiMarauderApp* app) {
  10. if(!app->ok_to_save_pcaps) {
  11. return false;
  12. }
  13. // If it is a script that contains a sniff function
  14. if(app->script != NULL) {
  15. return wifi_marauder_script_has_stage(app->script, WifiMarauderScriptStageTypeSniffRaw) ||
  16. wifi_marauder_script_has_stage(
  17. app->script, WifiMarauderScriptStageTypeSniffBeacon) ||
  18. wifi_marauder_script_has_stage(
  19. app->script, WifiMarauderScriptStageTypeSniffDeauth) ||
  20. wifi_marauder_script_has_stage(app->script, WifiMarauderScriptStageTypeSniffEsp) ||
  21. wifi_marauder_script_has_stage(
  22. app->script, WifiMarauderScriptStageTypeSniffPmkid) ||
  23. wifi_marauder_script_has_stage(app->script, WifiMarauderScriptStageTypeSniffPwn);
  24. }
  25. // If it is a sniff function
  26. return app->is_command && app->selected_tx_string &&
  27. strncmp("sniff", app->selected_tx_string, strlen("sniff")) == 0;
  28. }
  29. void wifi_marauder_console_output_handle_rx_data_cb(uint8_t* buf, size_t len, void* context) {
  30. furi_assert(context);
  31. WifiMarauderApp* app = context;
  32. if(app->is_writing_log) {
  33. app->has_saved_logs_this_session = true;
  34. storage_file_write(app->log_file, buf, len);
  35. }
  36. // If text box store gets too big, then truncate it
  37. app->text_box_store_strlen += len;
  38. if(app->text_box_store_strlen >= WIFI_MARAUDER_TEXT_BOX_STORE_SIZE - 1) {
  39. furi_string_right(app->text_box_store, app->text_box_store_strlen / 2);
  40. app->text_box_store_strlen = furi_string_size(app->text_box_store) + len;
  41. }
  42. // Null-terminate buf and append to text box store
  43. buf[len] = '\0';
  44. furi_string_cat_printf(app->text_box_store, "%s", buf);
  45. view_dispatcher_send_custom_event(app->view_dispatcher, WifiMarauderEventRefreshConsoleOutput);
  46. }
  47. void wifi_marauder_console_output_handle_rx_packets_cb(uint8_t* buf, size_t len, void* context) {
  48. furi_assert(context);
  49. WifiMarauderApp* app = context;
  50. if(app->is_writing_pcap) {
  51. storage_file_write(app->capture_file, buf, len);
  52. }
  53. }
  54. void wifi_marauder_scene_console_output_on_enter(void* context) {
  55. WifiMarauderApp* app = context;
  56. // Reset text box and set font
  57. TextBox* text_box = app->text_box;
  58. text_box_reset(text_box);
  59. text_box_set_font(text_box, TextBoxFontText);
  60. // Set focus on start or end
  61. if(app->focus_console_start) {
  62. text_box_set_focus(text_box, TextBoxFocusStart);
  63. } else {
  64. text_box_set_focus(text_box, TextBoxFocusEnd);
  65. }
  66. // Set command-related messages
  67. if(app->is_command) {
  68. furi_string_reset(app->text_box_store);
  69. app->text_box_store_strlen = 0;
  70. // Help message
  71. if(0 == strncmp("help", app->selected_tx_string, strlen("help"))) {
  72. const char* help_msg = "Marauder companion " WIFI_MARAUDER_APP_VERSION "\n";
  73. furi_string_cat_str(app->text_box_store, help_msg);
  74. app->text_box_store_strlen += strlen(help_msg);
  75. }
  76. // Stopscan message
  77. if(app->show_stopscan_tip) {
  78. const char* help_msg = "Press BACK to send stopscan\n";
  79. furi_string_cat_str(app->text_box_store, help_msg);
  80. app->text_box_store_strlen += strlen(help_msg);
  81. }
  82. }
  83. // Set starting text
  84. text_box_set_text(app->text_box, furi_string_get_cstr(app->text_box_store));
  85. // Set scene state and switch view
  86. scene_manager_set_scene_state(app->scene_manager, WifiMarauderSceneConsoleOutput, 0);
  87. view_dispatcher_switch_to_view(app->view_dispatcher, WifiMarauderAppViewConsoleOutput);
  88. // Register callbacks to receive data
  89. wifi_marauder_uart_set_handle_rx_data_cb(
  90. app->uart,
  91. wifi_marauder_console_output_handle_rx_data_cb); // setup callback for general log rx thread
  92. wifi_marauder_uart_set_handle_rx_data_cb(
  93. app->lp_uart,
  94. wifi_marauder_console_output_handle_rx_packets_cb); // setup callback for packets rx thread
  95. // Get ready to send command
  96. if((app->is_command && app->selected_tx_string) || app->script) {
  97. const char* prefix =
  98. strlen(app->selected_tx_string) > 0 ?
  99. _wifi_marauder_get_prefix_from_cmd(app->selected_tx_string) : // Function name
  100. app->script->name; // Script name
  101. // Create files *before* sending command
  102. // (it takes time to iterate through the directory)
  103. if(app->ok_to_save_logs) {
  104. strcpy(
  105. app->log_file_path,
  106. sequential_file_resolve_path(
  107. app->storage, MARAUDER_APP_FOLDER_LOGS, prefix, "log"));
  108. if(app->log_file_path != NULL) {
  109. if(storage_file_open(
  110. app->log_file, app->log_file_path, FSAM_WRITE, FSOM_CREATE_ALWAYS)) {
  111. app->is_writing_log = true;
  112. } else {
  113. dialog_message_show_storage_error(app->dialogs, "Cannot open log file");
  114. }
  115. } else {
  116. dialog_message_show_storage_error(app->dialogs, "Cannot resolve log path");
  117. }
  118. }
  119. // If it is a sniff function or script, open the pcap file for recording
  120. if(_wifi_marauder_is_save_pcaps_enabled(app)) {
  121. if(sequential_file_open(
  122. app->storage, app->capture_file, MARAUDER_APP_FOLDER_PCAPS, prefix, "pcap")) {
  123. app->is_writing_pcap = true;
  124. } else {
  125. dialog_message_show_storage_error(app->dialogs, "Cannot open pcap file");
  126. }
  127. }
  128. // Send command with newline '\n'
  129. if(app->selected_tx_string) {
  130. wifi_marauder_uart_tx(
  131. (uint8_t*)(app->selected_tx_string), strlen(app->selected_tx_string));
  132. wifi_marauder_uart_tx((uint8_t*)("\n"), 1);
  133. }
  134. // Run the script if the file with the script has been opened
  135. if(app->script != NULL) {
  136. app->script_worker = wifi_marauder_script_worker_alloc();
  137. wifi_marauder_script_worker_start(app->script_worker, app->script);
  138. }
  139. }
  140. }
  141. bool wifi_marauder_scene_console_output_on_event(void* context, SceneManagerEvent event) {
  142. WifiMarauderApp* app = context;
  143. bool consumed = false;
  144. if(event.type == SceneManagerEventTypeCustom) {
  145. text_box_set_text(app->text_box, furi_string_get_cstr(app->text_box_store));
  146. consumed = true;
  147. } else if(event.type == SceneManagerEventTypeTick) {
  148. consumed = true;
  149. }
  150. return consumed;
  151. }
  152. void wifi_marauder_scene_console_output_on_exit(void* context) {
  153. WifiMarauderApp* app = context;
  154. // Automatically stop the scan when exiting view
  155. if(app->is_command) {
  156. wifi_marauder_uart_tx((uint8_t*)("stopscan\n"), strlen("stopscan\n"));
  157. furi_delay_ms(50);
  158. }
  159. // Unregister rx callback
  160. wifi_marauder_uart_set_handle_rx_data_cb(app->uart, NULL);
  161. wifi_marauder_uart_set_handle_rx_data_cb(app->lp_uart, NULL);
  162. wifi_marauder_script_worker_free(app->script_worker);
  163. app->script_worker = NULL;
  164. app->is_writing_pcap = false;
  165. if(app->capture_file && storage_file_is_open(app->capture_file)) {
  166. storage_file_close(app->capture_file);
  167. }
  168. app->is_writing_log = false;
  169. if(app->log_file && storage_file_is_open(app->log_file)) {
  170. storage_file_close(app->log_file);
  171. }
  172. }