From 9c2b15e140f180d1eeaac7d05d706dc0312ab16f Mon Sep 17 00:00:00 2001 From: Spacehuhn Date: Sun, 3 Jul 2022 18:41:25 +0200 Subject: [PATCH] Support for IMPORT function --- USBNova.ino | 124 +++++++++++++++++++++------------- src/duckparser/duckparser.cpp | 30 ++++++-- src/duckparser/duckparser.h | 6 ++ src/msc/msc.cpp | 77 ++++++++++++++++++++- src/msc/msc.h | 3 +- 5 files changed, 183 insertions(+), 57 deletions(-) diff --git a/USBNova.ino b/USBNova.ino index b30e55a..b0b616b 100644 --- a/USBNova.ino +++ b/USBNova.ino @@ -21,64 +21,34 @@ void setup() { selector::init(); led::init(); + /* + // Wait until Serial Monitor was opened + while (!Serial) { + delay(1); + } + */ + + delay(1000); + debugln("Started"); + // Setup Mode - if(selector::read()) { + if (selector::read()) { led::setColor(0, 255, 0); debugln("Setup Mode"); - } - // Attack Mode else { led::setColor(255, 0, 0); debugln("Attack Mode"); + msc::open("/payload.script"); + delay(1000); - - // Start reading file - msc::prepareRead("/payload.script"); - - // Read and parse file - char buffer[READ_BUFFER]; - size_t len = 0; - uint32_t prev_pos = 0; - uint32_t cur_pos = 0; - int repeats = 0; - - do { - if(!msc::getInLine()) cur_pos = msc::getPosition(); - len = msc::readLine(buffer, READ_BUFFER); - - duckparser::parse(buffer, len); - - // For REPEAT/REPLAY - repeats = duckparser::getRepeats(); - for(int i=0; i 0); + start_attack(); } + + debugln("Finished"); } void loop() { @@ -99,4 +69,66 @@ void loop() { file.close(); } }*/ +} + +void start_attack() { + // Read and parse file + char buffer[READ_BUFFER]; + + size_t len = 0; + uint32_t prev_pos = 0; + uint32_t cur_pos = 0; + int repeats = 0; + + // For LOOP_START and LOOP_END + uint32_t start_pos = 0; + int loops = 0; + + while (true) { + debug("Reading line..."); + if (!msc::getInLine()) cur_pos = msc::getPosition(); + len = msc::readLine(buffer, READ_BUFFER); + debugln(len); + debugln(std::string(buffer, len-1).c_str()); + + // Reached end of file + if (len == 0) { + debugln("Reached end of file"); + if (msc::openNextFile()) continue; + else break; + } + + debug("Parsing..."); + duckparser::parse(buffer, len); + + // For REPEAT/REPLAY + repeats = duckparser::getRepeats(); + + for (int i = 0; i 1)) { + msc::gotoPosition(start_pos); + --loops; + } + + // For IMPORT + if (duckparser::import()) { + std::string path = duckparser::getImport(); + msc::open(path.c_str()); + } + debugln("OK"); + } } \ No newline at end of file diff --git a/src/duckparser/duckparser.cpp b/src/duckparser/duckparser.cpp index 07ff379..e512503 100644 --- a/src/duckparser/duckparser.cpp +++ b/src/duckparser/duckparser.cpp @@ -24,6 +24,8 @@ namespace duckparser { int repeat_num = 0; int loop_num = 0; + std::string import_path = ""; + unsigned long interpret_time = 0; unsigned long sleep_start_time = 0; unsigned long sleep_time = 0; @@ -163,8 +165,8 @@ namespace duckparser { while (n) { ignore_delay = false; - loop_begin = false; - loop_end = false; + loop_begin = false; + loop_end = false; word_list* wl = n->words; word_node* cmd = wl->first; @@ -181,7 +183,7 @@ namespace duckparser { // Stop it if (compare(cmd->str, cmd->len, "LSTRING_END", CASE_SENSETIVE)) { in_large_string = false; - ignore_delay = true; + ignore_delay = true; } // or type out the entire line else { @@ -192,7 +194,7 @@ namespace duckparser { // LSTRING_BEGIN (-> type each character including linebreaks until LSTRING_END) else if (compare(cmd->str, cmd->len, "LSTRING_BEGIN", CASE_SENSETIVE)) { in_large_string = true; - ignore_delay = true; + ignore_delay = true; } // REM or # (= Comment -> do nothing) else if (in_comment || compare(cmd->str, cmd->len, "REM", CASE_SENSETIVE) || compare(cmd->str, cmd->len, "#", CASE_SENSETIVE)) { @@ -229,13 +231,13 @@ namespace duckparser { } // LOOP_BEGIN else if (compare(cmd->str, cmd->len, "LOOP_BEGIN", CASE_SENSETIVE)) { - loop_num = toInt(line_str, line_str_len); - loop_begin = true; + loop_num = toInt(line_str, line_str_len); + loop_begin = true; ignore_delay = true; } // LOOP_END else if (compare(cmd->str, cmd->len, "LOOP_END", CASE_SENSETIVE)) { - loop_end = true; + loop_end = true; ignore_delay = true; } // LOCALE (-> change keyboard layout) @@ -285,6 +287,10 @@ namespace duckparser { keyboard::release(); } } + // IMPORT (-> open another script) + else if (compare(cmd->str, cmd->len, "IMPORT", CASE_SENSETIVE)) { + import_path = std::string(line_str, line_str_len); + } // Otherwise go through words and look for keys to press else { word_node* w = wl->first; @@ -336,4 +342,14 @@ namespace duckparser { int getLoops() { return loop_num; } + + bool import() { + return !import_path.empty(); + } + + std::string getImport() { + std::string path = import_path; + import_path.clear(); + return path; + } } \ No newline at end of file diff --git a/src/duckparser/duckparser.h b/src/duckparser/duckparser.h index 01d6268..121ad7a 100644 --- a/src/duckparser/duckparser.h +++ b/src/duckparser/duckparser.h @@ -3,12 +3,18 @@ #pragma once #include // size_t +#include // std::string namespace duckparser { void parse(const char* str, size_t len); + int getRepeats(); unsigned int getDelayTime(); + bool loopBegin(); bool loopEnd(); int getLoops(); + + bool import(); + std::string getImport(); }; \ No newline at end of file diff --git a/src/msc/msc.cpp b/src/msc/msc.cpp index a532c9d..7d558f4 100644 --- a/src/msc/msc.cpp +++ b/src/msc/msc.cpp @@ -2,12 +2,25 @@ #include "msc.h" +#include "../../config.h" +#include "../../debug.h" + +#include +#include + #include "SPI.h" #include "Adafruit_SPIFlash.h" #include "Adafruit_TinyUSB.h" namespace msc { // ===== PRIVATE ===== // + typedef struct file_element_t { + std::string path; + uint32_t pos; + } file_element_t; + + std::stack file_stack; + Adafruit_FlashTransport_SPI flashTransport(EXTERNAL_FLASH_USE_CS, EXTERNAL_FLASH_USE_SPI); Adafruit_SPIFlash flash(&flashTransport); Adafruit_USBD_MSC usb_msc; @@ -72,12 +85,70 @@ namespace msc { return tmp; } - bool prepareRead(const char* path) { + bool open(const char* path) { + debug("Open new file: "); + debugln(path); + + // Check if filepath isn't empty if (!path) return false; + // If the stack isn't empty, save the current position + if (!file_stack.empty()) { + file_stack.top().pos = file.curPosition(); + } + + // If a file is already open, close it + if(file.isOpen()) file.close(); + + // Create a new file element and push it to the stack + file_element_t file_element; + file_element.path = std::string(path); + file_element.pos = 0; + file_stack.push(file_element); + + // Open file and return whether it was successful return file.open(path); } + bool openNextFile() { + debug("Opening next file: "); + + // Close current file and remove it from stack (it's not needed anymore) + debug("Stack (before file close): "); + debugln(file_stack.size()); + debugln(file_stack.top().path.c_str()); + + file.close(); + file_stack.pop(); + + debug("Stack (after file close): "); + debugln(file_stack.size()); + + // If stack is now empty, we're done + if (file_stack.empty()){ + debugln("Stack is empty"); + return false; + } + + debugln(file_stack.top().path.c_str()); + + // Get the next file from the stack + file_element_t file_element = file_stack.top(); + + // Open the file + if (file.open(file_element.path.c_str())) { + // Seek to the saved position + gotoPosition(file_element.pos); + debugln("OK"); + return true; + } else { + debug("ERROR failed to open "); + debugln(file_element.path.c_str()); + } + + return false; + } + uint32_t getPosition() { return file.curPosition(); } @@ -91,7 +162,7 @@ namespace msc { // Read as long as the file has data and buffer is not full // -1 to compensate for a extra linebreak at the end of the file - while (file.available() && read < len-1) { + while(file.isOpen() && file.available() > 0 && read < len-1) { // Read character by character char c = file.read(); @@ -107,7 +178,7 @@ namespace msc { in_line = false; break; } - // If no linebreak found, but file ended, add linebreak as last character + // If reached end of the file, add linebreak as last character else if (!file.available()) { buffer[read] = '\n'; in_line = false; diff --git a/src/msc/msc.h b/src/msc/msc.h index 53435e8..b219d5c 100644 --- a/src/msc/msc.h +++ b/src/msc/msc.h @@ -7,7 +7,8 @@ namespace msc { void init(); bool changed(); - bool prepareRead(const char* path); + bool open(const char* path); + bool openNextFile(); uint32_t getPosition(); void gotoPosition(uint32_t pos);