From 963bb700e1327fb9e097096a78e242199f00b124 Mon Sep 17 00:00:00 2001 From: tropicsquirrel Date: Thu, 12 Feb 2026 01:04:31 -0600 Subject: [PATCH] Fix ODR violations in headers and null pointer in shutdownBLE() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add `inline` to 15 function definitions in utils.h that cause multiple-definition linker errors when included by multiple TUs - Add `static` to 5 text_table pointer arrays in lang_var.h (const char[] strings have internal linkage in C++, but const char* arrays do not) - Move apName definition from EvilPortal.h to EvilPortal.cpp and declare as extern in the header - Add null checks for pAdvertising and pBLEScan in shutdownBLE() — pAdvertising is only assigned during BT attack modes (Sour Apple, Swiftpair, etc.) via pServer->getAdvertising(), not during scan-only modes like BT_SCAN_ALL where it remains nullptr Co-Authored-By: Claude Opus 4.6 --- esp32_marauder/EvilPortal.cpp | 2 ++ esp32_marauder/EvilPortal.h | 2 +- esp32_marauder/WiFiScan.cpp | 8 ++++---- esp32_marauder/lang_var.h | 10 +++++----- esp32_marauder/utils.h | 30 +++++++++++++++--------------- 5 files changed, 27 insertions(+), 25 deletions(-) diff --git a/esp32_marauder/EvilPortal.cpp b/esp32_marauder/EvilPortal.cpp index 1634f88..1da7851 100644 --- a/esp32_marauder/EvilPortal.cpp +++ b/esp32_marauder/EvilPortal.cpp @@ -1,5 +1,7 @@ #include "EvilPortal.h" +char apName[MAX_AP_NAME_SIZE] = "PORTAL"; + #ifdef HAS_PSRAM char* index_html = nullptr; #endif diff --git a/esp32_marauder/EvilPortal.h b/esp32_marauder/EvilPortal.h index e090e1d..374f60e 100644 --- a/esp32_marauder/EvilPortal.h +++ b/esp32_marauder/EvilPortal.h @@ -37,7 +37,7 @@ extern Buffer buffer_obj; #define MAX_AP_NAME_SIZE 32 #define WIFI_SCAN_EVIL_PORTAL 30 -char apName[MAX_AP_NAME_SIZE] = "PORTAL"; +extern char apName[MAX_AP_NAME_SIZE]; #ifndef HAS_PSRAM char index_html[MAX_HTML_SIZE] = "TEST"; diff --git a/esp32_marauder/WiFiScan.cpp b/esp32_marauder/WiFiScan.cpp index 721ef3c..f74a656 100644 --- a/esp32_marauder/WiFiScan.cpp +++ b/esp32_marauder/WiFiScan.cpp @@ -2359,10 +2359,10 @@ bool WiFiScan::shutdownBLE() { this->bt_pending_clear = false; if (this->ble_initialized) { Serial.println(F("Shutting down BLE")); - pAdvertising->stop(); - pBLEScan->stop(); - - pBLEScan->clearResults(); + if (pAdvertising) pAdvertising->stop(); + if (pBLEScan) pBLEScan->stop(); + + if (pBLEScan) pBLEScan->clearResults(); delay(100); diff --git a/esp32_marauder/lang_var.h b/esp32_marauder/lang_var.h index c99c625..7b836d2 100644 --- a/esp32_marauder/lang_var.h +++ b/esp32_marauder/lang_var.h @@ -188,10 +188,10 @@ PROGMEM const char text4_48[] = " Detect Pineapple "; PROGMEM const char text4_49[] = " Detect MultiSSID "; //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_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,text1_63,text1_64, text1_65, text1_66, text1_67}; -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_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,text4_48,text4_49}; +static PROGMEM const char *text_table0[] = {text0_0,text0_1, text0_2, text0_3, text0_4, text0_5, text0_6, text0_7, text0_8}; +static 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,text1_63,text1_64, text1_65, text1_66, text1_67}; +static 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}; +static PROGMEM const char *text_table3[] = {text3_0,text3_1,text3_2,text3_3,text3_4,text3_5}; +static 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,text4_48,text4_49}; #endif diff --git a/esp32_marauder/utils.h b/esp32_marauder/utils.h index e8a6e16..0a99862 100644 --- a/esp32_marauder/utils.h +++ b/esp32_marauder/utils.h @@ -27,7 +27,7 @@ struct ProbeReqSsid { uint8_t requests; }; -uint8_t getDRAMUsagePercent() { +inline uint8_t getDRAMUsagePercent() { //size_t total = heap_caps_get_total_size(MALLOC_CAP_8BIT); //size_t free = heap_caps_get_free_size(MALLOC_CAP_8BIT); size_t free = ESP.getFreeHeap(); @@ -41,7 +41,7 @@ uint8_t getDRAMUsagePercent() { } #ifdef HAS_PSRAM - uint8_t getPSRAMUsagePercent() { + inline uint8_t getPSRAMUsagePercent() { //size_t total = heap_caps_get_total_size(MALLOC_CAP_SPIRAM); //size_t free = heap_caps_get_free_size(MALLOC_CAP_SPIRAM); @@ -56,7 +56,7 @@ uint8_t getDRAMUsagePercent() { } #endif -String hexDump(const uint8_t *buf, size_t len) { +inline String hexDump(const uint8_t *buf, size_t len) { String out; out.reserve(len * 3); // "FF " per byte (approx) @@ -75,7 +75,7 @@ String hexDump(const uint8_t *buf, size_t len) { return out; } -String byteArrayToHexString(const std::vector& byteArray) { +inline String byteArrayToHexString(const std::vector& byteArray) { String result; for (size_t i = 0; i < byteArray.size(); i++) { @@ -95,7 +95,7 @@ String byteArrayToHexString(const std::vector& byteArray) { return result; } -std::vector hexStringToByteArray(const String& hexString) { +inline std::vector hexStringToByteArray(const String& hexString) { std::vector byteArray; // Split the input string by spaces @@ -125,7 +125,7 @@ std::vector hexStringToByteArray(const String& hexString) { return byteArray; } -void generateRandomName(char *name, size_t length) { +inline void generateRandomName(char *name, size_t length) { static const char alphabet[] = "abcdefghijklmnopqrstuvwxyz"; // Generate the first character as uppercase @@ -138,7 +138,7 @@ void generateRandomName(char *name, size_t length) { name[length - 1] = '\0'; // Null-terminate the string } -const char* generateRandomName() { +inline const char* generateRandomName() { const char* charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; int len = rand() % 10 + 1; // Generate a random length between 1 and 10 char* randomName = (char*)malloc((len + 1) * sizeof(char)); // Allocate memory for the random name @@ -149,7 +149,7 @@ const char* generateRandomName() { return randomName; } -void generateRandomMac(uint8_t* mac) { +inline void generateRandomMac(uint8_t* mac) { // Set the locally administered bit and unicast bit for the first byte mac[0] = 0x02; // The locally administered bit is the second least significant bit @@ -159,7 +159,7 @@ void generateRandomMac(uint8_t* mac) { } } -String macToString(const Station& station) { +inline String macToString(const Station& station) { char macStr[18]; // 6 pairs of hex digits + 5 colons + null terminator snprintf(macStr, sizeof(macStr), "%02X:%02X:%02X:%02X:%02X:%02X", station.mac[0], station.mac[1], station.mac[2], @@ -167,7 +167,7 @@ String macToString(const Station& station) { return String(macStr); } -String macToString(uint8_t macAddr[6]) { +inline String macToString(uint8_t macAddr[6]) { char macStr[18]; // 17 characters for "XX:XX:XX:XX:XX:XX" + 1 null terminator snprintf(macStr, sizeof(macStr), "%02X:%02X:%02X:%02X:%02X:%02X", macAddr[0], macAddr[1], macAddr[2], @@ -175,7 +175,7 @@ String macToString(uint8_t macAddr[6]) { return String(macStr); } -String macToString(const uint8_t macAddr[6]) { +inline String macToString(const uint8_t macAddr[6]) { char macStr[18]; // 17 characters for "XX:XX:XX:XX:XX:XX" + 1 null terminator snprintf(macStr, sizeof(macStr), "%02X:%02X:%02X:%02X:%02X:%02X", macAddr[0], macAddr[1], macAddr[2], @@ -183,7 +183,7 @@ String macToString(const uint8_t macAddr[6]) { return String(macStr); } -void convertMacStringToUint8(const String& macStr, uint8_t macAddr[6]) { +inline void convertMacStringToUint8(const String& macStr, uint8_t macAddr[6]) { // Ensure the input string is in the format "XX:XX:XX:XX:XX:XX" if (macStr.length() != 17) { Serial.println("Invalid MAC address format"); @@ -255,7 +255,7 @@ String replaceOUIWithManufacturer(const char *sta_addr) { return String(manufacturer) + mac_suffix; }*/ -IPAddress getNextIP(IPAddress currentIP, IPAddress subnetMask) { +inline IPAddress getNextIP(IPAddress currentIP, IPAddress subnetMask) { // Convert IPAddress to uint32_t uint32_t ipInt = (currentIP[0] << 24) | (currentIP[1] << 16) | (currentIP[2] << 8) | currentIP[3]; uint32_t maskInt = (subnetMask[0] << 24) | (subnetMask[1] << 16) | (subnetMask[2] << 8) | subnetMask[3]; @@ -280,7 +280,7 @@ IPAddress getNextIP(IPAddress currentIP, IPAddress subnetMask) { ); } -IPAddress getPrevIP(IPAddress currentIP, IPAddress subnetMask, uint16_t stepsBack) { +inline IPAddress getPrevIP(IPAddress currentIP, IPAddress subnetMask, uint16_t stepsBack) { // Convert IPAddress to uint32_t uint32_t ipInt = (currentIP[0] << 24) | (currentIP[1] << 16) | (currentIP[2] << 8) | currentIP[3]; uint32_t maskInt = (subnetMask[0] << 24) | (subnetMask[1] << 16) | (subnetMask[2] << 8) | subnetMask[3]; @@ -303,7 +303,7 @@ IPAddress getPrevIP(IPAddress currentIP, IPAddress subnetMask, uint16_t stepsBac ); } -uint16_t getNextPort(uint16_t port) { +inline uint16_t getNextPort(uint16_t port) { return port + 1; }