Przeglądaj źródła

Create a function for writing a script file from an object

Supported stages for saving:
- Scan
- Select
- Beacon List

Two sample scripts are created on running the application now.
tcpassos 2 lat temu
rodzic
commit
32d64610d5

+ 6 - 10
applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_console_output.c

@@ -14,16 +14,12 @@ bool _wifi_marauder_is_save_pcaps_enabled(WifiMarauderApp* app) {
     }
     }
     // If it is a script that contains a sniff function
     // If it is a script that contains a sniff function
     if (app->script != NULL) {
     if (app->script != NULL) {
-        WifiMarauderScriptStage* sniff_raw_stage = wifi_marauder_script_get_stage(app->script, WifiMarauderScriptStageTypeSniffRaw);
-        WifiMarauderScriptStage* sniff_beacon_stage = wifi_marauder_script_get_stage(app->script, WifiMarauderScriptStageTypeSniffBeacon);
-        WifiMarauderScriptStage* sniff_deauth_stage = wifi_marauder_script_get_stage(app->script, WifiMarauderScriptStageTypeSniffDeauth);
-        WifiMarauderScriptStage* sniff_esp_stage = wifi_marauder_script_get_stage(app->script, WifiMarauderScriptStageTypeSniffEsp);
-        WifiMarauderScriptStage* sniff_pmkid_stage = wifi_marauder_script_get_stage(app->script, WifiMarauderScriptStageTypeSniffPmkid);
-        WifiMarauderScriptStage* sniff_pwn_stage = wifi_marauder_script_get_stage(app->script, WifiMarauderScriptStageTypeSniffPwn);
-        if (sniff_raw_stage != NULL || sniff_beacon_stage != NULL || sniff_deauth_stage != NULL ||
-            sniff_esp_stage != NULL || sniff_pmkid_stage != NULL || sniff_pwn_stage != NULL) {
-            return true;
-        }
+        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
     // If it is a sniff function
     return app->is_command && app->selected_tx_string && strncmp("sniff", app->selected_tx_string, strlen("sniff")) == 0;
     return app->is_command && app->selected_tx_string && strncmp("sniff", app->selected_tx_string, strlen("sniff")) == 0;

+ 1 - 1
applications/external/wifi_marauder_companion/scenes/wifi_marauder_scene_script_select.c

@@ -10,7 +10,7 @@ static void wifi_marauder_scene_script_select_script_list_enter_callback(void* c
     char script_path[256];
     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]));
     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_file(script_path, app->storage);
+    app->script = wifi_marauder_script_parse_json(app->storage, script_path);
     if (app->script) {
     if (app->script) {
         scene_manager_next_scene(app->scene_manager, WifiMarauderSceneConsoleOutput);
         scene_manager_next_scene(app->scene_manager, WifiMarauderSceneConsoleOutput);
     }
     }

+ 4 - 4
applications/external/wifi_marauder_companion/script/cJSON.c

@@ -619,18 +619,18 @@ static cJSON_bool print_number(const cJSON * const item, printbuffer * const out
     /* This checks for NaN and Infinity */
     /* This checks for NaN and Infinity */
     if (isnan(d) || isinf(d))
     if (isnan(d) || isinf(d))
     {
     {
-        length = sprintf((char*)number_buffer, "null");
+        length = snprintf((char*)number_buffer, sizeof(number_buffer), "null");
     }
     }
     else
     else
     {
     {
         /* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */
         /* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */
-        length = sprintf((char*)number_buffer, "%1.15g", d);
+        length = snprintf((char*)number_buffer, sizeof(number_buffer), "%1.15g", d);
 
 
         /* Check whether the original double can be recovered */
         /* Check whether the original double can be recovered */
         if ((sscanf((char*)number_buffer, "%lg", &test) != 1) || !compare_double((double)test, d))
         if ((sscanf((char*)number_buffer, "%lg", &test) != 1) || !compare_double((double)test, d))
         {
         {
             /* If not, print with 17 decimal places of precision */
             /* If not, print with 17 decimal places of precision */
-            length = sprintf((char*)number_buffer, "%1.17g", d);
+            length = snprintf((char*)number_buffer, sizeof(number_buffer), "%1.17g", d);
         }
         }
     }
     }
 
 
@@ -1063,7 +1063,7 @@ static cJSON_bool print_string_ptr(const unsigned char * const input, printbuffe
                     break;
                     break;
                 default:
                 default:
                     /* escape and print as unicode codepoint */
                     /* escape and print as unicode codepoint */
-                    sprintf((char*)output_pointer, "u%04x", *input_pointer);
+                    snprintf((char*)output_pointer, 6, "u%04x", *input_pointer);
                     output_pointer += 4;
                     output_pointer += 4;
                     break;
                     break;
             }
             }

+ 184 - 128
applications/external/wifi_marauder_companion/script/wifi_marauder_script.c

@@ -15,12 +15,19 @@ WifiMarauderScript *wifi_marauder_script_alloc() {
     script->name = NULL;
     script->name = NULL;
     script->description = NULL;
     script->description = NULL;
     script->first_stage = NULL;
     script->first_stage = NULL;
+    script->last_stage = NULL;
     script->enable_led = WifiMarauderScriptBooleanUndefined;
     script->enable_led = WifiMarauderScriptBooleanUndefined;
     script->save_pcap = WifiMarauderScriptBooleanUndefined;
     script->save_pcap = WifiMarauderScriptBooleanUndefined;
     script->repeat = 1;
     script->repeat = 1;
     return script;
     return script;
 }
 }
 
 
+WifiMarauderScript* wifi_marauder_script_create(const char* script_name) {
+    WifiMarauderScript *script = wifi_marauder_script_alloc();
+    script->name = strdup(script_name);
+    return script;
+}
+
 void _wifi_marauder_script_load_meta(WifiMarauderScript *script, cJSON *meta_section) {
 void _wifi_marauder_script_load_meta(WifiMarauderScript *script, cJSON *meta_section) {
     if (meta_section != NULL) {
     if (meta_section != NULL) {
         // Script description
         // Script description
@@ -329,137 +336,44 @@ WifiMarauderScriptStage* _wifi_marauder_script_create_stage(WifiMarauderScriptSt
     return stage;
     return stage;
 }
 }
 
 
-void _wifi_marauder_script_add_stage(WifiMarauderScript *script, WifiMarauderScriptStage *stage, WifiMarauderScriptStage **prev_stage) {
-    if (*prev_stage != NULL) {
-        (*prev_stage)->next_stage = stage;
+void wifi_marauder_script_add_stage(WifiMarauderScript *script, WifiMarauderScriptStageType stage_type, void* stage_data) {
+    if (script == NULL || stage_data == NULL) {
+        return;
+    }
+    WifiMarauderScriptStage* stage = _wifi_marauder_script_create_stage(stage_type, stage_data);
+    if (script->last_stage != NULL) {
+        script->last_stage->next_stage = stage;
     } else {
     } else {
         script->first_stage = stage;
         script->first_stage = stage;
     }
     }
-    *prev_stage = stage;
+    script->last_stage = stage;
 }
 }
 
 
 void _wifi_marauder_script_load_stages(WifiMarauderScript *script, cJSON *stages) {
 void _wifi_marauder_script_load_stages(WifiMarauderScript *script, cJSON *stages) {
-    WifiMarauderScriptStage *prev_stage = wifi_marauder_script_get_last_stage(script);
-
     // Scan stage
     // Scan stage
-    WifiMarauderScriptStageScan *stage_scan = _wifi_marauder_script_get_stage_scan(stages);
-    if (stage_scan != NULL) {
-        _wifi_marauder_script_add_stage(
-            script,
-            _wifi_marauder_script_create_stage(WifiMarauderScriptStageTypeScan, stage_scan),
-            &prev_stage
-        );
-    }
-
+    wifi_marauder_script_add_stage(script, WifiMarauderScriptStageTypeScan, _wifi_marauder_script_get_stage_scan(stages));
     // Select stage
     // Select stage
-    WifiMarauderScriptStageSelect *stage_select = _wifi_marauder_script_get_stage_select(stages);
-    if (stage_select != NULL) {
-        _wifi_marauder_script_add_stage(
-            script,
-            _wifi_marauder_script_create_stage(WifiMarauderScriptStageTypeSelect, stage_select),
-            &prev_stage
-        );
-    }
-
+    wifi_marauder_script_add_stage(script, WifiMarauderScriptStageTypeSelect, _wifi_marauder_script_get_stage_select(stages));
     // Deauth stage
     // Deauth stage
-    WifiMarauderScriptStageDeauth *stage_deauth = _wifi_marauder_script_get_stage_deauth(stages);
-    if (stage_deauth != NULL) {
-        _wifi_marauder_script_add_stage(
-            script,
-            _wifi_marauder_script_create_stage(WifiMarauderScriptStageTypeDeauth, stage_deauth),
-            &prev_stage
-        );
-    }
-
+    wifi_marauder_script_add_stage(script, WifiMarauderScriptStageTypeDeauth, _wifi_marauder_script_get_stage_deauth(stages));
     // Probe stage
     // Probe stage
-    WifiMarauderScriptStageProbe *stage_probe = _wifi_marauder_script_get_stage_probe(stages);
-    if (stage_probe != NULL) {
-        _wifi_marauder_script_add_stage(
-            script,
-            _wifi_marauder_script_create_stage(WifiMarauderScriptStageTypeProbe, stage_probe),
-            &prev_stage
-        );
-    }
-
+    wifi_marauder_script_add_stage(script, WifiMarauderScriptStageTypeProbe, _wifi_marauder_script_get_stage_probe(stages));
     // Sniff raw stage
     // Sniff raw stage
-    WifiMarauderScriptStageSniffRaw *sniff_raw = _wifi_marauder_script_get_stage_sniff_raw(stages);
-    if (sniff_raw != NULL) {
-        _wifi_marauder_script_add_stage(
-            script,
-            _wifi_marauder_script_create_stage(WifiMarauderScriptStageTypeSniffRaw, sniff_raw),
-            &prev_stage
-        );
-    }
-
+    wifi_marauder_script_add_stage(script, WifiMarauderScriptStageTypeSniffRaw, _wifi_marauder_script_get_stage_sniff_raw(stages));
     // Sniff beacon stage
     // Sniff beacon stage
-    WifiMarauderScriptStageSniffBeacon *sniff_beacon = _wifi_marauder_script_get_stage_sniff_beacon(stages);
-    if (sniff_beacon != NULL) {
-        _wifi_marauder_script_add_stage(
-            script,
-            _wifi_marauder_script_create_stage(WifiMarauderScriptStageTypeSniffBeacon, sniff_beacon),
-            &prev_stage
-        );
-    }
-
+    wifi_marauder_script_add_stage(script, WifiMarauderScriptStageTypeSniffBeacon, _wifi_marauder_script_get_stage_sniff_beacon(stages));
     // Sniff deauth stage
     // Sniff deauth stage
-    WifiMarauderScriptStageSniffDeauth *sniff_deauth = _wifi_marauder_script_get_stage_sniff_deauth(stages);
-    if (sniff_deauth != NULL) {
-        _wifi_marauder_script_add_stage(
-            script,
-            _wifi_marauder_script_create_stage(WifiMarauderScriptStageTypeSniffDeauth, sniff_deauth),
-            &prev_stage
-        );
-    }
-
+    wifi_marauder_script_add_stage(script, WifiMarauderScriptStageTypeSniffDeauth, _wifi_marauder_script_get_stage_sniff_deauth(stages));
     // Sniff esp stage
     // Sniff esp stage
-    WifiMarauderScriptStageSniffEsp *sniff_esp = _wifi_marauder_script_get_stage_sniff_esp(stages);
-    if (sniff_esp != NULL) {
-        _wifi_marauder_script_add_stage(
-            script,
-            _wifi_marauder_script_create_stage(WifiMarauderScriptStageTypeSniffEsp, sniff_esp),
-            &prev_stage
-        );
-    }
-
+    wifi_marauder_script_add_stage(script, WifiMarauderScriptStageTypeSniffEsp, _wifi_marauder_script_get_stage_sniff_esp(stages));
     // Sniff PMKID stage
     // Sniff PMKID stage
-    WifiMarauderScriptStageSniffPmkid *sniff_pmkid = _wifi_marauder_script_get_stage_sniff_pmkid(stages);
-    if (sniff_pmkid != NULL) {
-        _wifi_marauder_script_add_stage(
-            script,
-            _wifi_marauder_script_create_stage(WifiMarauderScriptStageTypeSniffPmkid, sniff_pmkid),
-            &prev_stage
-        );
-    }
-
+    wifi_marauder_script_add_stage(script, WifiMarauderScriptStageTypeSniffPmkid, _wifi_marauder_script_get_stage_sniff_pmkid(stages));
     // Sniff pwn stage
     // Sniff pwn stage
-    WifiMarauderScriptStageSniffPwn *sniff_pwn = _wifi_marauder_script_get_stage_sniff_pwn(stages);
-    if (sniff_pwn != NULL) {
-        _wifi_marauder_script_add_stage(
-            script,
-            _wifi_marauder_script_create_stage(WifiMarauderScriptStageTypeSniffPwn, sniff_pwn),
-            &prev_stage
-        );
-    }
-
+    wifi_marauder_script_add_stage(script, WifiMarauderScriptStageTypeSniffPwn, _wifi_marauder_script_get_stage_sniff_pwn(stages));
     // Beacon List stage
     // Beacon List stage
-    WifiMarauderScriptStageBeaconList *stage_beacon_list = _wifi_marauder_script_get_stage_beacon_list(stages);
-    if (stage_beacon_list != NULL) {
-        _wifi_marauder_script_add_stage(
-            script,
-            _wifi_marauder_script_create_stage(WifiMarauderScriptStageTypeBeaconList, stage_beacon_list),
-            &prev_stage
-        );
-    }
-
+    wifi_marauder_script_add_stage(script, WifiMarauderScriptStageTypeBeaconList, _wifi_marauder_script_get_stage_beacon_list(stages));
     // Beacon Ap stage
     // Beacon Ap stage
-    WifiMarauderScriptStageBeaconAp *stage_beacon_ap = _wifi_marauder_script_get_stage_beacon_ap(stages);
-    if (stage_beacon_ap != NULL) {
-        _wifi_marauder_script_add_stage(
-            script,
-            _wifi_marauder_script_create_stage(WifiMarauderScriptStageTypeBeaconAp, stage_beacon_ap),
-            &prev_stage
-        );
-    }
+    wifi_marauder_script_add_stage(script, WifiMarauderScriptStageTypeBeaconAp, _wifi_marauder_script_get_stage_beacon_ap(stages));
 }
 }
 
 
 WifiMarauderScript *wifi_marauder_script_parse_raw(const char* json_raw) {
 WifiMarauderScript *wifi_marauder_script_parse_raw(const char* json_raw) {
@@ -487,7 +401,7 @@ WifiMarauderScript *wifi_marauder_script_parse_raw(const char* json_raw) {
     return script;
     return script;
 }
 }
 
 
-WifiMarauderScript *wifi_marauder_script_parse_file(const char* file_path, Storage* storage) {
+WifiMarauderScript *wifi_marauder_script_parse_json(Storage* storage, const char* file_path) {
     WifiMarauderScript *script = NULL;
     WifiMarauderScript *script = NULL;
     File* script_file = storage_file_alloc(storage);
     File* script_file = storage_file_alloc(storage);
 
 
@@ -512,29 +426,171 @@ WifiMarauderScript *wifi_marauder_script_parse_file(const char* file_path, Stora
     return script;
     return script;
 }
 }
 
 
-WifiMarauderScriptStage* wifi_marauder_script_get_stage(WifiMarauderScript* script, WifiMarauderScriptStageType stage_type) {
-    if (script == NULL) {
-        return NULL;
+cJSON* _wifi_marauder_script_create_json_meta(WifiMarauderScript *script) {
+    cJSON* meta_json = cJSON_CreateObject();
+    if (script->description != NULL) {
+        cJSON_AddStringToObject(meta_json, "description", script->description);
+    } else {
+        cJSON_AddStringToObject(meta_json, "description", "My Script");
     }
     }
-    WifiMarauderScriptStage* current_stage = script->first_stage;
-    while (current_stage != NULL) {
-        if (current_stage->type == stage_type) {
-            return current_stage;
+    if (script->enable_led != WifiMarauderScriptBooleanUndefined) {
+        cJSON_AddBoolToObject(meta_json, "enable_led", (script->enable_led == WifiMarauderScriptBooleanTrue));
+    }
+    if (script->save_pcap != WifiMarauderScriptBooleanUndefined) {
+        cJSON_AddBoolToObject(meta_json, "save_pcap", (script->save_pcap == WifiMarauderScriptBooleanTrue));
+    }
+    cJSON_AddNumberToObject(meta_json, "repeat", script->repeat);
+    return meta_json;
+}
+
+cJSON* _wifi_marauder_script_create_json_scan(WifiMarauderScriptStageScan* scan_stage) {
+    cJSON* stage_json = cJSON_CreateObject();
+    cJSON_AddItemToObject(stage_json, "scan", cJSON_CreateObject());
+    cJSON* scan_json = cJSON_GetObjectItem(stage_json, "scan");
+    // Scan type
+    cJSON_AddStringToObject(scan_json, "type", scan_stage->type == WifiMarauderScriptScanTypeAp ? "ap" : "station");
+    // Channel
+    if (scan_stage->channel > 0) {
+        cJSON_AddNumberToObject(scan_json, "channel", scan_stage->channel);
+    }
+    // Timeout
+    if (scan_stage->timeout > 0) {
+        cJSON_AddNumberToObject(scan_json, "timeout", scan_stage->timeout);
+    }
+    return stage_json;
+}
+
+cJSON* _wifi_marauder_script_create_json_select(WifiMarauderScriptStageSelect* select_stage) {
+    cJSON* stage_json = cJSON_CreateObject();
+    cJSON_AddItemToObject(stage_json, "select", cJSON_CreateObject());
+    cJSON* select_json = cJSON_GetObjectItem(stage_json, "select");
+    // Select type
+    cJSON_AddStringToObject(select_json, "type", select_stage->type == WifiMarauderScriptSelectTypeAp ? "ap" : select_stage->type == WifiMarauderScriptSelectTypeStation ? "station" : "ssid");
+    if (select_stage->filter != NULL) {
+        cJSON_AddStringToObject(select_json, "filter", select_stage->filter);
+    }
+    // Indexes
+    if (select_stage->indexes != NULL) {
+        cJSON* indexes_json = cJSON_CreateArray();
+        int* index_ptr = select_stage->indexes;
+        while (*index_ptr != -1) {
+            cJSON_AddItemToArray(indexes_json, cJSON_CreateNumber(*index_ptr));
+            index_ptr++;
+        }
+        if (cJSON_GetArraySize(indexes_json) > 0) {
+            cJSON_AddItemToObject(select_json, "indexes", indexes_json);
         }
         }
-        current_stage = current_stage->next_stage;
     }
     }
-    return NULL;
+    return select_json;
 }
 }
 
 
-WifiMarauderScriptStage* wifi_marauder_script_get_last_stage(WifiMarauderScript* script) {
-    if (script == NULL || script->first_stage == NULL) {
-        return NULL;
+cJSON* _wifi_marauder_script_create_json_deauth(WifiMarauderScriptStageDeauth* deauth_stage) {
+    cJSON* stage_json = cJSON_CreateObject();
+    cJSON_AddItemToObject(stage_json, "deauth", cJSON_CreateObject());
+    cJSON* deauth_json = cJSON_GetObjectItem(stage_json, "deauth");
+    // Timeout
+    if (deauth_stage->timeout > 0) {
+        cJSON_AddNumberToObject(deauth_json, "timeout", deauth_stage->timeout);
+    }
+    return stage_json;
+}
+
+cJSON* _wifi_marauder_script_create_json_beaconlist(WifiMarauderScriptStageBeaconList* beaconlist_stage) {
+    cJSON* stage_json = cJSON_CreateObject();
+    cJSON_AddItemToObject(stage_json, "beaconList", cJSON_CreateObject());
+    cJSON* beaconlist_json = cJSON_GetObjectItem(stage_json, "beaconList");
+    // SSIDs
+    if (beaconlist_stage->ssids != NULL) {
+        cJSON* ssids_json = cJSON_CreateStringArray((const char**)beaconlist_stage->ssids, beaconlist_stage->ssid_count);
+        cJSON_AddItemToObject(beaconlist_json, "ssids", ssids_json);
+    }
+    // Random SSIDs
+    if (beaconlist_stage->random_ssids > 0) {
+        cJSON_AddNumberToObject(beaconlist_json, "generate", beaconlist_stage->random_ssids);
+    }
+    // Timeout
+    if (beaconlist_stage->timeout > 0) {
+        cJSON_AddNumberToObject(beaconlist_json, "timeout", beaconlist_stage->timeout);
+    }
+    return stage_json;
+}
+
+
+void wifi_marauder_script_save_json(Storage* storage, const char* file_path, WifiMarauderScript* script) {
+    File* script_file = storage_file_alloc(storage);
+
+    if (storage_file_open(script_file, file_path, FSAM_WRITE, FSOM_CREATE_ALWAYS)) {
+        cJSON* root_json = cJSON_CreateObject();
+
+        // Meta info
+        cJSON* meta_json = _wifi_marauder_script_create_json_meta(script);
+        cJSON_AddItemToObject(root_json, "meta", meta_json);
+
+        // Create array for stages
+        cJSON* stages_array = cJSON_CreateArray();
+        cJSON_AddItemToObject(root_json, "stages", stages_array);
+
+        // Iterate over each stage and create the corresponding JSON object
+        WifiMarauderScriptStage* stage = script->first_stage;
+        while (stage != NULL) {
+            cJSON* stage_json = NULL;
+
+            switch (stage->type) {
+                case WifiMarauderScriptStageTypeScan: {
+                    WifiMarauderScriptStageScan* scan_stage = (WifiMarauderScriptStageScan*) stage->stage;
+                    stage_json = _wifi_marauder_script_create_json_scan(scan_stage);
+                    break;
+                }
+                case WifiMarauderScriptStageTypeSelect: {
+                    WifiMarauderScriptStageSelect* select_stage = (WifiMarauderScriptStageSelect*) stage->stage;
+                    stage_json = _wifi_marauder_script_create_json_select(select_stage);
+                    break;
+                }
+                case WifiMarauderScriptStageTypeDeauth: {
+                    WifiMarauderScriptStageDeauth* deauth_stage = (WifiMarauderScriptStageDeauth*) stage->stage;
+                    stage_json = _wifi_marauder_script_create_json_deauth(deauth_stage);
+                    break;
+                }
+                case WifiMarauderScriptStageTypeBeaconList: {
+                    WifiMarauderScriptStageBeaconList* beaconlist_stage = (WifiMarauderScriptStageBeaconList*) stage->stage;
+                    stage_json = _wifi_marauder_script_create_json_beaconlist(beaconlist_stage);
+                    break;
+                }
+                // TODO: Implement other stages
+                default:
+                    break;
+            }
+
+            // Add the stage JSON object to the "stages" array
+            if (stage_json != NULL) {
+                cJSON_AddItemToArray(stages_array, stage_json);
+            }
+
+            stage = stage->next_stage;
+        }
+
+        // Write JSON to file
+        char* json_str = cJSON_Print(root_json);
+        storage_file_write(script_file, json_str, strlen(json_str));
+
+        //free(json_str);
+        storage_file_close(script_file);
+    }
+    storage_file_free(script_file);
+}
+
+bool wifi_marauder_script_has_stage(WifiMarauderScript* script, WifiMarauderScriptStageType stage_type) {
+    if (script == NULL) {
+        return false;
     }
     }
     WifiMarauderScriptStage* current_stage = script->first_stage;
     WifiMarauderScriptStage* current_stage = script->first_stage;
-    while (current_stage->next_stage != NULL) {
+    while (current_stage != NULL) {
+        if (current_stage->type == stage_type) {
+            return true;
+        }
         current_stage = current_stage->next_stage;
         current_stage = current_stage->next_stage;
     }
     }
-    return current_stage;
+    return false;
 }
 }
 
 
 void wifi_marauder_script_free(WifiMarauderScript *script) {
 void wifi_marauder_script_free(WifiMarauderScript *script) {

+ 7 - 4
applications/external/wifi_marauder_companion/script/wifi_marauder_script.h

@@ -7,8 +7,8 @@
  * - Create struct WifiMarauderScriptStage???? for the new stage
  * - Create struct WifiMarauderScriptStage???? for the new stage
  * 
  * 
  * wifi_marauder_script.c
  * wifi_marauder_script.c
- * - Create function "WifiMarauderScriptStage????* _wifi_marauder_script_get_stage_????(cJSON *stages)"
  * - Change _wifi_marauder_script_load_stages() to load new stage
  * - Change _wifi_marauder_script_load_stages() to load new stage
+ * - Change wifi_marauder_script_save_json() to support the new stage
  * - Add case to free memory in wifi_marauder_script_free()
  * - Add case to free memory in wifi_marauder_script_free()
  * 
  * 
  * wifi_marauder_script_executor.c
  * wifi_marauder_script_executor.c
@@ -212,14 +212,17 @@ typedef struct WifiMarauderScript {
     char* name;
     char* name;
     char* description;
     char* description;
     WifiMarauderScriptStage *first_stage;
     WifiMarauderScriptStage *first_stage;
+    WifiMarauderScriptStage *last_stage;
     WifiMarauderScriptBoolean enable_led;
     WifiMarauderScriptBoolean enable_led;
     WifiMarauderScriptBoolean save_pcap;
     WifiMarauderScriptBoolean save_pcap;
     int repeat;
     int repeat;
 } WifiMarauderScript;
 } WifiMarauderScript;
 
 
 WifiMarauderScript* wifi_marauder_script_alloc();
 WifiMarauderScript* wifi_marauder_script_alloc();
+WifiMarauderScript* wifi_marauder_script_create(const char* script_name);
 WifiMarauderScript* wifi_marauder_script_parse_raw(const char* script_raw);
 WifiMarauderScript* wifi_marauder_script_parse_raw(const char* script_raw);
-WifiMarauderScript* wifi_marauder_script_parse_file(const char* file_path, Storage* storage);
-WifiMarauderScriptStage* wifi_marauder_script_get_stage(WifiMarauderScript* script, WifiMarauderScriptStageType stage_type);
-WifiMarauderScriptStage* wifi_marauder_script_get_last_stage(WifiMarauderScript* script);
+WifiMarauderScript* wifi_marauder_script_parse_json(Storage* storage, const char* file_path);
+void wifi_marauder_script_save_json(Storage* storage, const char* file_path, WifiMarauderScript* script);
+void wifi_marauder_script_add_stage(WifiMarauderScript* script, WifiMarauderScriptStageType stage_type, void* stage_data);
+bool wifi_marauder_script_has_stage(WifiMarauderScript* script, WifiMarauderScriptStageType stage_type);
 void wifi_marauder_script_free(WifiMarauderScript *script);
 void wifi_marauder_script_free(WifiMarauderScript *script);

+ 58 - 0
applications/external/wifi_marauder_companion/wifi_marauder_app.c

@@ -91,6 +91,62 @@ WifiMarauderApp* wifi_marauder_app_alloc() {
     return app;
     return app;
 }
 }
 
 
+void wifi_marauder_create_demo_scripts(WifiMarauderApp* app) {
+    // Beaconlist
+    const char* script_beaconlist_file = MARAUDER_APP_SCRIPT_PATH("demo_beaconlist");
+    if(!storage_file_exists(app->storage, script_beaconlist_file)) {
+        WifiMarauderScript* script_beaconlist = wifi_marauder_script_create("demo_deauth");
+        script_beaconlist->description = strdup("Beacon spam list");
+
+        WifiMarauderScriptStageBeaconList* stage_beaconlist_1 = (WifiMarauderScriptStageBeaconList*) malloc(sizeof(WifiMarauderScriptStageBeaconList));
+        stage_beaconlist_1->ssid_count = 5;
+        stage_beaconlist_1->ssids = malloc(sizeof(char*) * stage_beaconlist_1->ssid_count);
+        stage_beaconlist_1->ssids[0] = strdup("01 APERTURE SCIENCE");
+        stage_beaconlist_1->ssids[1] = strdup("02 WE DO WHAT WE MUST");
+        stage_beaconlist_1->ssids[2] = strdup("03 BECAUSE WE CAN");
+        stage_beaconlist_1->ssids[3] = strdup("04 FOR THE GOOD");
+        stage_beaconlist_1->ssids[4] = strdup("05 OF ALL OF US");
+        stage_beaconlist_1->timeout = 60;
+        wifi_marauder_script_add_stage(script_beaconlist, WifiMarauderScriptStageTypeBeaconList, stage_beaconlist_1);
+
+        WifiMarauderScriptStageBeaconList* stage_beaconlist_2 = (WifiMarauderScriptStageBeaconList*) malloc(sizeof(WifiMarauderScriptStageBeaconList));
+        stage_beaconlist_2->ssid_count = 1;
+        stage_beaconlist_2->ssids = malloc(sizeof(char*) * stage_beaconlist_2->ssid_count);
+        stage_beaconlist_2->ssids[0] = strdup("FIXED SSID");
+        stage_beaconlist_2->random_ssids = 2;
+        stage_beaconlist_2->timeout = 30;
+        wifi_marauder_script_add_stage(script_beaconlist, WifiMarauderScriptStageTypeBeaconList, stage_beaconlist_2);
+
+        wifi_marauder_script_save_json(app->storage, script_beaconlist_file, script_beaconlist);
+        wifi_marauder_script_free(script_beaconlist);
+    }
+
+    // Deauth
+    const char* script_deauth_file = MARAUDER_APP_SCRIPT_PATH("demo_deauth");
+    if(!storage_file_exists(app->storage, script_deauth_file)) {
+        WifiMarauderScript* script_deauth = wifi_marauder_script_create("demo_deauth");
+        script_deauth->description = strdup("Deauth all clients that fit the filter on channel 10 for 30 seconds");
+
+        WifiMarauderScriptStageScan* stage_scan = (WifiMarauderScriptStageScan*) malloc(sizeof(WifiMarauderScriptStageScan));
+        stage_scan->type = WifiMarauderScriptScanTypeAp;
+        stage_scan->channel = 10;
+        stage_scan->timeout = 30;
+        wifi_marauder_script_add_stage(script_deauth, WifiMarauderScriptStageTypeScan, stage_scan);
+
+        WifiMarauderScriptStageSelect* stage_select = (WifiMarauderScriptStageSelect*) malloc(sizeof(WifiMarauderScriptStageSelect));
+        stage_select->type = WifiMarauderScriptSelectTypeAp;
+        stage_select->filter = strdup("all");
+        wifi_marauder_script_add_stage(script_deauth, WifiMarauderScriptStageTypeSelect, stage_select);
+
+        WifiMarauderScriptStageDeauth *stage_deauth = (WifiMarauderScriptStageDeauth*) malloc(sizeof(WifiMarauderScriptStageDeauth));
+        stage_deauth->timeout = 30;
+        wifi_marauder_script_add_stage(script_deauth, WifiMarauderScriptStageTypeDeauth, stage_deauth);
+
+        wifi_marauder_script_save_json(app->storage, MARAUDER_APP_SCRIPT_PATH("demo_deauth"), script_deauth);
+        wifi_marauder_script_free(script_deauth);
+    }
+}
+
 void wifi_marauder_make_app_folder(WifiMarauderApp* app) {
 void wifi_marauder_make_app_folder(WifiMarauderApp* app) {
     furi_assert(app);
     furi_assert(app);
 
 
@@ -108,6 +164,8 @@ void wifi_marauder_make_app_folder(WifiMarauderApp* app) {
 
 
     if(!storage_simply_mkdir(app->storage, MARAUDER_APP_FOLDER_SCRIPTS)) {
     if(!storage_simply_mkdir(app->storage, MARAUDER_APP_FOLDER_SCRIPTS)) {
         dialog_message_show_storage_error(app->dialogs, "Cannot create\nscripts folder");
         dialog_message_show_storage_error(app->dialogs, "Cannot create\nscripts folder");
+    } else {
+        wifi_marauder_create_demo_scripts(app);
     }
     }
 }
 }
 
 

+ 2 - 1
applications/external/wifi_marauder_companion/wifi_marauder_app_i.h

@@ -32,9 +32,10 @@
 #define MARAUDER_APP_FOLDER ANY_PATH(MARAUDER_APP_FOLDER_USER)
 #define MARAUDER_APP_FOLDER ANY_PATH(MARAUDER_APP_FOLDER_USER)
 #define MARAUDER_APP_FOLDER_PCAPS MARAUDER_APP_FOLDER "/pcaps"
 #define MARAUDER_APP_FOLDER_PCAPS MARAUDER_APP_FOLDER "/pcaps"
 #define MARAUDER_APP_FOLDER_LOGS MARAUDER_APP_FOLDER "/logs"
 #define MARAUDER_APP_FOLDER_LOGS MARAUDER_APP_FOLDER "/logs"
-#define MARAUDER_APP_FOLDER_SCRIPTS MARAUDER_APP_FOLDER "/scripts"
 #define MARAUDER_APP_FOLDER_USER_PCAPS MARAUDER_APP_FOLDER_USER "/pcaps"
 #define MARAUDER_APP_FOLDER_USER_PCAPS MARAUDER_APP_FOLDER_USER "/pcaps"
 #define MARAUDER_APP_FOLDER_USER_LOGS MARAUDER_APP_FOLDER_USER "/logs"
 #define MARAUDER_APP_FOLDER_USER_LOGS MARAUDER_APP_FOLDER_USER "/logs"
+#define MARAUDER_APP_FOLDER_SCRIPTS MARAUDER_APP_FOLDER "/scripts"
+#define MARAUDER_APP_SCRIPT_PATH(file_name) MARAUDER_APP_FOLDER_SCRIPTS "/" file_name ".json"
 #define SAVE_PCAP_SETTING_FILEPATH MARAUDER_APP_FOLDER "/save_pcaps_here.setting"
 #define SAVE_PCAP_SETTING_FILEPATH MARAUDER_APP_FOLDER "/save_pcaps_here.setting"
 #define SAVE_LOGS_SETTING_FILEPATH MARAUDER_APP_FOLDER "/save_logs_here.setting"
 #define SAVE_LOGS_SETTING_FILEPATH MARAUDER_APP_FOLDER "/save_logs_here.setting"