From 006e7508dd053211494e518346d29eca2e4bdb68 Mon Sep 17 00:00:00 2001 From: Just Call Me Koko Date: Sat, 14 Dec 2024 13:17:52 -0500 Subject: [PATCH] Move save files menu and add save/load airtags --- esp32_marauder/MenuFunctions.cpp | 114 +++++++++++++++++++------------ esp32_marauder/MenuFunctions.h | 2 + esp32_marauder/WiFiScan.cpp | 105 ++++++++++++++++++++++++++++ esp32_marauder/WiFiScan.h | 2 + esp32_marauder/utils.h | 51 ++++++++++++++ 5 files changed, 229 insertions(+), 45 deletions(-) diff --git a/esp32_marauder/MenuFunctions.cpp b/esp32_marauder/MenuFunctions.cpp index a8c83ec9b..8c27b6e35 100644 --- a/esp32_marauder/MenuFunctions.cpp +++ b/esp32_marauder/MenuFunctions.cpp @@ -1432,6 +1432,8 @@ void MenuFunctions::RunSetup() loadSSIDsMenu.list = new LinkedList(); saveAPsMenu.list = new LinkedList(); loadAPsMenu.list = new LinkedList(); + saveATsMenu.list = new LinkedList(); + loadATsMenu.list = new LinkedList(); // Work menu names mainMenu.name = text_table1[6]; @@ -1453,6 +1455,9 @@ void MenuFunctions::RunSetup() loadSSIDsMenu.name = "Load SSIDs"; saveAPsMenu.name = "Save APs"; loadAPsMenu.name = "Load APs"; + saveATsMenu.name = "Save Airtags"; + loadATsMenu.name = "Load Airtags"; + bluetoothSnifferMenu.name = text_table1[23]; bluetoothAttackMenu.name = "Bluetooth Attacks"; generateSSIDsMenu.name = text_table1[27]; @@ -1660,9 +1665,6 @@ void MenuFunctions::RunSetup() this->changeMenu(&generateSSIDsMenu); wifi_scan_obj.RunGenerateSSIDs(); }); - this->addNodes(&wifiGeneralMenu, "Save/Load Files", TFT_CYAN, NULL, SD_UPDATE, [this]() { - this->changeMenu(&saveFileMenu); - }); #ifdef HAS_ILI9341 this->addNodes(&wifiGeneralMenu, text_table1[1], TFT_NAVY, NULL, KEYBOARD_ICO, [this](){ display_obj.clearScreen(); @@ -1929,48 +1931,6 @@ void MenuFunctions::RunSetup() this->changeMenu(clearAPsMenu.parentMenu); }); - saveSSIDsMenu.parentMenu = &saveFileMenu; - this->addNodes(&saveSSIDsMenu, text09, TFT_LIGHTGREY, NULL, 0, [this]() { - this->changeMenu(saveSSIDsMenu.parentMenu); - }); - - loadSSIDsMenu.parentMenu = &saveFileMenu; - this->addNodes(&loadSSIDsMenu, text09, TFT_LIGHTGREY, NULL, 0, [this]() { - this->changeMenu(loadSSIDsMenu.parentMenu); - }); - - saveAPsMenu.parentMenu = &saveFileMenu; - this->addNodes(&saveAPsMenu, text09, TFT_LIGHTGREY, NULL, 0, [this]() { - this->changeMenu(saveAPsMenu.parentMenu); - }); - - loadAPsMenu.parentMenu = &saveFileMenu; - this->addNodes(&loadAPsMenu, text09, TFT_LIGHTGREY, NULL, 0, [this]() { - this->changeMenu(loadAPsMenu.parentMenu); - }); - - // Save Files Menu - saveFileMenu.parentMenu = &wifiGeneralMenu; - this->addNodes(&saveFileMenu, text09, TFT_LIGHTGREY, NULL, 0, [this]() { - this->changeMenu(saveFileMenu.parentMenu); - }); - this->addNodes(&saveFileMenu, "Save SSIDs", TFT_CYAN, NULL, SD_UPDATE, [this]() { - this->changeMenu(&saveSSIDsMenu); - wifi_scan_obj.RunSaveSSIDList(true); - }); - this->addNodes(&saveFileMenu, "Load SSIDs", TFT_SKYBLUE, NULL, SD_UPDATE, [this]() { - this->changeMenu(&loadSSIDsMenu); - wifi_scan_obj.RunLoadSSIDList(); - }); - this->addNodes(&saveFileMenu, "Save APs", TFT_NAVY, NULL, SD_UPDATE, [this]() { - this->changeMenu(&saveAPsMenu); - wifi_scan_obj.RunSaveAPList(); - }); - this->addNodes(&saveFileMenu, "Load APs", TFT_BLUE, NULL, SD_UPDATE, [this]() { - this->changeMenu(&loadAPsMenu); - wifi_scan_obj.RunLoadAPList(); - }); - // Build Bluetooth Menu bluetoothMenu.parentMenu = &mainMenu; // Second Menu is third menu parent this->addNodes(&bluetoothMenu, text09, TFT_LIGHTGREY, NULL, 0, [this]() { @@ -2131,6 +2091,10 @@ void MenuFunctions::RunSetup() this->changeMenu(&whichUpdateMenu); }); + this->addNodes(&deviceMenu, "Save/Load Files", TFT_CYAN, NULL, SD_UPDATE, [this]() { + this->changeMenu(&saveFileMenu); + }); + this->addNodes(&deviceMenu, text_table1[16], TFT_GREEN, NULL, LANGUAGE, [this]() { wifi_scan_obj.currentScanMode = SHOW_INFO; @@ -2236,6 +2200,66 @@ void MenuFunctions::RunSetup() #endif #endif + // Save Files Menu + saveFileMenu.parentMenu = &deviceMenu; + this->addNodes(&saveFileMenu, text09, TFT_LIGHTGREY, NULL, 0, [this]() { + this->changeMenu(saveFileMenu.parentMenu); + }); + this->addNodes(&saveFileMenu, "Save SSIDs", TFT_CYAN, NULL, SD_UPDATE, [this]() { + this->changeMenu(&saveSSIDsMenu); + wifi_scan_obj.RunSaveSSIDList(true); + }); + this->addNodes(&saveFileMenu, "Load SSIDs", TFT_SKYBLUE, NULL, SD_UPDATE, [this]() { + this->changeMenu(&loadSSIDsMenu); + wifi_scan_obj.RunLoadSSIDList(); + }); + this->addNodes(&saveFileMenu, "Save APs", TFT_NAVY, NULL, SD_UPDATE, [this]() { + this->changeMenu(&saveAPsMenu); + wifi_scan_obj.RunSaveAPList(); + }); + this->addNodes(&saveFileMenu, "Load APs", TFT_BLUE, NULL, SD_UPDATE, [this]() { + this->changeMenu(&loadAPsMenu); + wifi_scan_obj.RunLoadAPList(); + }); + this->addNodes(&saveFileMenu, "Save Airtags", TFT_WHITE, NULL, SD_UPDATE, [this]() { + this->changeMenu(&saveAPsMenu); + wifi_scan_obj.RunSaveATList(); + }); + this->addNodes(&saveFileMenu, "Load Airtags", TFT_WHITE, NULL, SD_UPDATE, [this]() { + this->changeMenu(&loadAPsMenu); + wifi_scan_obj.RunLoadATList(); + }); + + saveSSIDsMenu.parentMenu = &saveFileMenu; + this->addNodes(&saveSSIDsMenu, text09, TFT_LIGHTGREY, NULL, 0, [this]() { + this->changeMenu(saveSSIDsMenu.parentMenu); + }); + + loadSSIDsMenu.parentMenu = &saveFileMenu; + this->addNodes(&loadSSIDsMenu, text09, TFT_LIGHTGREY, NULL, 0, [this]() { + this->changeMenu(loadSSIDsMenu.parentMenu); + }); + + saveAPsMenu.parentMenu = &saveFileMenu; + this->addNodes(&saveAPsMenu, text09, TFT_LIGHTGREY, NULL, 0, [this]() { + this->changeMenu(saveAPsMenu.parentMenu); + }); + + loadAPsMenu.parentMenu = &saveFileMenu; + this->addNodes(&loadAPsMenu, text09, TFT_LIGHTGREY, NULL, 0, [this]() { + this->changeMenu(loadAPsMenu.parentMenu); + }); + + saveATsMenu.parentMenu = &saveFileMenu; + this->addNodes(&saveATsMenu, text09, TFT_LIGHTGREY, NULL, 0, [this]() { + this->changeMenu(saveATsMenu.parentMenu); + }); + + loadATsMenu.parentMenu = &saveFileMenu; + this->addNodes(&loadATsMenu, text09, TFT_LIGHTGREY, NULL, 0, [this]() { + this->changeMenu(loadATsMenu.parentMenu); + }); + // GPS Menu #ifdef HAS_GPS if (gps_obj.getGpsModuleStatus()) { diff --git a/esp32_marauder/MenuFunctions.h b/esp32_marauder/MenuFunctions.h index 9599e20a0..c6ed5bff2 100644 --- a/esp32_marauder/MenuFunctions.h +++ b/esp32_marauder/MenuFunctions.h @@ -205,6 +205,8 @@ class MenuFunctions Menu loadSSIDsMenu; Menu saveAPsMenu; Menu loadAPsMenu; + Menu saveATsMenu; + Menu loadATsMenu; #ifdef HAS_GPS // GPS Menu diff --git a/esp32_marauder/WiFiScan.cpp b/esp32_marauder/WiFiScan.cpp index 00c282ab8..5365da2c5 100644 --- a/esp32_marauder/WiFiScan.cpp +++ b/esp32_marauder/WiFiScan.cpp @@ -1186,6 +1186,111 @@ void WiFiScan::parseBSSID(const char* bssidStr, uint8_t* bssid) { &bssid[3], &bssid[4], &bssid[5]); } +void WiFiScan::RunLoadATList() { + #ifdef HAS_SD + // Prepare to access the file + File file = sd_obj.getFile("/Airtags_0.log"); + if (!file) { + Serial.println("Could not open /Airtags_0.log"); + #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("Could not open /Airtags_0.log"); + #endif + return; + } + + // Prepare JSON + DynamicJsonDocument doc(10048); + DeserializationError error = deserializeJson(doc, file); + if (error) { + Serial.print("JSON deserialize error: "); + Serial.println(error.c_str()); + file.close(); + #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("Could not deserialize JSON"); + display_obj.tft.println(error.c_str()); + #endif + return; + } + + JsonArray array = doc.as(); + for (JsonObject obj : array) { + AirTag at; + at.mac = obj["mac"].as(); + at.payloadSize = obj["payload_size"]; + at.payload = hexStringToByteArray(obj["payload"].as()); + at.selected = false; + airtags->add(at); + } + + file.close(); + + //doc.clear(); + + #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.print("Loaded Airtags: "); + display_obj.tft.println((String)airtags->size()); + #endif + Serial.print("Loaded Airtags:"); + Serial.println((String)airtags->size()); + #endif +} + +void WiFiScan::RunSaveATList(bool save_as) { + if (save_as) { + sd_obj.removeFile("/Airtags_0.log"); + + this->startLog("Airtags"); + + DynamicJsonDocument jsonDocument(2048); + + JsonArray jsonArray = jsonDocument.to(); + + for (int i = 0; i < airtags->size(); i++) { + const AirTag& at = airtags->get(i); + JsonObject jsonAt = jsonArray.createNestedObject(); + jsonAt["mac"] = at.mac; + jsonAt["payload"] = byteArrayToHexString(at.payload); + jsonAt["payload_size"] = at.payloadSize; + } + + String jsonString; + serializeJson(jsonArray, jsonString); + + buffer_obj.append(jsonString); + + #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.print("Saved Airtags: "); + display_obj.tft.println((String)airtags->size()); + #endif + Serial.print("Saved Airtags:"); + Serial.println((String)airtags->size()); + } +} + void WiFiScan::RunLoadAPList() { #ifdef HAS_SD File file = sd_obj.getFile("/APs_0.log"); diff --git a/esp32_marauder/WiFiScan.h b/esp32_marauder/WiFiScan.h index 3cf52fa61..c72907c8c 100644 --- a/esp32_marauder/WiFiScan.h +++ b/esp32_marauder/WiFiScan.h @@ -415,6 +415,8 @@ class WiFiScan void RunLoadSSIDList(); void RunSaveAPList(bool save_as = true); void RunLoadAPList(); + void RunSaveATList(bool save_as = true); + void RunLoadATList(); void channelHop(); uint8_t currentScanMode = 0; void main(uint32_t currentTime); diff --git a/esp32_marauder/utils.h b/esp32_marauder/utils.h index a9e6ad69e..d7e683a65 100644 --- a/esp32_marauder/utils.h +++ b/esp32_marauder/utils.h @@ -3,6 +3,7 @@ #define utils_h #include +#include struct mac_addr { unsigned char bytes[6]; @@ -13,6 +14,56 @@ struct Station { bool selected; }; +String byteArrayToHexString(const std::vector& byteArray) { + String result; + + for (size_t i = 0; i < byteArray.size(); i++) { + // Append the byte in "0xXX" format + result += "0x"; + if (byteArray[i] < 0x10) { + result += "0"; // Add leading zero for single-digit hex values + } + result += String(byteArray[i], HEX); + + // Add a space between bytes, but not at the end + if (i < byteArray.size() - 1) { + result += " "; + } + } + + return result; +} + +std::vector hexStringToByteArray(const String& hexString) { + std::vector byteArray; + + // Split the input string by spaces + int startIndex = 0; + while (startIndex < hexString.length()) { + // Find the next space or end of string + int spaceIndex = hexString.indexOf(' ', startIndex); + + // If no space is found, process the last token + if (spaceIndex == -1) { + spaceIndex = hexString.length(); + } + + // Extract the "0xXX" part + String byteString = hexString.substring(startIndex, spaceIndex); + + // Convert "0xXX" to an integer and store it in the vector + if (byteString.startsWith("0x") || byteString.startsWith("0X")) { + uint8_t byte = strtol(byteString.c_str() + 2, nullptr, 16); + byteArray.push_back(byte); + } + + // Move the start index to the next byte + startIndex = spaceIndex + 1; + } + + return byteArray; +} + void generateRandomName(char *name, size_t length) { static const char alphabet[] = "abcdefghijklmnopqrstuvwxyz";