diff --git a/.gitignore b/.gitignore index bf5cfa7..0d87727 100755 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,7 @@ build # Seeed-Studio libs lib/PN532 -lib/PN532_I2C \ No newline at end of file +lib/PN532_I2C + +# MacOS useless file +.DS_Store \ No newline at end of file diff --git a/README.md b/README.md index 84d6b47..691c801 100644 --- a/README.md +++ b/README.md @@ -34,14 +34,13 @@ Working Features: - Wi-Fi support - BLE support - BadUSB support(Limited to 4-5 files in file browser) -- NFC support(Expect bugs) +- NFC support - Some network attacks +- SubGHZ(Beta support, need more testing) WIP features: -- SubGHZ - IR -- Add more network attacks More details in the project view: https://github.com/orgs/CapibaraZero/projects/2/views/1 diff --git a/include/pins.h b/include/pins.h index 6ee7a79..82e9da8 100644 --- a/include/pins.h +++ b/include/pins.h @@ -37,6 +37,10 @@ #define SD_CARD_SCK 36 #define SD_CARD_MISO 37 +#define SX1276_NSS 1 +#define SX1276_DIO2 15 +#define SX1276_DIO1 16 + #define PN532_SDA 8 #define PN532_SCL 9 @@ -62,9 +66,12 @@ #define SD_CARD_MISO D12 #define SD_CARD_SCK D13 -#define CC1101_GDO0 A0 -#define CC1101_CSN D7 +// SX1276(SubGHZ) +#define SX1276_DIO1 D3 +#define SX1276_NSS D7 +#define SX1276_DIO2 D8 +// PN532(NFC) #define PN532_SCL A6 #define PN532_SDA A7 #endif \ No newline at end of file diff --git a/lib/SubGHZ/SubGHZ.cpp b/lib/SubGHZ/SubGHZ.cpp new file mode 100644 index 0000000..0ff0696 --- /dev/null +++ b/lib/SubGHZ/SubGHZ.cpp @@ -0,0 +1,161 @@ +#include "SubGHZ.hpp" +#include +#include +#include "../../include/pins.h" + +SX1276 radio = new Module(SX1276_NSS, RADIOLIB_NC, RADIOLIB_NC, SX1276_DIO1); + +// this function is called when a new bit is received +void IRAM_ATTR readBit(void) { + // read the data bit + radio.readBit(SX1276_DIO2); +} + +SubGHZ::SubGHZ(uint8_t sck, uint8_t miso, uint8_t mosi, uint8_t csn, + uint8_t gdo0, uint8_t gdo2) { + if (initialized) return; + int state = radio.beginFSK(); + if (state == RADIOLIB_ERR_NONE) { + Serial.println(F("success!")); + } else { + Serial.print(F("failed, code ")); + Serial.println(state); + } + _gdo0 = gdo0; + _gdo2 = gdo2; + initialized = true; +} + +SubGHZ::~SubGHZ() {} + +void SubGHZ::error_check(const char *operation, int16_t status_code) { + if (status_code != RADIOLIB_ERR_NONE) { + Serial.print(operation); + Serial.print(" : "); + Serial.print(F("failed, code ")); + Serial.println(status_code); + } +} + +void SubGHZ::init_receive() { + if (_modulation == 2) // LoRa doesn't require anything + return; + radio.setCRC(false); + radio.setAFC(true); + radio.setDirectSyncWord(0x555512AD, 0); + radio.setDirectAction(readBit); + radio.receiveDirect(); +} + +void SubGHZ::stop_receive() { radio.clearDio1Action(); } + +void SubGHZ::set_freq_mod(float freq, float bw, float deviation) { + int state = radio.setFrequency(freq); + error_check("Set frequency", state); + if (_modulation != 2) { + state = radio.setRxBandwidth(bw); + error_check("Set bandwidth", state); + state = radio.setFrequencyDeviation(deviation); + error_check("Set deviation", state); + _deviation = deviation; + } + _frequency = freq; + _bw = bw; +} + +SignalStrength SubGHZ::scan_frequency(float freq, float bw, float deviation) { + set_freq_mod(freq, bw, deviation); + return SignalStrength{.rssi = radio.getRSSI(false, false)}; +} + +SignalStrength SubGHZ::scan_frequency() { + return SignalStrength{.rssi = radio.getRSSI(false, false)}; +} + +#define DEFAULT_SAMPLING_RATE 50 + +#define READ_N_BYTE() for (int j = 7; j > -1; j--) + +void read_lora_packet(std::vector *orig_signal) { + // TODO: Add DIO0 and use it as interrupt + + // you can also receive data as byte array + size_t len = radio.getPacketLength(); + byte byteArr[len]; + int state = radio.receive(byteArr, len); + + if (state == RADIOLIB_ERR_NONE) { + // packet was successfully received + Serial.println(F("Packet arrived!")); + memcpy(orig_signal->data(), byteArr, len); + } else if (state == RADIOLIB_ERR_RX_TIMEOUT) { + // timeout occurred while waiting for a packet + Serial.println(F("timeout!")); + + } else if (state == RADIOLIB_ERR_CRC_MISMATCH) { + // packet was received, but is malformed + Serial.println(F("CRC error!")); + + } else { + // some other error occurred + Serial.print(F("failed, code ")); + Serial.println(state); + } +} + +void SubGHZ::rec_signal(std::vector *orig_signal) { + if (_modulation == 2) { // LoRa modulation + while (true) { + read_lora_packet(orig_signal); + } + } + if (radio.available()) { + Serial.println("[SX1276] Received packet in direct mode!"); + while (radio.available()) { + // read a byte + byte signal = radio.read(); + orig_signal->push_back(signal); + } + } +} + +void SubGHZ::send_signal(float freq, Modulation modulation, byte *payload, + size_t length) { + set_modulation(modulation.mode); + set_freq_mod(freq, modulation.bandwidth, modulation.deviation); + int state = radio.transmit(payload, length); + if (state == RADIOLIB_ERR_NONE) { + Serial.println(F("Transimt successfully!")); + + } else if (state == RADIOLIB_ERR_PACKET_TOO_LONG) { + // the supplied packet was longer than 256 bytes + Serial.println(F("too long!")); + } + else { + // some other error occurred + Serial.print(F("failed, code ")); + Serial.println(state); + } +}; + +void SubGHZ::set_modulation(int mod) { + int state = RADIOLIB_ERR_NONE; + /* Module was on LoRA*/ + if (_modulation == 2 && mod != 2) { + state = radio.beginFSK(); + error_check("Begin FSK", state); + } + + _modulation = mod; + + if (!mod) + state = radio.setOOK(true); + else if (mod == 1) + state = radio.setOOK(false); + else { + state = radio.begin(); + error_check("Begin LoRa", state); + return; + } + error_check("Set modulation", state); +} \ No newline at end of file diff --git a/lib/SubGHZ/SubGHZ.hpp b/lib/SubGHZ/SubGHZ.hpp new file mode 100644 index 0000000..8b665e6 --- /dev/null +++ b/lib/SubGHZ/SubGHZ.hpp @@ -0,0 +1,59 @@ +#ifndef SUBGHZ_LIBRARY_H +#define SUBGHZ_LIBRARY_H + +#include +#include +#include + +// enum ModulationMode { ASK, FSK }; + +typedef struct Modulation { + int mode; + float deviation; + float bandwidth; +} Modulation; + +typedef struct Signal { + int modulation; + float frequency; + uint8_t *payload; +} Signal; + +typedef struct SignalStrength { + float rssi; +}SignalStrength; + +class SubGHZ { + private: + byte jammer_payload[8] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}; + int _gdo0 = -1; + int _gdo2 = -1; + float _frequency; + float _bw; + float _deviation; + int _modulation; + bool initialized = false; + void error_check(const char *operation, int16_t status_code); + public: + SubGHZ(uint8_t sck, uint8_t miso, uint8_t mosi, uint8_t csn, uint8_t gdo0, + uint8_t gdo2); + ~SubGHZ(); + // Getter functions + float get_frequency() { return _frequency; }; + float get_bw() { return _bw; }; + float get_deviation() { return _deviation; }; + int get_modulation() { return _modulation; }; + void init_receive(); + void stop_receive(); + void set_freq_mod(float freq, float bw, float deviation); + SignalStrength scan_frequency(float freq, float bw = 200.0F, + float deviation = 47.0F); + SignalStrength scan_frequency(); + void rec_signal(std::vector *orig_signal); + void send_signal(float freq, Modulation modulation, byte *payload, size_t length); + /// @brief Set modulation to ASK or FSK + /// @param mod 0 for ASK, 1 for FSK and 2 for LoRA + void set_modulation(int mod); +}; + +#endif \ No newline at end of file diff --git a/lib/UI/gui.cpp b/lib/UI/gui.cpp index 15d5e39..b12d856 100644 --- a/lib/UI/gui.cpp +++ b/lib/UI/gui.cpp @@ -228,7 +228,9 @@ void Gui::set_selected_widget(int pos, bool selected) { else if (nfc_felica_polling_result_page_visible()) nfc_felica_polling_result_page->set_selected(pos, selected); else if (badusb_browser_visible()) - badusb_payload_browser_page->set_selected(pos, selected); + file_browser_page->set_selected(pos, selected); + else if(subghz_page_visible()) + subghz_page->set_selected(pos, selected); } /******************** NFC GUI FUNCTIONS ************************/ @@ -330,15 +332,51 @@ void Gui::nfc_cleanup() { } /******************** BadUSB FUNCTIONS ************************/ -void Gui::init_badusb_browser_gui(std::list *files) { +void Gui::init_file_browser_gui(const char *name, std::list *files, bool _badusb) { grid_visible = false; + if(_badusb) + badusb_visible = true; + else + subghz_browser_visible = true; lower_limit = 1; - position_limit = 2; // TODO: To adjust dynamically + position_limit = files->size() - 1; position_increment = 1; - badusb_payload_browser_page = new BadUSBPayloadBrowserPage(screen); - badusb_payload_browser_page->display(files); + file_browser_page = new FileBrowserPage(screen); + file_browser_page->display(name, files); }; +void Gui::init_subghz_gui(){ + grid_visible = false; + position_limit = 3; + position_increment = 1; + subghz_page = new SubGHZPage(screen); + subghz_page->display(); +}; + +void Gui::init_subghz_frequency_analyzer() { + grid_visible = false; + position_limit = 1; + position_increment = 0; + subghz_frequency_analyzer_page = new SubGHZFrequencyAnalyzerPage(screen); + subghz_frequency_analyzer_page->display(); +} + +void Gui::init_subghz_raw_record_ui() { + grid_visible = false; + position_limit = 1; + position_increment = 0; + subghz_raw_record_page = new SubGHZRAWRecordPage(screen); + subghz_raw_record_page->display(); +} + +void Gui::init_subghz_sender() { + grid_visible = false; + position_limit = 0; + position_increment = 0; + subghz_sender_page = new SubGHZSender(screen); + subghz_sender_page->display(); +} + void Gui::click_element(int pos, void callback()) { if (grid_visible) grid->click(pos, callback); @@ -357,7 +395,7 @@ void Gui::click_element(int pos, void callback()) { else if (nfc_felica_polling_result_page_visible()) nfc_felica_polling_result_page->click(pos, callback); else if (badusb_browser_visible()) - badusb_payload_browser_page->click(pos, callback); + file_browser_page->click(pos, callback); } void Gui::up() { diff --git a/lib/UI/gui.hpp b/lib/UI/gui.hpp index a3e4814..acfe474 100644 --- a/lib/UI/gui.hpp +++ b/lib/UI/gui.hpp @@ -22,7 +22,11 @@ #include "pages/BLE/BLEScanPage.hpp" #include "pages/BLE/BLESniffPage.hpp" #include "pages/BLE/BLESpamPage.hpp" -#include "pages/BadUSB/BadUSBPayloadBrowserPage.hpp" +#include "pages/FileBrowser/FileBrowserPage.hpp" +#include "pages/SubGHZ/SubGHZPage.hpp" +#include "pages/SubGHZ/SubGHZFrequencyAnalyzerPage.hpp" +#include "pages/SubGHZ/SubGHZRAWRecordPage.hpp" +#include "pages/SubGHZ/SubGHZSender.hpp" #include "pages/NFC/FeliCaPages/NFCFelicaPollingResultPage.hpp" #include "pages/NFC/NFCBruteforceTagPage.hpp" #include "pages/NFC/NFCDumpResultPage.hpp" @@ -68,9 +72,17 @@ class Gui { #endif #if defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) RectText *badusb; - BadUSBPayloadBrowserPage *badusb_payload_browser_page = nullptr; + FileBrowserPage *file_browser_page = nullptr; + bool badusb_visible = false; #endif + // SubGHZ RectText *SubGhz; + SubGHZPage *subghz_page = nullptr; + SubGHZFrequencyAnalyzerPage *subghz_frequency_analyzer_page = nullptr; + SubGHZRAWRecordPage *subghz_raw_record_page = nullptr; + SubGHZSender *subghz_sender_page = nullptr; + bool subghz_browser_visible = false; + // SubGhz // NFC RectText *NFC; NFCMainPage *nfc_main_page = nullptr; @@ -301,15 +313,70 @@ class Gui { } /******************** BadUSB FUNCTIONS ************************/ - void init_badusb_browser_gui(std::list *files); + void init_file_browser_gui(const char *name, std::list *files, bool _badusb); bool badusb_browser_visible() { - return badusb_payload_browser_page != nullptr; + return file_browser_page != nullptr && badusb_visible; }; - void destroy_badusb_browser_gui() { - delete badusb_payload_browser_page; - badusb_payload_browser_page = nullptr; + void destroy_file_browser_gui() { + delete file_browser_page; + file_browser_page = nullptr; } + /******************** SubGHZ GUI FUNCTIONS ************************/ + + void init_subghz_gui(); + bool subghz_page_visible() { return subghz_page != nullptr; }; + void init_subghz_frequency_analyzer(); + void destroy_subghz_frequency_analyzer() { + delete subghz_frequency_analyzer_page; + subghz_frequency_analyzer_page = nullptr; + } + void destroy_subghz_gui() { + delete subghz_page; + subghz_page = nullptr; + } + void set_subghz_freqeuncy(float freq) { + subghz_frequency_analyzer_page->set_frequency(freq); + } + void set_subghz_rssi(int rssi) { + subghz_frequency_analyzer_page->set_rssi(rssi); + } + bool subghz_frequency_analyzer_visible() { return subghz_frequency_analyzer_page != nullptr; }; + void init_subghz_raw_record_ui(); + bool subghz_raw_record_ui_visible() { return subghz_raw_record_page != nullptr; }; + void set_subghz_raw_record_freq(float freq) { + subghz_raw_record_page->set_frequency(freq); + } + void set_subghz_raw_record_rssi(float rssi) { + subghz_raw_record_page->set_rssi(rssi); + } + void destroy_subghz_raw_record_ui() { + delete subghz_raw_record_page; + subghz_raw_record_page = nullptr; + } + + bool subghz_file_browser_visible() { return file_browser_page != nullptr && subghz_browser_visible; }; + void init_subghz_sender(); + void set_subghz_sender_freq(float freq) { + subghz_sender_page->set_frequency(freq); + } + void set_subghz_sender_bandwidth(float bandwidth) { + subghz_sender_page->set_bandwidth(bandwidth); + } + void set_subghz_sender_deviation(float deviation) { + subghz_sender_page->set_deviation(deviation); + } + void set_subghz_sender_modulation(int modulation) { + subghz_sender_page->set_modulation(modulation); + } + bool subghz_sender_visible() { return subghz_sender_page != nullptr; }; + void destroy_subghz_sender() { + delete subghz_sender_page; + subghz_sender_page = nullptr; + } + + /******************** SubGHZ GUI FUNCTIONS ************************/ + /******************** NFC GUI FUNCTIONS ************************/ void init_nfc_gui(); bool nfc_page_visible() { return nfc_main_page != nullptr; }; diff --git a/lib/UI/navigation/BadUSB/BadUSBNavigation.cpp b/lib/UI/navigation/BadUSB/BadUSBNavigation.cpp index de7dc4a..46c178b 100644 --- a/lib/UI/navigation/BadUSB/BadUSBNavigation.cpp +++ b/lib/UI/navigation/BadUSB/BadUSBNavigation.cpp @@ -6,6 +6,7 @@ #include "sdcard_helper.hpp" #include "usb_hid/USBHid.hpp" #include "../../../../include/debug.h" +#include "../../i18n/BadUSB/badusb_keys.h" static Gui *_gui; std::list files; @@ -20,7 +21,7 @@ void goto_badusb_gui() { files = list_dir(open("/ducky", "r")); _gui->reset(); _gui->set_current_position(1); - _gui->init_badusb_browser_gui(&files); + _gui->init_file_browser_gui(english_words->at(BADUSB_TITLE_KEY), &files, true); _gui->set_position_limit(files.size() + 1); } @@ -29,13 +30,13 @@ void badusb_selection_handler(int pos) { if (pos == files.size() + 1) { // Means return to main menu hid.end(); _gui->reset(); - _gui->destroy_badusb_browser_gui(); + _gui->destroy_file_browser_gui(); _gui->init_gui(); _gui->set_current_position(0); _gui->set_selected_widget(0, true); return; } - auto selected_file = files.begin(); + std::list::iterator selected_file = files.begin(); std::advance(selected_file, pos - 1); Serial.printf("Selected file: %s\n", selected_file->c_str()); FILE *file = fopen(("/sd/ducky/" + *selected_file).c_str(), "r"); diff --git a/lib/UI/navigation/SubGHZ/SubGHZNavigation.cpp b/lib/UI/navigation/SubGHZ/SubGHZNavigation.cpp new file mode 100644 index 0000000..3dcfa4a --- /dev/null +++ b/lib/UI/navigation/SubGHZ/SubGHZNavigation.cpp @@ -0,0 +1,131 @@ +#include "gui.hpp" +#include "subghz_attacks.hpp" +#include "../../../../include/pins.h" +#include "../navigation.hpp" +#include "fm.hpp" +#include "sdcard_helper.hpp" +#include "posixsd.hpp" +#include "ArduinoJson.h" + +static Gui *gui; +SubGHZ *subghz_module = nullptr; + +void goto_subghz_gui() { + Serial.println("GOTO SUBGHZ"); + gui->reset(); + gui->set_current_position(0); + gui->init_subghz_gui(); +} + +void start_frequency_analyzer() { + gui->reset(); + gui->set_current_position(0); + gui->destroy_subghz_gui(); + gui->init_subghz_frequency_analyzer(); + frequency_analyzer_attack(subghz_module, gui); +} + +void stop_frequency_analyzer() { + stop_subghz_attack(); + gui->destroy_subghz_frequency_analyzer(); + subghz_module->stop_receive(); + init_main_gui(); +} + +void start_raw_record() { + gui->reset(); + gui->set_current_position(0); + gui->destroy_subghz_gui(); + gui->init_subghz_raw_record_ui(); + raw_record_attack(subghz_module, gui); +} + +void make_dump_file() { + Serial.println("Saving file"); + extern std::vector raw_signal; + DynamicJsonDocument doc(110 + (32 * raw_signal.size())); + doc["frequency"] = subghz_module->get_frequency(); + doc["bandwidth"] = subghz_module->get_bw(); + doc["deviation"] = subghz_module->get_deviation(); + doc["data_length"] = raw_signal.size(); + JsonArray data = doc.createNestedArray("data"); + Serial.println("Saving file"); + for (byte b : raw_signal) { + data.add(b); + } + Serial.println("Saving file"); + + File file = open(((String)"/subghz/raw_signals/" + (String)millis() + (String)"_capture.json"), "w"); + Serial.println("Saving file14"); + serializeJsonPretty(doc, file); + Serial.println("Saving file4"); + + file.close(); +} + +void stop_subghz_raw_record() { + stop_subghz_attack(); + gui->destroy_subghz_raw_record_ui(); + init_main_gui(); + make_dump_file(); + subghz_module->stop_receive(); +} + +std::list subghz_files; + +void start_subghz_emulation(int pos) { + gui->destroy_file_browser_gui(); + if(pos == subghz_files.size()) { + init_main_gui(); + return; + } + std::list::iterator selected_file = subghz_files.begin(); + std::advance(selected_file, pos); + Serial.println(selected_file->c_str()); + gui->reset(); + gui->set_current_position(0); + gui->destroy_subghz_gui(); + gui->init_subghz_sender(); + start_subghz_emulation_attack(subghz_module, gui, ("/subghz/raw_signals/" + (String)selected_file->c_str()).c_str()); + gui->destroy_subghz_sender(); + init_main_gui(); +} + +void subghz_sender_file_browser() { + gui->reset(); + gui->set_current_position(0); + gui->destroy_subghz_gui(); + subghz_files = list_dir(open("/subghz/raw_signals", "r"));; + gui->init_file_browser_gui("SubGHZ file browser", &subghz_files, false); +} + +/* Avoid linker error */ +void goto_home_from_subghz() { + gui->destroy_subghz_gui(); + init_main_gui(); +} + +void subghz_submenu_handler(int pos) { + switch (pos) + { + case 0: + start_frequency_analyzer(); + break; + case 1: + start_raw_record(); + break; + case 2: + subghz_sender_file_browser(); + break; + case 3: + goto_home_from_subghz(); + break; + default: + break; + } +} + +void init_subghz_navigation(Gui *_gui) { + gui = _gui; + subghz_module = new SubGHZ(SD_CARD_SCK, SD_CARD_MISO, SD_CARD_MOSI, SX1276_NSS, SX1276_DIO1, SX1276_DIO2); +} \ No newline at end of file diff --git a/lib/UI/navigation/SubGHZ/SubGHZNavigation.hpp b/lib/UI/navigation/SubGHZ/SubGHZNavigation.hpp new file mode 100644 index 0000000..9435a26 --- /dev/null +++ b/lib/UI/navigation/SubGHZ/SubGHZNavigation.hpp @@ -0,0 +1,8 @@ +#include "gui.hpp" + +void goto_subghz_gui(); +void subghz_submenu_handler(int pos); +void init_subghz_navigation(Gui *_gui); +void stop_frequency_analyzer(); +void stop_subghz_raw_record(); +void start_subghz_emulation(int pos); \ No newline at end of file diff --git a/lib/UI/navigation/SubGHZ/example_signal.json b/lib/UI/navigation/SubGHZ/example_signal.json new file mode 100644 index 0000000..90eada5 --- /dev/null +++ b/lib/UI/navigation/SubGHZ/example_signal.json @@ -0,0 +1,7 @@ +{ + "frequency": 433.92, + "bandwidth": 650.0, + "deviation": 47.0, + "data_length": 100, + "data": [10, 100] + } \ No newline at end of file diff --git a/lib/UI/navigation/buttons/btn_routines.cpp b/lib/UI/navigation/buttons/btn_routines.cpp index e2c1414..f1bdba0 100644 --- a/lib/UI/navigation/buttons/btn_routines.cpp +++ b/lib/UI/navigation/buttons/btn_routines.cpp @@ -22,15 +22,15 @@ static Buttons btn_pressed = NULL_BTN; /* ISR routines */ -void handle_up_button() { btn_pressed = UP_BTN; } +void IRAM_ATTR handle_up_button() { btn_pressed = UP_BTN; } -void handle_down_button() { btn_pressed = DOWN_BTN; } +void IRAM_ATTR handle_down_button() { btn_pressed = DOWN_BTN; } -void handle_left_button() { btn_pressed = LEFT_BTN; } +void IRAM_ATTR handle_left_button() { btn_pressed = LEFT_BTN; } -void handle_right_button() { btn_pressed = RIGHT_BTN; } +void IRAM_ATTR handle_right_button() { btn_pressed = RIGHT_BTN; } -void handle_ok_button() { btn_pressed = OK_BTN; } +void IRAM_ATTR handle_ok_button() { btn_pressed = OK_BTN; } Buttons get_btn_pressed() { return btn_pressed; } diff --git a/lib/UI/navigation/navigation.cpp b/lib/UI/navigation/navigation.cpp index f9e6074..81c2e8f 100644 --- a/lib/UI/navigation/navigation.cpp +++ b/lib/UI/navigation/navigation.cpp @@ -17,6 +17,7 @@ #include "BLE/ble_navigation.hpp" #include "BadUSB/BadUSBNavigation.hpp" +#include "SubGHZ/SubGHZNavigation.hpp" #include "NFC/NFCNavigation.hpp" #include "buttons/btn_routines.hpp" #include "gui.hpp" @@ -27,6 +28,7 @@ #define WIFI_MODULE_POS 0 #define BLE_MODULE_POS 1 #define BADUSB_MODULE_POS 2 +#define SUBGHZ_MODULE_POS 3 #define NFC_MODULE_POS 4 #define NETWORK_ATTACKS_MODULE_POS 6 @@ -57,6 +59,10 @@ void main_menu_handler(int pos) { init_badusb_navigation(gui); gui->ok(goto_badusb_gui); break; + case SUBGHZ_MODULE_POS: + init_subghz_navigation(gui); + gui->ok(goto_subghz_gui); + break; case NFC_MODULE_POS: init_nfc_navigation(gui); gui->ok(goto_nfc_gui); @@ -126,6 +132,36 @@ Serial.println("WiFI4"); return; } + if(gui->subghz_page_visible()) { + Serial.println("SUBGHZ PAGE"); + subghz_submenu_handler(pos); + return; + } + + if(gui->subghz_frequency_analyzer_visible()) { + Serial.println("PAGE ANALZYER"); + stop_frequency_analyzer(); + return; + } + + if(gui->subghz_raw_record_ui_visible()) { + Serial.println("PAGE RAW RECORD"); + stop_subghz_raw_record(); + return; + } + + if(gui->subghz_sender_visible()) { + // SubGHZ sender haven't any button + return; + } + + if(gui->subghz_file_browser_visible()) { + Serial.println("PAGE FILE BROWSER"); + start_subghz_emulation(pos); + // stop_subghz_file_browser(); + return; + } + if (gui->network_attacks_submenu_visible()) { network_attacks_submenu_handler(pos); return; diff --git a/lib/UI/pages/BadUSB/BadUSBPayloadBrowserPage.cpp b/lib/UI/pages/FileBrowser/FileBrowserPage.cpp similarity index 81% rename from lib/UI/pages/BadUSB/BadUSBPayloadBrowserPage.cpp rename to lib/UI/pages/FileBrowser/FileBrowserPage.cpp index 067049b..3ed6d40 100644 --- a/lib/UI/pages/BadUSB/BadUSBPayloadBrowserPage.cpp +++ b/lib/UI/pages/FileBrowser/FileBrowserPage.cpp @@ -16,21 +16,21 @@ * along with this program. If not, see . */ -#include "BadUSBPayloadBrowserPage.hpp" +#include "FileBrowserPage.hpp" #include "../../../../include/icons/file/file.h" #include "../../i18n.hpp" #include "../../i18n/BadUSB/badusb_keys.h" #include "Bitmap.hpp" -BadUSBPayloadBrowserPage::BadUSBPayloadBrowserPage(GFXForms *_screen) { +FileBrowserPage::FileBrowserPage(GFXForms *_screen) { screen = _screen; } -BadUSBPayloadBrowserPage::~BadUSBPayloadBrowserPage() {} +FileBrowserPage::~FileBrowserPage() {} -void BadUSBPayloadBrowserPage::display() { +void FileBrowserPage::display() { badusb_grid = new Grid(screen, 2, 1); - title = new Text(screen, ST77XX_WHITE, "Bad USB Payload Browser"); + title = new Text(screen, ST77XX_WHITE, "File Browser"); Bitmap bitmap = Bitmap(screen, (uint8_t *)file_icon, 16, 16, 100, 100); List file = List(screen, "example", 2, ST77XX_WHITE, 20, &bitmap, ST77XX_BLACK); @@ -40,9 +40,9 @@ void BadUSBPayloadBrowserPage::display() { badusb_grid->display(); } -void BadUSBPayloadBrowserPage::display(std::list *files) { +void FileBrowserPage::display(const char *text, std::list *files) { badusb_grid = new Grid(screen, 2, 1); - title = new Text(screen, ST77XX_WHITE, english_words->at(BADUSB_TITLE_KEY)); + title = new Text(screen, ST77XX_WHITE, text); badusb_grid->add(title); Bitmap bitmap = Bitmap(screen, (uint8_t *)file_icon, 16, 16, 100, 100); List *file_list = nullptr; // In for loop, variable got deleted diff --git a/lib/UI/pages/BadUSB/BadUSBPayloadBrowserPage.hpp b/lib/UI/pages/FileBrowser/FileBrowserPage.hpp similarity index 82% rename from lib/UI/pages/BadUSB/BadUSBPayloadBrowserPage.hpp rename to lib/UI/pages/FileBrowser/FileBrowserPage.hpp index 2f31fcf..72e5622 100644 --- a/lib/UI/pages/BadUSB/BadUSBPayloadBrowserPage.hpp +++ b/lib/UI/pages/FileBrowser/FileBrowserPage.hpp @@ -22,20 +22,20 @@ #include "List.hpp" #include "Text.hpp" -#ifndef BADUSB_PAYLOAD_BROWSER_PAGE_H -#define BADUSB_PAYLOAD_BROWSER_PAGE_H +#ifndef FILE_BROWSER_PAGE_H +#define FILE_BROWSER_PAGE_H -class BadUSBPayloadBrowserPage : public Page { +class FileBrowserPage : public Page { private: Text *title; List *go_back; Grid *badusb_grid; public: - BadUSBPayloadBrowserPage(GFXForms *_screen); - ~BadUSBPayloadBrowserPage(); + FileBrowserPage(GFXForms *_screen); + ~FileBrowserPage(); void display(); - void display(std::list *files); + void display(const char *text, std::list *files); void click(int pos, void callback()) { badusb_grid->click(pos, callback); }; void set_selected(int pos, bool status) { badusb_grid->set_selected(pos, status); diff --git a/lib/UI/pages/SubGHZ/SubGHZFrequencyAnalyzerPage.cpp b/lib/UI/pages/SubGHZ/SubGHZFrequencyAnalyzerPage.cpp new file mode 100644 index 0000000..9d1fa8d --- /dev/null +++ b/lib/UI/pages/SubGHZ/SubGHZFrequencyAnalyzerPage.cpp @@ -0,0 +1,37 @@ +/* + * This file is part of the Capibara zero (https://github.com/CapibaraZero/fw or + * https://capibarazero.github.io/). Copyright (c) 2024 Andrea Canale. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "SubGHZFrequencyAnalyzerPage.hpp" + +#include "../../i18n.hpp" + +SubGHZFrequencyAnalyzerPage::SubGHZFrequencyAnalyzerPage(GFXForms *_screen) { screen = _screen; } + +SubGHZFrequencyAnalyzerPage::~SubGHZFrequencyAnalyzerPage() {} + +void SubGHZFrequencyAnalyzerPage::display() { + SubGHZ_grid = new Grid(screen, 3, 1); + SubGHZ_grid->set_y_spacing(30); + current_frequency = new Text(screen, ST77XX_WHITE, "Frequency: 0 MHz"); + current_rssi = new Text(screen, ST77XX_WHITE, "RSSI: 0 dBm"); + stop = new List(screen, "Stop", 2, ST77XX_WHITE, 20, ST77XX_BLUE); + SubGHZ_grid->add(current_frequency); + SubGHZ_grid->add(current_rssi); + SubGHZ_grid->add(stop); + // SubGHZ_grid->set_selected(0, true); + SubGHZ_grid->display(); +} \ No newline at end of file diff --git a/lib/UI/pages/SubGHZ/SubGHZFrequencyAnalyzerPage.hpp b/lib/UI/pages/SubGHZ/SubGHZFrequencyAnalyzerPage.hpp new file mode 100644 index 0000000..fa3af68 --- /dev/null +++ b/lib/UI/pages/SubGHZ/SubGHZFrequencyAnalyzerPage.hpp @@ -0,0 +1,52 @@ +/* + * This file is part of the Capibara zero (https://github.com/CapibaraZero/fw or + * https://capibarazero.github.io/). Copyright (c) 2024 Andrea Canale. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../Page.hpp" +#include "Grid.hpp" +#include "List.hpp" + +#ifndef SUBGHZ_FREQUENCY_ANALYZER_PAGE_H +#define SUBGHZ_FREQUENCY_ANALYZER_PAGE_H + +class SubGHZFrequencyAnalyzerPage : public Page { + private: + Text *current_frequency; + Text *current_rssi; + List *stop; + Grid *SubGHZ_grid; + + public: + SubGHZFrequencyAnalyzerPage(GFXForms *_screen); + ~SubGHZFrequencyAnalyzerPage(); + void display(); + void click(int pos, void callback()) { SubGHZ_grid->click(pos, callback); }; + void set_selected(int pos, bool status) { + SubGHZ_grid->set_selected(pos, status); + }; + void set_rssi(int rssi) { + current_rssi->set_text("RSSI: " + String(rssi)); + } + void set_frequency(float frequency) { + current_frequency->set_text("Frequency: " + String(frequency) + "MHz"); + } + void up() {}; + void down() {}; + void left() {}; + void right() {}; +}; + +#endif \ No newline at end of file diff --git a/lib/UI/pages/SubGHZ/SubGHZPage.cpp b/lib/UI/pages/SubGHZ/SubGHZPage.cpp new file mode 100644 index 0000000..1892d0a --- /dev/null +++ b/lib/UI/pages/SubGHZ/SubGHZPage.cpp @@ -0,0 +1,43 @@ +/* + * This file is part of the Capibara zero (https://github.com/CapibaraZero/fw or + * https://capibarazero.github.io/). Copyright (c) 2024 Andrea Canale. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "SubGHZPage.hpp" + +#include "../../i18n.hpp" + +SubGHZPage::SubGHZPage(GFXForms *_screen) { screen = _screen; } + +SubGHZPage::~SubGHZPage() {} + +void SubGHZPage::display() { + SubGHZ_grid = new Grid(screen, 4, 1); + SubGHZ_freq_analyzer = new List(screen, "Frequency analyzer", 2, + ST77XX_WHITE, 20, ST77XX_BLACK); + SubGHZ_sniff = + new List(screen, "Record RAW", 2, ST77XX_WHITE, 20, ST77XX_BLACK); + SubGHZ_sender = + new List(screen, "Sender", 2, ST77XX_WHITE, 20, ST77XX_BLACK); + SubGHZ_jammer = + new List(screen, "Jammer", 2, ST77XX_WHITE, 20, ST77XX_BLACK); + go_back = new List(screen, "Go back", 2, ST77XX_WHITE, 20, ST77XX_BLACK); + SubGHZ_grid->add(SubGHZ_freq_analyzer); + SubGHZ_grid->add(SubGHZ_sniff); + SubGHZ_grid->add(SubGHZ_sender); + SubGHZ_grid->add(go_back); + SubGHZ_grid->set_selected(0, true); + SubGHZ_grid->display(); +} \ No newline at end of file diff --git a/lib/UI/pages/SubGHZ/SubGHZPage.hpp b/lib/UI/pages/SubGHZ/SubGHZPage.hpp new file mode 100644 index 0000000..d0e69ea --- /dev/null +++ b/lib/UI/pages/SubGHZ/SubGHZPage.hpp @@ -0,0 +1,48 @@ +/* + * This file is part of the Capibara zero (https://github.com/CapibaraZero/fw or + * https://capibarazero.github.io/). Copyright (c) 2024 Andrea Canale. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../Page.hpp" +#include "Grid.hpp" +#include "List.hpp" + +#ifndef SUBGHZ_PAGE_H +#define SUBGHZ_PAGE_H + +class SubGHZPage : public Page { + private: + List *SubGHZ_freq_analyzer; + List *SubGHZ_sniff; + List *SubGHZ_sender; + List *SubGHZ_jammer; + List *go_back; + Grid *SubGHZ_grid; + + public: + SubGHZPage(GFXForms *_screen); + ~SubGHZPage(); + void display(); + void click(int pos, void callback()) { SubGHZ_grid->click(pos, callback); }; + void set_selected(int pos, bool status) { + SubGHZ_grid->set_selected(pos, status); + }; + void up() {}; + void down() {}; + void left() {}; + void right() {}; +}; + +#endif \ No newline at end of file diff --git a/lib/UI/pages/SubGHZ/SubGHZRAWRecordPage.cpp b/lib/UI/pages/SubGHZ/SubGHZRAWRecordPage.cpp new file mode 100644 index 0000000..e3f85db --- /dev/null +++ b/lib/UI/pages/SubGHZ/SubGHZRAWRecordPage.cpp @@ -0,0 +1,40 @@ +/* + * This file is part of the Capibara zero (https://github.com/CapibaraZero/fw or + * https://capibarazero.github.io/). Copyright (c) 2024 Andrea Canale. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "SubGHZRAWRecordPage.hpp" + +#include "../../i18n.hpp" +// #include "../../i18n/SubGHZ/SubGHZ_submenu_keys.h" + +SubGHZRAWRecordPage::SubGHZRAWRecordPage(GFXForms *_screen) { screen = _screen; } + +SubGHZRAWRecordPage::~SubGHZRAWRecordPage() {} + +void SubGHZRAWRecordPage::display() { + SubGHZ_grid = new Grid(screen, 3, 1); + SubGHZ_grid->set_y_spacing(30); + current_frequency = new Text(screen, ST77XX_WHITE, "Frequency: 0 MHz"); + current_rssi = new Text(screen, ST77XX_WHITE, "RSSI: 0 dBm"); + current_lqi = new Text(screen, ST77XX_WHITE, "LQI: 0"); + stop = new List(screen, "Stop", 2, ST77XX_WHITE, 20, ST77XX_BLUE); + SubGHZ_grid->add(current_frequency); + SubGHZ_grid->add(current_rssi); + SubGHZ_grid->add(current_lqi); + SubGHZ_grid->add(stop); + // SubGHZ_grid->set_selected(0, true); + SubGHZ_grid->display(); +} \ No newline at end of file diff --git a/lib/UI/pages/SubGHZ/SubGHZRAWRecordPage.hpp b/lib/UI/pages/SubGHZ/SubGHZRAWRecordPage.hpp new file mode 100644 index 0000000..5709f60 --- /dev/null +++ b/lib/UI/pages/SubGHZ/SubGHZRAWRecordPage.hpp @@ -0,0 +1,53 @@ +/* + * This file is part of the Capibara zero (https://github.com/CapibaraZero/fw or + * https://capibarazero.github.io/). Copyright (c) 2024 Andrea Canale. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../Page.hpp" +#include "Grid.hpp" +#include "List.hpp" + +#ifndef SUBGHZ_RAW_RECORD_PAGE_H +#define SUBGHZ_RAW_RECORD_PAGE_H + +class SubGHZRAWRecordPage : public Page { + private: + Text *current_frequency; + Text *current_rssi; + Text *current_lqi; + Text *received_packets; + List *stop; + Grid *SubGHZ_grid; + + public: + SubGHZRAWRecordPage(GFXForms *_screen); + ~SubGHZRAWRecordPage(); + void display(); + void click(int pos, void callback()) { SubGHZ_grid->click(pos, callback); }; + void set_selected(int pos, bool status) { + SubGHZ_grid->set_selected(pos, status); + }; + void set_rssi(int rssi) { current_rssi->set_text("RSSI: " + String(rssi)); } + void set_lqi(int lqi) { current_lqi->set_text("LQI: " + String(lqi)); } + void set_frequency(int frequency) { + current_frequency->set_text("Frequency: " + String(frequency) + "MHz"); + } + void up() {}; + void down() {}; + void left() {}; + void right() {}; +}; + +#endif \ No newline at end of file diff --git a/lib/UI/pages/SubGHZ/SubGHZSender.cpp b/lib/UI/pages/SubGHZ/SubGHZSender.cpp new file mode 100644 index 0000000..8a03943 --- /dev/null +++ b/lib/UI/pages/SubGHZ/SubGHZSender.cpp @@ -0,0 +1,40 @@ + +/* + * This file is part of the Capibara zero (https://github.com/CapibaraZero/fw or + * https://capibarazero.github.io/). Copyright (c) 2024 Andrea Canale. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "SubGHZSender.hpp" + +#include "../../i18n.hpp" +// #include "../../i18n/SubGHZ/SubGHZ_submenu_keys.h" + +SubGHZSender::SubGHZSender(GFXForms *_screen) { screen = _screen; } + +SubGHZSender::~SubGHZSender() {} + +void SubGHZSender::display() { + SubGHZ_grid = new Grid(screen, 4, 1); + SubGHZ_grid->set_y_spacing(30); + current_frequency = new Text(screen, ST77XX_WHITE, "Frequency: 0 MHz"); + current_modulation = new Text(screen, ST77XX_WHITE, "Modulation: "); + current_bw = new Text(screen, ST77XX_WHITE, "Bandwidth: "); + current_deviation = new Text(screen, ST77XX_WHITE, "Deviation: "); + SubGHZ_grid->add(current_frequency); + SubGHZ_grid->add(current_modulation); + SubGHZ_grid->add(current_bw); + SubGHZ_grid->add(current_deviation); + SubGHZ_grid->display(); +} \ No newline at end of file diff --git a/lib/UI/pages/SubGHZ/SubGHZSender.hpp b/lib/UI/pages/SubGHZ/SubGHZSender.hpp new file mode 100644 index 0000000..02f3b73 --- /dev/null +++ b/lib/UI/pages/SubGHZ/SubGHZSender.hpp @@ -0,0 +1,68 @@ + +/* + * This file is part of the Capibara zero (https://github.com/CapibaraZero/fw or + * https://capibarazero.github.io/). Copyright (c) 2024 Andrea Canale. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "../Page.hpp" +#include "Grid.hpp" +#include "List.hpp" + +#ifndef SUBGHZ_SENDER_PAGE_H +#define SUBGHZ_SENDER_PAGE_H + +class SubGHZSender : public Page { + private: + Text *current_frequency; + Text *current_modulation; + Text *current_bw; + Text *current_deviation; + Text *bytes; + Grid *SubGHZ_grid; + + public: + SubGHZSender(GFXForms *_screen); + ~SubGHZSender(); + void display(); + void click(int pos, void callback()) { SubGHZ_grid->click(pos, callback); }; + void set_selected(int pos, bool status) { + SubGHZ_grid->set_selected(pos, status); + }; + void set_frequency(int frequency) { + current_frequency->set_text("Frequency: " + String(frequency) + "MHz"); + } + void set_modulation(int modulation) { + if(modulation == 0) + current_modulation->set_text("Modulation: ASK"); + else if(modulation == 1) + current_modulation->set_text("Modulation: FSK"); + else if(modulation == 2) + current_modulation->set_text("Modulation: LoRA"); + else + current_modulation->set_text("Modulation: UNKNOWN"); + } + void set_bandwidth(int bandwidth) { + current_bw->set_text("Bandwidth: " + String(bandwidth) + "KHz"); + } + void set_deviation(int deviation) { + current_deviation->set_text("Deviation: " + String(deviation) + "KHz"); + } + void up() {}; + void down() {}; + void left() {}; + void right() {}; +}; + +#endif \ No newline at end of file diff --git a/lib/subghz_attacks/config_parser.cpp b/lib/subghz_attacks/config_parser.cpp new file mode 100644 index 0000000..877db78 --- /dev/null +++ b/lib/subghz_attacks/config_parser.cpp @@ -0,0 +1,154 @@ +#include "ArduinoJson.h" +#include "posixsd.hpp" +#include "config_struct.h" + +#define SUBGHZ_CONFIG_FILE "/subghz/config.json" + +#define FREQ_CHECK(x) \ + (x >= 300 && x <= 348) || (x >= 387 && x <= 464) || (x >= 779 && x <= 928) + +#define DEFAULT_FREQUENCY 433.92 +#define DEFAULT_BANDWIDTH 650.0 +#define DEFAULT_DEVIATION 47.60 +#define DEFAULT_MODULATION 0 // ASK +#define DEFAULT_RSSI_THRESHOLD -90 + +static void param_check(float value, const char *name, float initial_range, float end_range, float default_value, float *var) { + if(value >= initial_range && value <= end_range){ + *var = value; + }else { + Serial.printf("Invalid value for %s. Using default value %f\n", name, default_value); + } +} + +#define CONFIG_SIZE 300 + +bool parse_lora_freq_analyzer() { + File subghz_config_file = SD.open("/subghz/config.json", "r"); + Serial.println("Loading Subghz configuration2"); + + if (!subghz_config_file.available()) { + Serial.println("Error: Subghz configuration file not exists"); + return false; + } + StaticJsonDocument doc; + DeserializationError error = deserializeJson(doc, subghz_config_file); + if (error) { + Serial.printf("Error: %s", error.c_str()); + Serial.println( + "Error during deserialization of configuration. Using default " + "configuration"); + return false; + } + JsonObject freq_analyzer_config = doc["frequency_analyzer"]; + return freq_analyzer_config["lora"]; +} + +SubGHZRAWRecorderConfig parse_raw_record_config() { + SubGHZRAWRecorderConfig params; + params.freq = DEFAULT_FREQUENCY; + params.bw = DEFAULT_BANDWIDTH; + params.deviation = DEFAULT_DEVIATION; + params.modulation = DEFAULT_MODULATION; + params.rssi_threshold = -80; + + File subghz_config_file = SD.open("/subghz/config.json", "r"); + Serial.println("Loading Subghz configuration2"); + + if (!subghz_config_file.available()) { + Serial.println("Error: Subghz configuration file not exists"); + return params; + } + StaticJsonDocument doc; + DeserializationError error = deserializeJson(doc, subghz_config_file); + if (error) { + Serial.printf("Error: %s", error.c_str()); + Serial.println( + "Error during deserialization of configuration. Using default " + "configuration"); + return params; + } + JsonObject raw_record_config = doc["raw_record"]; + float raw_record_config_frequency = raw_record_config["frequency"]; + float raw_record_config_bandwidth = raw_record_config["bandwidth"]; + float raw_record_config_deviation = raw_record_config["deviation"]; + int raw_record_config_modulation = raw_record_config["modulation"]; + float raw_record_config_rssi_threshold = raw_record_config["rssi_threshold"]; + + Serial.printf("Frequency: %f\n", raw_record_config_frequency); + Serial.printf("Bandwidth: %f\n", raw_record_config_bandwidth); + Serial.printf("Deviation: %f\n", raw_record_config_deviation); + Serial.printf("Modulation: %d\n", raw_record_config_modulation); + Serial.printf("RSSI threshold: %f\n", raw_record_config_rssi_threshold); + + if(raw_record_config["frequency"].isNull()){ + Serial.printf("Frequency is null. Using default frequency: %f\n", DEFAULT_FREQUENCY); + }else{ + if (FREQ_CHECK(raw_record_config["frequency"])) + params.freq = raw_record_config_frequency; + else + Serial.printf("Invalid frequency value %f. Using %f MHz", + raw_record_config["frequency"], DEFAULT_FREQUENCY); + } + + if(raw_record_config["bandwidth"].isNull()){ + Serial.printf("Bandwidth is null. Using default bandwidth: %f\n", DEFAULT_BANDWIDTH); + }else{ + param_check(raw_record_config_bandwidth, "Bandwidth", 58.03, 812.50, DEFAULT_BANDWIDTH, ¶ms.bw); + } + + if(raw_record_config["deviation"].isNull()){ + Serial.printf("Deviation is null. Using default deviation: %f\n", DEFAULT_DEVIATION); + }else{ + param_check(raw_record_config_deviation, "Deviation", 1.58, 380.85, DEFAULT_DEVIATION, ¶ms.deviation); + } + + if(raw_record_config["modulation"].isNull()){ + Serial.printf("Modulation is null. Using default modulation: %d\n", DEFAULT_MODULATION); + } else { + param_check(raw_record_config_modulation, "Modulation", 0, 4, DEFAULT_MODULATION, (float *)¶ms.modulation); + } + + if(raw_record_config["rssi_threshold"].isNull()) + Serial.printf("RSSI threshold is null. Using default value %f\n", DEFAULT_RSSI_THRESHOLD); + else { + if(raw_record_config["rssi_threshold"] > 0) + Serial.printf("RSSI threshold can't be positive. Using default value %f\n", DEFAULT_RSSI_THRESHOLD); + else + params.rssi_threshold = raw_record_config["rssi_threshold"]; + } + + Serial.printf("Frequency: %f\n", params.freq); + Serial.printf("Bandwidth: %f\n", params.bw); + Serial.printf("Deviation: %f\n", params.deviation); + Serial.printf("Modulation: %d\n", params.modulation); + Serial.printf("RSSI Threshold: %f\n", params.rssi_threshold); + + return params; +} + +SubGHZCapture parse_json_subghz_capture(std::string path) { + File file = open(path.c_str(), "r"); + DynamicJsonDocument doc(file.size() + 90); + SubGHZCapture capture; + DeserializationError error = deserializeJson(doc, file); + if (error) { + Serial.print("deserializeJson() failed: "); + Serial.println(error.c_str()); + return capture; + } + file.close(); + capture = { + .freq = doc["frequency"], + .bw = doc["bandwidth"], + .deviation = doc["deviation"], + .modulation = doc["modulation"], + .len = doc["data_length"] + }; + capture.data = new uint8_t[capture.len]; + // TODO: Try to do in a more efficient way + for (int i = 0; i < capture.len; i++) { + capture.data[i] = doc["data"][i]; + } + return capture; +} \ No newline at end of file diff --git a/lib/subghz_attacks/config_parser.hpp b/lib/subghz_attacks/config_parser.hpp new file mode 100644 index 0000000..b3a57be --- /dev/null +++ b/lib/subghz_attacks/config_parser.hpp @@ -0,0 +1,6 @@ +#include "subghz_tasks_type.h" +#include "config_struct.h" + +bool parse_lora_freq_analyzer(); +SubGHZRAWRecorderConfig parse_raw_record_config(); +SubGHZCapture parse_json_subghz_capture(std::string path); \ No newline at end of file diff --git a/lib/subghz_attacks/config_struct.h b/lib/subghz_attacks/config_struct.h new file mode 100644 index 0000000..9c417e2 --- /dev/null +++ b/lib/subghz_attacks/config_struct.h @@ -0,0 +1,23 @@ +#ifndef SUBGHZ_CONFIG_STRUCT_H +#define SUBGHZ_CONFIG_STRUCT_H + +#include "SubGHZ.hpp" + +typedef struct SubGHZRAWRecorderConfig { + float freq; + float bw; + float deviation; + int modulation; + float rssi_threshold; +} SubGHZRAWRecorderConfig; + +typedef struct { + float freq; + float bw; + float deviation; + int modulation; + size_t len; + uint8_t *data; +} SubGHZCapture; + +#endif \ No newline at end of file diff --git a/lib/subghz_attacks/example_config.json b/lib/subghz_attacks/example_config.json new file mode 100644 index 0000000..98c4ac2 --- /dev/null +++ b/lib/subghz_attacks/example_config.json @@ -0,0 +1,12 @@ +{ + "frequency_analyzer": { + "lora": false + }, + "raw_record": { + "frequency": 433.92, + "bandwidth": 350.50, + "deviation": 47.60, + "modulation": 0, + "rssi_threshold": -90 + } +} diff --git a/lib/subghz_attacks/subghz_attacks.cpp b/lib/subghz_attacks/subghz_attacks.cpp new file mode 100644 index 0000000..cf87616 --- /dev/null +++ b/lib/subghz_attacks/subghz_attacks.cpp @@ -0,0 +1,59 @@ +#include "config_parser.hpp" +#include "fm.hpp" +#include "posixsd.hpp" +#include "subghz_tasks.hpp" + +TaskHandle_t subghz_task_handle = NULL; +static SubGHZTaskParameters *params = NULL; + +void frequency_analyzer_attack(SubGHZ *subghz, Gui *gui) { + params = (SubGHZTaskParameters *)malloc(sizeof(SubGHZTaskParameters)); + params->subghz = subghz; + params->gui = gui; + if(parse_lora_freq_analyzer()) + subghz->set_modulation(2); + else + subghz->init_receive(); + xTaskCreate(frequency_analyzer, "subghz_frequency_analyzer", 8192, params, + 5, &subghz_task_handle); +} + +void stop_subghz_attack() { + vTaskDelete(subghz_task_handle); + subghz_task_handle = NULL; + free(params); +} + +void raw_record_attack(SubGHZ *subghz, Gui *gui) { + Serial.println("raw_record_attack"); + params = (SubGHZTaskParameters *)malloc(sizeof(SubGHZTaskParameters)); + SubGHZRAWRecorderConfig config = parse_raw_record_config(); + params->subghz = subghz; + params->gui = gui; + params->rssi_threshold = config.rssi_threshold; + subghz->set_modulation(config.modulation); + subghz->set_freq_mod(config.freq, config.bw, config.deviation); + subghz->init_receive(); + gui->set_subghz_raw_record_freq(config.freq); + xTaskCreate(raw_record_task, "subghz_raw_record_task", 8192, params, 5, + &subghz_task_handle); +} + +void start_subghz_emulation_attack(SubGHZ *subghz, Gui *gui, + std::string capture_path) { + Serial.println("start_emulation_attack"); + params = (SubGHZTaskParameters *)malloc(sizeof(SubGHZTaskParameters)); + params->subghz = subghz; + params->gui = gui; + SubGHZCapture signal = parse_json_subghz_capture(capture_path); + gui->set_subghz_sender_freq(signal.freq); + gui->set_subghz_sender_deviation(signal.deviation); + gui->set_subghz_sender_bandwidth(signal.bw); + gui->set_subghz_sender_modulation(signal.modulation); + Modulation signal_params = { + .mode = signal.modulation, + .deviation = signal.deviation, + .bandwidth = signal.bw, + }; + subghz->send_signal(signal.freq, signal_params, signal.data, signal.len); +} \ No newline at end of file diff --git a/lib/subghz_attacks/subghz_attacks.hpp b/lib/subghz_attacks/subghz_attacks.hpp new file mode 100644 index 0000000..c9791c7 --- /dev/null +++ b/lib/subghz_attacks/subghz_attacks.hpp @@ -0,0 +1,8 @@ +#include "SubGHZ.hpp" +#include "gui.hpp" + +void frequency_analyzer_attack(SubGHZ *subghz, Gui *gui); +void stop_subghz_attack(); +void raw_record_attack(SubGHZ *subghz, Gui *gui); +void stop_raw_record_attack(SubGHZ *subghz); +void start_subghz_emulation_attack(SubGHZ *subghz, Gui *gui, std::string capture_path); \ No newline at end of file diff --git a/lib/subghz_attacks/subghz_tasks.cpp b/lib/subghz_attacks/subghz_tasks.cpp new file mode 100644 index 0000000..1fbc6bf --- /dev/null +++ b/lib/subghz_attacks/subghz_tasks.cpp @@ -0,0 +1,33 @@ +#include "SubGHZ.hpp" +#include "subghz_tasks_type.h" +#include "fm.hpp" +#include + +#define TIME_BETWEEN_SCAN 400 + +void frequency_analyzer(void *pv) { + SubGHZTaskParameters *params = (SubGHZTaskParameters *)pv; + while (true) { + for (size_t freq = 139.0; freq < 1020.0; freq++) + { + SignalStrength result = params->subghz->scan_frequency(freq); + if (result.rssi > -74) { + params->gui->set_subghz_freqeuncy(freq); + params->gui->set_subghz_rssi(result.rssi); + } + } + } +} + +std::vector raw_signal; + +void raw_record_task(void *pv) { + SubGHZTaskParameters *params = (SubGHZTaskParameters *)pv; + Serial.println(params->rssi_threshold); + while (true) + { + if(params->subghz->scan_frequency().rssi >= params->rssi_threshold) { + params->subghz->rec_signal(&raw_signal); + } + } +} \ No newline at end of file diff --git a/lib/subghz_attacks/subghz_tasks.hpp b/lib/subghz_attacks/subghz_tasks.hpp new file mode 100644 index 0000000..8cf5eb4 --- /dev/null +++ b/lib/subghz_attacks/subghz_tasks.hpp @@ -0,0 +1,4 @@ +void frequency_analyzer(void *pv); +void frequencies_analyzer(void *pv); +void well_known_frequencies_analyzer(void *pv); +void raw_record_task(void *pv); diff --git a/lib/subghz_attacks/subghz_tasks_type.h b/lib/subghz_attacks/subghz_tasks_type.h new file mode 100644 index 0000000..841eb5a --- /dev/null +++ b/lib/subghz_attacks/subghz_tasks_type.h @@ -0,0 +1,12 @@ +#include "SubGHZ.hpp" +#include "GFXForms.hpp" // Fix building errors +#include "gui.hpp" +#include "network_attacks.hpp" +#include "wifi_attack.hpp" +#include "config_struct.h" + +typedef struct SubGHZTaskParameters { + SubGHZ *subghz; + Gui *gui; + float rssi_threshold; +}SubGHZTaskParameters; \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index 737517c..06b8433 100755 --- a/platformio.ini +++ b/platformio.ini @@ -34,6 +34,7 @@ lib_deps_external = https://github.com/spacehuhn/ArduinoPcap.git bblanchon /ArduinoJson@^6.21.4 esphome/AsyncTCP-esphome@^2.0.0 + https://github.com/andreock/RadioLib.git build_flags = -DCONFIG_USE_LOGIN_CALLBACK=1 -DUSE_NIMBLE=true -DNO_SERIAL_PRINT_BLESNIFFER=true @@ -41,7 +42,6 @@ monitor_speed = 115200 monitor_rts = 0 monitor_dtr = 0 monitor_raw = yes - [env:esp32-s3-devkitc-1] platform = espressif32 framework = arduino diff --git a/src/main.cpp b/src/main.cpp index 7d54048..9b08915 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -40,7 +40,7 @@ static void init_sd() { SPI.begin(SD_CARD_SCK, SD_CARD_MISO, SD_CARD_MOSI, SD_CARD_CS); if (!init_sdcard(SD_CARD_CS)) { - Serial.println("init_sdcard failed"); + LOG_ERROR("init_sdcard failed"); }; } @@ -53,20 +53,22 @@ Gui *main_gui; Adafruit_ST7789 *display; GFXForms *screen; + void setup() { #ifdef ARDUINO_NANO_ESP32 Serial.begin(115200); Serial.println("Test"); + delay(2000); #else Serial0.begin(115200); #endif init_sd(); init_english_dict(); - display = new Adafruit_ST7789(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST); + + display = new Adafruit_ST7789(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, -1); screen = new GFXForms(DISPLAY_WIDTH, DISPLAY_HEIGHT, display); screen->set_rotation(1); screen->set_background_color(HOME_BACKGROUND_COLOR); - main_gui = new Gui(screen); main_gui->init_gui(); init_navigation_btn(UP_BTN_PIN, handle_up_button); @@ -81,6 +83,6 @@ void setup() { } void loop() { - Serial.println("Loop"); // Avoid FreeRTOS watchdog trigger + LOG_INFO("Loop\n"); // Avoid FreeRTOS watchdog trigger delay(1000); }