Support for IMPORT function
This commit is contained in:
parent
b5b9453d54
commit
9c2b15e140
124
USBNova.ino
124
USBNova.ino
|
@ -21,64 +21,34 @@ void setup() {
|
||||||
selector::init();
|
selector::init();
|
||||||
led::init();
|
led::init();
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Wait until Serial Monitor was opened
|
||||||
|
while (!Serial) {
|
||||||
|
delay(1);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
delay(1000);
|
||||||
|
debugln("Started");
|
||||||
|
|
||||||
// Setup Mode
|
// Setup Mode
|
||||||
if(selector::read()) {
|
if (selector::read()) {
|
||||||
led::setColor(0, 255, 0);
|
led::setColor(0, 255, 0);
|
||||||
debugln("Setup Mode");
|
debugln("Setup Mode");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attack Mode
|
// Attack Mode
|
||||||
else {
|
else {
|
||||||
led::setColor(255, 0, 0);
|
led::setColor(255, 0, 0);
|
||||||
debugln("Attack Mode");
|
debugln("Attack Mode");
|
||||||
|
|
||||||
|
msc::open("/payload.script");
|
||||||
|
|
||||||
delay(1000);
|
delay(1000);
|
||||||
|
|
||||||
// Start reading file
|
|
||||||
msc::prepareRead("/payload.script");
|
|
||||||
|
|
||||||
// Read and parse file
|
|
||||||
char buffer[READ_BUFFER];
|
|
||||||
|
|
||||||
size_t len = 0;
|
start_attack();
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debugln("Finished");
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
|
@ -99,4 +69,66 @@ void loop() {
|
||||||
file.close();
|
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");
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -24,6 +24,8 @@ namespace duckparser {
|
||||||
int repeat_num = 0;
|
int repeat_num = 0;
|
||||||
int loop_num = 0;
|
int loop_num = 0;
|
||||||
|
|
||||||
|
std::string import_path = "";
|
||||||
|
|
||||||
unsigned long interpret_time = 0;
|
unsigned long interpret_time = 0;
|
||||||
unsigned long sleep_start_time = 0;
|
unsigned long sleep_start_time = 0;
|
||||||
unsigned long sleep_time = 0;
|
unsigned long sleep_time = 0;
|
||||||
|
@ -163,8 +165,8 @@ namespace duckparser {
|
||||||
|
|
||||||
while (n) {
|
while (n) {
|
||||||
ignore_delay = false;
|
ignore_delay = false;
|
||||||
loop_begin = false;
|
loop_begin = false;
|
||||||
loop_end = false;
|
loop_end = false;
|
||||||
|
|
||||||
word_list* wl = n->words;
|
word_list* wl = n->words;
|
||||||
word_node* cmd = wl->first;
|
word_node* cmd = wl->first;
|
||||||
|
@ -181,7 +183,7 @@ namespace duckparser {
|
||||||
// Stop it
|
// Stop it
|
||||||
if (compare(cmd->str, cmd->len, "LSTRING_END", CASE_SENSETIVE)) {
|
if (compare(cmd->str, cmd->len, "LSTRING_END", CASE_SENSETIVE)) {
|
||||||
in_large_string = false;
|
in_large_string = false;
|
||||||
ignore_delay = true;
|
ignore_delay = true;
|
||||||
}
|
}
|
||||||
// or type out the entire line
|
// or type out the entire line
|
||||||
else {
|
else {
|
||||||
|
@ -192,7 +194,7 @@ namespace duckparser {
|
||||||
// LSTRING_BEGIN (-> type each character including linebreaks until LSTRING_END)
|
// LSTRING_BEGIN (-> type each character including linebreaks until LSTRING_END)
|
||||||
else if (compare(cmd->str, cmd->len, "LSTRING_BEGIN", CASE_SENSETIVE)) {
|
else if (compare(cmd->str, cmd->len, "LSTRING_BEGIN", CASE_SENSETIVE)) {
|
||||||
in_large_string = true;
|
in_large_string = true;
|
||||||
ignore_delay = true;
|
ignore_delay = true;
|
||||||
}
|
}
|
||||||
// REM or # (= Comment -> do nothing)
|
// REM or # (= Comment -> do nothing)
|
||||||
else if (in_comment || compare(cmd->str, cmd->len, "REM", CASE_SENSETIVE) || compare(cmd->str, cmd->len, "#", CASE_SENSETIVE)) {
|
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
|
// LOOP_BEGIN
|
||||||
else if (compare(cmd->str, cmd->len, "LOOP_BEGIN", CASE_SENSETIVE)) {
|
else if (compare(cmd->str, cmd->len, "LOOP_BEGIN", CASE_SENSETIVE)) {
|
||||||
loop_num = toInt(line_str, line_str_len);
|
loop_num = toInt(line_str, line_str_len);
|
||||||
loop_begin = true;
|
loop_begin = true;
|
||||||
ignore_delay = true;
|
ignore_delay = true;
|
||||||
}
|
}
|
||||||
// LOOP_END
|
// LOOP_END
|
||||||
else if (compare(cmd->str, cmd->len, "LOOP_END", CASE_SENSETIVE)) {
|
else if (compare(cmd->str, cmd->len, "LOOP_END", CASE_SENSETIVE)) {
|
||||||
loop_end = true;
|
loop_end = true;
|
||||||
ignore_delay = true;
|
ignore_delay = true;
|
||||||
}
|
}
|
||||||
// LOCALE (-> change keyboard layout)
|
// LOCALE (-> change keyboard layout)
|
||||||
|
@ -285,6 +287,10 @@ namespace duckparser {
|
||||||
keyboard::release();
|
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
|
// Otherwise go through words and look for keys to press
|
||||||
else {
|
else {
|
||||||
word_node* w = wl->first;
|
word_node* w = wl->first;
|
||||||
|
@ -336,4 +342,14 @@ namespace duckparser {
|
||||||
int getLoops() {
|
int getLoops() {
|
||||||
return loop_num;
|
return loop_num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool import() {
|
||||||
|
return !import_path.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getImport() {
|
||||||
|
std::string path = import_path;
|
||||||
|
import_path.clear();
|
||||||
|
return path;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -3,12 +3,18 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stddef.h> // size_t
|
#include <stddef.h> // size_t
|
||||||
|
#include <string> // std::string
|
||||||
|
|
||||||
namespace duckparser {
|
namespace duckparser {
|
||||||
void parse(const char* str, size_t len);
|
void parse(const char* str, size_t len);
|
||||||
|
|
||||||
int getRepeats();
|
int getRepeats();
|
||||||
unsigned int getDelayTime();
|
unsigned int getDelayTime();
|
||||||
|
|
||||||
bool loopBegin();
|
bool loopBegin();
|
||||||
bool loopEnd();
|
bool loopEnd();
|
||||||
int getLoops();
|
int getLoops();
|
||||||
|
|
||||||
|
bool import();
|
||||||
|
std::string getImport();
|
||||||
};
|
};
|
|
@ -2,12 +2,25 @@
|
||||||
|
|
||||||
#include "msc.h"
|
#include "msc.h"
|
||||||
|
|
||||||
|
#include "../../config.h"
|
||||||
|
#include "../../debug.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <stack>
|
||||||
|
|
||||||
#include "SPI.h"
|
#include "SPI.h"
|
||||||
#include "Adafruit_SPIFlash.h"
|
#include "Adafruit_SPIFlash.h"
|
||||||
#include "Adafruit_TinyUSB.h"
|
#include "Adafruit_TinyUSB.h"
|
||||||
|
|
||||||
namespace msc {
|
namespace msc {
|
||||||
// ===== PRIVATE ===== //
|
// ===== 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_FlashTransport_SPI flashTransport(EXTERNAL_FLASH_USE_CS, EXTERNAL_FLASH_USE_SPI);
|
||||||
Adafruit_SPIFlash flash(&flashTransport);
|
Adafruit_SPIFlash flash(&flashTransport);
|
||||||
Adafruit_USBD_MSC usb_msc;
|
Adafruit_USBD_MSC usb_msc;
|
||||||
|
@ -72,12 +85,70 @@ namespace msc {
|
||||||
return tmp;
|
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 (!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);
|
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() {
|
uint32_t getPosition() {
|
||||||
return file.curPosition();
|
return file.curPosition();
|
||||||
}
|
}
|
||||||
|
@ -91,7 +162,7 @@ namespace msc {
|
||||||
|
|
||||||
// Read as long as the file has data and buffer is not full
|
// 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
|
// -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
|
// Read character by character
|
||||||
char c = file.read();
|
char c = file.read();
|
||||||
|
|
||||||
|
@ -107,7 +178,7 @@ namespace msc {
|
||||||
in_line = false;
|
in_line = false;
|
||||||
break;
|
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()) {
|
else if (!file.available()) {
|
||||||
buffer[read] = '\n';
|
buffer[read] = '\n';
|
||||||
in_line = false;
|
in_line = false;
|
||||||
|
|
|
@ -7,7 +7,8 @@
|
||||||
namespace msc {
|
namespace msc {
|
||||||
void init();
|
void init();
|
||||||
bool changed();
|
bool changed();
|
||||||
bool prepareRead(const char* path);
|
bool open(const char* path);
|
||||||
|
bool openNextFile();
|
||||||
|
|
||||||
uint32_t getPosition();
|
uint32_t getPosition();
|
||||||
void gotoPosition(uint32_t pos);
|
void gotoPosition(uint32_t pos);
|
||||||
|
|
Loading…
Reference in New Issue