Support for IMPORT function

This commit is contained in:
Spacehuhn 2022-07-03 18:41:25 +02:00
parent b5b9453d54
commit 9c2b15e140
5 changed files with 183 additions and 57 deletions

View File

@ -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<repeats; ++i) {
msc::gotoPosition(prev_pos);
do {
len = msc::readLine(buffer, READ_BUFFER);
duckparser::parse(buffer, len);
} while(msc::getInLine());
}
if(!msc::getInLine()) prev_pos = cur_pos;
// For LOOP_START/LOOP_STOP
if(duckparser::loopBegin()) {
uint32_t start_pos = msc::getPosition();
int loops = duckparser::getLoops();
for(int i=0; i<loops; ++i) {
msc::gotoPosition(start_pos);
do {
len = msc::readLine(buffer, READ_BUFFER);
duckparser::parse(buffer, len);
} while(!duckparser::loopEnd());
}
}
} while(len > 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<repeats; ++i) {
msc::gotoPosition(prev_pos);
do {
len = msc::readLine(buffer, READ_BUFFER);
duckparser::parse(buffer, len);
} while (msc::getInLine());
}
if (!msc::getInLine()) prev_pos = cur_pos;
// For LOOP_START/LOOP_STOP
if (duckparser::loopBegin()) {
start_pos = msc::getPosition();
loops = duckparser::getLoops();
} else if (duckparser::loopEnd() && (loops > 1)) {
msc::gotoPosition(start_pos);
--loops;
}
// For IMPORT
if (duckparser::import()) {
std::string path = duckparser::getImport();
msc::open(path.c_str());
}
debugln("OK");
}
}

View File

@ -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;
}
}

View File

@ -3,12 +3,18 @@
#pragma once
#include <stddef.h> // size_t
#include <string> // 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();
};

View File

@ -2,12 +2,25 @@
#include "msc.h"
#include "../../config.h"
#include "../../debug.h"
#include <string>
#include <stack>
#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_element_t> 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;

View File

@ -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);