RP2040 Support
This commit is contained in:
parent
ef4e77edd5
commit
8db0a6e881
|
@ -25,4 +25,5 @@ Compile and export:
|
||||||
`arduino-cli compile --fqbn adafruit:samd:adafruit_qtpy_m0_nova:usbstack=tinyusb,debug=off --output-dir build/`
|
`arduino-cli compile --fqbn adafruit:samd:adafruit_qtpy_m0_nova:usbstack=tinyusb,debug=off --output-dir build/`
|
||||||
|
|
||||||
Convert to uf2:
|
Convert to uf2:
|
||||||
`uf2conv build/USBNova.ino.bin -o build/USBNova.ino.uf2`
|
`uf2conv build/USBNova.ino.bin -o build/USBNova.ino.uf2`
|
||||||
|
(To install uf2conv, install rust, then `cargo install uf2conv`)
|
35
USBNova.ino
35
USBNova.ino
|
@ -18,7 +18,7 @@ void update() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
// Start Serial (for debug)
|
// Start Serial (for debug) or disable it
|
||||||
debug_init();
|
debug_init();
|
||||||
|
|
||||||
// Initialize memory and check for problems
|
// Initialize memory and check for problems
|
||||||
|
@ -35,14 +35,14 @@ void setup() {
|
||||||
|
|
||||||
// Read mode from selector switch
|
// Read mode from selector switch
|
||||||
selector::init();
|
selector::init();
|
||||||
|
|
||||||
// Start Keyboard
|
// Start Keyboard
|
||||||
if (selector::mode() == ATTACK || preferences::hidEnabled()) {
|
if ((selector::mode() == ATTACK) || preferences::hidEnabled()) {
|
||||||
hid::init();
|
hid::init();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start USB Drive
|
// Start USB Drive
|
||||||
if (preferences::mscEnabled() || (selector::mode() == SETUP)){
|
if (preferences::mscEnabled() || (selector::mode() == SETUP)) {
|
||||||
msc::enableDrive();
|
msc::enableDrive();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ void setup() {
|
||||||
if (!msc::exists(PREFERENCES_PATH)) {
|
if (!msc::exists(PREFERENCES_PATH)) {
|
||||||
preferences::save();
|
preferences::save();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create main_script.txt if it doesn't exist yet
|
// Create main_script.txt if it doesn't exist yet
|
||||||
if (!msc::exists(preferences::getMainScript().c_str())) {
|
if (!msc::exists(preferences::getMainScript().c_str())) {
|
||||||
char message[21];
|
char message[21];
|
||||||
|
@ -85,42 +85,43 @@ void setup() {
|
||||||
selector::changed();
|
selector::changed();
|
||||||
|
|
||||||
// Start attack
|
// Start attack
|
||||||
if (selector::mode() == ATTACK && !preferences::getRunOnIndicator()) {
|
if ((selector::mode() == ATTACK) && !preferences::getRunOnIndicator()) {
|
||||||
delay(preferences::getInitialDelay()); // Wait to give computer time to init keyboard
|
delay(preferences::getInitialDelay()); // Wait to give computer time to init keyboard
|
||||||
attack::start(); // Start keystroke injection attack
|
attack::start(); // Start keystroke injection attack
|
||||||
led::setColor(preferences::getIdleColor()); // Set LED to green
|
led::setColor(preferences::getIdleColor()); // Set LED to green
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup CLI
|
// Setup CLI
|
||||||
|
#ifdef ENABLE_DEBUG
|
||||||
cli::init();
|
cli::init();
|
||||||
|
#endif // ifdef ENABLE_DEBUG
|
||||||
|
|
||||||
debugln("[Started]");
|
debugln("[Started]");
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
taks:update();
|
tasks::update();
|
||||||
cli::update();
|
cli::update();
|
||||||
|
|
||||||
if(selector::read() != ATTACK) return;
|
if (selector::read() != ATTACK) return;
|
||||||
|
|
||||||
// Only start the attack if run-on-indicator is disabled, or indicator actually changed
|
// Only start the attack if run-on-indicator is disabled, or indicator actually changed
|
||||||
if(preferences::getRunOnIndicator() && hid::indicatorChanged()) {
|
if (preferences::getRunOnIndicator() && hid::indicatorChanged()) {
|
||||||
delay(100);
|
delay(100);
|
||||||
attack::start(); // Run script
|
attack::start(); // Run script
|
||||||
led::setColor(preferences::getIdleColor()); // Set LED to green
|
led::setColor(preferences::getIdleColor()); // Set LED to green
|
||||||
} else if (selector::changed()) {
|
} else if (selector::changed()) {
|
||||||
// ========== Setup Mode ========== //
|
// ========== Setup Mode ========== //
|
||||||
if (selector::mode() == SETUP && preferences::hidEnabled()) {
|
if ((selector::mode() == SETUP) && preferences::hidEnabled()) {
|
||||||
preferences::load(); // Reload the settings (in case the main script path changed)
|
preferences::load(); // Reload the settings (in case the main script path changed)
|
||||||
|
|
||||||
// Attack settings
|
// Attack settings
|
||||||
keyboard::setLocale(locale::get(preferences::getDefaultLayout().c_str()));
|
keyboard::setLocale(locale::get(preferences::getDefaultLayout().c_str()));
|
||||||
duckparser::setDefaultDelay(preferences::getDefaultDelay());
|
duckparser::setDefaultDelay(preferences::getDefaultDelay());
|
||||||
|
|
||||||
attack::start(); // Start keystroke injection attack
|
attack::start(); // Start keystroke injection attack
|
||||||
led::setColor(preferences::getSetupColor()); // Set LED to blue
|
led::setColor(preferences::getSetupColor()); // Set LED to blue
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========== Attack Mode ========== //
|
// ========== Attack Mode ========== //
|
||||||
else if (selector::mode() == ATTACK) {
|
else if (selector::mode() == ATTACK) {
|
||||||
// Only start the attack if run-on-indicator is disabled, or indicator actually changed
|
// Only start the attack if run-on-indicator is disabled, or indicator actually changed
|
||||||
|
|
14
config.h
14
config.h
|
@ -2,10 +2,10 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define VERSION "1.1.2"
|
#define VERSION "1.1.3"
|
||||||
|
|
||||||
// ===== DEBUG Settings ===== //
|
// ===== DEBUG Settings ===== //
|
||||||
//#define ENABLE_DEBUG
|
// #define ENABLE_DEBUG
|
||||||
#define DEBUG_PORT Serial
|
#define DEBUG_PORT Serial
|
||||||
#define DEBUG_BAUD 115200
|
#define DEBUG_BAUD 115200
|
||||||
|
|
||||||
|
@ -13,10 +13,20 @@
|
||||||
#define READ_BUFFER 2048
|
#define READ_BUFFER 2048
|
||||||
|
|
||||||
// ===== LED Settings ===== //
|
// ===== LED Settings ===== //
|
||||||
|
|
||||||
|
#if defined(ARDUINO_ARCH_RP2040)
|
||||||
|
#define LED_PIN 12
|
||||||
|
#else // if defined(ARDUINO_ARCH_RP2040)
|
||||||
#define LED_PIN 11
|
#define LED_PIN 11
|
||||||
|
#endif // if defined(ARDUINO_ARCH_RP2040)
|
||||||
|
|
||||||
// ===== SELECTOR SWITCH ===== //
|
// ===== SELECTOR SWITCH ===== //
|
||||||
|
|
||||||
|
#if defined(ARDUINO_ARCH_RP2040)
|
||||||
|
#define SELECTOR 13
|
||||||
|
#else // if defined(ARDUINO_ARCH_RP2040)
|
||||||
#define SELECTOR A0
|
#define SELECTOR A0
|
||||||
|
#endif // if defined(ARDUINO_ARCH_RP2040)
|
||||||
|
|
||||||
// ===== Parser Settings ===== //
|
// ===== Parser Settings ===== //
|
||||||
#define CASE_SENSETIVE false
|
#define CASE_SENSETIVE false
|
||||||
|
|
1
debug.h
1
debug.h
|
@ -3,6 +3,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
#ifdef ENABLE_DEBUG
|
#ifdef ENABLE_DEBUG
|
||||||
|
|
||||||
|
|
|
@ -11,12 +11,13 @@
|
||||||
#include "../attack/attack.h"
|
#include "../attack/attack.h"
|
||||||
#include "../msc/msc.h"
|
#include "../msc/msc.h"
|
||||||
#include "../../config.h"
|
#include "../../config.h"
|
||||||
|
#include "../../debug.h"
|
||||||
|
|
||||||
#define BUFFER_SIZE 1024
|
#define BUFFER_SIZE 1024
|
||||||
|
|
||||||
namespace cli {
|
namespace cli {
|
||||||
// ====== PRIVATE ====== //
|
// ====== PRIVATE ====== //
|
||||||
SimpleCLI cli;
|
SimpleCLI cli;
|
||||||
char buffer[BUFFER_SIZE];
|
char buffer[BUFFER_SIZE];
|
||||||
|
|
||||||
// Copied from https://github.com/SpacehuhnTech/esp8266_deauther/blob/b70dc19579e7af65857726ae45e3e477899942ac/esp8266_deauther/cli.cpp#L1602
|
// Copied from https://github.com/SpacehuhnTech/esp8266_deauther/blob/b70dc19579e7af65857726ae45e3e477899942ac/esp8266_deauther/cli.cpp#L1602
|
||||||
|
@ -59,38 +60,38 @@ namespace cli {
|
||||||
|
|
||||||
// ====== PUBLIC ====== //
|
// ====== PUBLIC ====== //
|
||||||
void init() {
|
void init() {
|
||||||
Serial.begin(115200);
|
// Serial.begin(115200);
|
||||||
|
|
||||||
// error
|
// error
|
||||||
cli.setOnError([](cmd_error* e) {
|
cli.setOnError([](cmd_error* e) {
|
||||||
CommandError cmdError(e);
|
CommandError cmdError(e);
|
||||||
|
|
||||||
Serial.print("ERROR: ");
|
debugF("ERROR: ");
|
||||||
Serial.println(cmdError.toString());
|
debugln(cmdError.toString());
|
||||||
|
|
||||||
if (cmdError.hasCommand()) {
|
if (cmdError.hasCommand()) {
|
||||||
Serial.print("Did you mean \"");
|
debugF("Did you mean \"");
|
||||||
Serial.print(cmdError.getCommand().toString());
|
debug(cmdError.getCommand().toString());
|
||||||
Serial.println("\"?");
|
debuglnF("\"?");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// help
|
// help
|
||||||
cli.addCmd("help", [](cmd* c) {
|
cli.addCmd("help", [](cmd* c) {
|
||||||
Serial.println("[ = Available Commands =]");
|
debuglnF("[ = Available Commands =]");
|
||||||
Serial.print(cli.toString());
|
debug(cli.toString());
|
||||||
Serial.println("Enter any BadUSB Scripts to run it.");
|
debuglnF("Enter any BadUSB Scripts to run it.");
|
||||||
Serial.println();
|
debugln();
|
||||||
}).setDescription(" Get a list of available commands.");
|
}).setDescription(" Get a list of available commands.");
|
||||||
|
|
||||||
// version
|
// version
|
||||||
cli.addCmd("version", [](cmd* c) {
|
cli.addCmd("version", [](cmd* c) {
|
||||||
Serial.println("[ = USB Nova =]");
|
debuglnF("[ = USB Nova =]");
|
||||||
Serial.print("Version ");
|
debugF("Version ");
|
||||||
Serial.println(VERSION);
|
debugln(VERSION);
|
||||||
Serial.println("Source: https://github.com/spacehuhntech/usbnova");
|
debuglnF("Source: https://github.com/spacehuhntech/usbnova");
|
||||||
Serial.println("Made with <3 by Spacehuhn (spacehuhn.com)");
|
debuglnF("Made with <3 by Spacehuhn (spacehuhn.com)");
|
||||||
Serial.println();
|
debugln();
|
||||||
}).setDescription(" Print the firmware version.");
|
}).setDescription(" Print the firmware version.");
|
||||||
|
|
||||||
// format
|
// format
|
||||||
|
@ -98,25 +99,25 @@ namespace cli {
|
||||||
led::setColor(255, 255, 255);
|
led::setColor(255, 255, 255);
|
||||||
msc::format(preferences::getDriveName().c_str());
|
msc::format(preferences::getDriveName().c_str());
|
||||||
preferences::save();
|
preferences::save();
|
||||||
if(selector::mode() == SETUP) {
|
if (selector::mode() == SETUP) {
|
||||||
led::setColor(preferences::getSetupColor());
|
led::setColor(preferences::getSetupColor());
|
||||||
} else {
|
} else {
|
||||||
led::setColor(preferences::getIdleColor());
|
led::setColor(preferences::getIdleColor());
|
||||||
}
|
}
|
||||||
|
|
||||||
Serial.println("Done formatting!");
|
debuglnF("Done formatting!");
|
||||||
Serial.println();
|
debugln();
|
||||||
}).setDescription(" Fromat the internal memory.");
|
}).setDescription(" Fromat the internal memory.");
|
||||||
|
|
||||||
// reset
|
// reset
|
||||||
cli.addCmd("reset", [](cmd* c) {
|
cli.addCmd("reset", [](cmd* c) {
|
||||||
preferences::reset();
|
preferences::reset();
|
||||||
preferences::save();
|
preferences::save();
|
||||||
|
|
||||||
Serial.println("Done resetting!");
|
debuglnF("Done resetting!");
|
||||||
Serial.println();
|
debugln();
|
||||||
}).setDescription(" Reset the preferences.");
|
}).setDescription(" Reset the preferences.");
|
||||||
|
|
||||||
// TODO: preferences
|
// TODO: preferences
|
||||||
cli.addSingleArgCmd("preferences", [](cmd* c) {
|
cli.addSingleArgCmd("preferences", [](cmd* c) {
|
||||||
preferences::print();
|
preferences::print();
|
||||||
|
@ -132,7 +133,7 @@ namespace cli {
|
||||||
Command cmd(c);
|
Command cmd(c);
|
||||||
Argument arg = cmd.getArgument(0);
|
Argument arg = cmd.getArgument(0);
|
||||||
attack::start(arg.getValue().c_str());
|
attack::start(arg.getValue().c_str());
|
||||||
if(selector::mode() == SETUP) {
|
if (selector::mode() == SETUP) {
|
||||||
led::setColor(preferences::getSetupColor());
|
led::setColor(preferences::getSetupColor());
|
||||||
} else {
|
} else {
|
||||||
led::setColor(preferences::getIdleColor());
|
led::setColor(preferences::getIdleColor());
|
||||||
|
|
|
@ -2,14 +2,16 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "../../config.h"
|
||||||
|
|
||||||
#include <cstdint> // uint8_t
|
#include <cstdint> // uint8_t
|
||||||
|
|
||||||
namespace hid {
|
namespace hid {
|
||||||
// Report ID
|
// Report ID
|
||||||
enum RID {
|
enum RID {
|
||||||
KEYBOARD = 0,
|
KEYBOARD = 1,
|
||||||
MOUSE = 1,
|
MOUSE = 2,
|
||||||
CONSUMER_CONTROL = 2, // Media, volume etc ..
|
CONSUMER_CONTROL = 3, // Media, volume etc ..
|
||||||
};
|
};
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
|
|
|
@ -19,7 +19,16 @@
|
||||||
|
|
||||||
namespace format {
|
namespace format {
|
||||||
// ========== PRIVATE ========= //
|
// ========== PRIVATE ========= //
|
||||||
|
#if defined(ARDUINO_ARCH_RP2040)
|
||||||
|
// RP2040 use same flash device that store code for file system. Therefore we
|
||||||
|
// only need to specify start address and size (no need SPI or SS)
|
||||||
|
// By default (start=0, size=0), values that match file system setting in
|
||||||
|
// 'Tools->Flash Size' menu selection will be used.
|
||||||
|
Adafruit_FlashTransport_RP2040 flashTransport;
|
||||||
|
#else // if defined(ARDUINO_ARCH_RP2040)
|
||||||
Adafruit_FlashTransport_SPI flashTransport(EXTERNAL_FLASH_USE_CS, EXTERNAL_FLASH_USE_SPI);
|
Adafruit_FlashTransport_SPI flashTransport(EXTERNAL_FLASH_USE_CS, EXTERNAL_FLASH_USE_SPI);
|
||||||
|
#endif // if defined(ARDUINO_ARCH_RP2040)
|
||||||
|
|
||||||
Adafruit_SPIFlash flash(&flashTransport);
|
Adafruit_SPIFlash flash(&flashTransport);
|
||||||
|
|
||||||
// file system object from SdFat
|
// file system object from SdFat
|
||||||
|
|
|
@ -23,7 +23,16 @@ namespace msc {
|
||||||
|
|
||||||
std::stack<file_element_t> file_stack;
|
std::stack<file_element_t> file_stack;
|
||||||
|
|
||||||
|
#if defined(ARDUINO_ARCH_RP2040)
|
||||||
|
// RP2040 use same flash device that store code for file system. Therefore we
|
||||||
|
// only need to specify start address and size (no need SPI or SS)
|
||||||
|
// By default (start=0, size=0), values that match file system setting in
|
||||||
|
// 'Tools->Flash Size' menu selection will be used.
|
||||||
|
Adafruit_FlashTransport_RP2040 flashTransport;
|
||||||
|
#else // if defined(ARDUINO_ARCH_RP2040)
|
||||||
Adafruit_FlashTransport_SPI flashTransport(EXTERNAL_FLASH_USE_CS, EXTERNAL_FLASH_USE_SPI);
|
Adafruit_FlashTransport_SPI flashTransport(EXTERNAL_FLASH_USE_CS, EXTERNAL_FLASH_USE_SPI);
|
||||||
|
#endif // if defined(ARDUINO_ARCH_RP2040)
|
||||||
|
|
||||||
Adafruit_SPIFlash flash(&flashTransport);
|
Adafruit_SPIFlash flash(&flashTransport);
|
||||||
Adafruit_USBD_MSC usb_msc;
|
Adafruit_USBD_MSC usb_msc;
|
||||||
|
|
||||||
|
@ -69,16 +78,16 @@ namespace msc {
|
||||||
|
|
||||||
// ===== PUBLIC ===== //
|
// ===== PUBLIC ===== //
|
||||||
bool init() {
|
bool init() {
|
||||||
if(!flash.begin()) {
|
if (!flash.begin()) {
|
||||||
debugln("Couldn't find flash chip!");
|
debugln("Couldn't find flash chip!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try formatting the drive if initialization failed
|
// Try formatting the drive if initialization failed
|
||||||
if(!fatfs.begin(&flash)) {
|
if (!fatfs.begin(&flash)) {
|
||||||
format();
|
format();
|
||||||
|
|
||||||
if(!fatfs.begin(&flash)) {
|
if (!fatfs.begin(&flash)) {
|
||||||
debugln("Couldn't mount flash!");
|
debugln("Couldn't mount flash!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -86,30 +95,31 @@ namespace msc {
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool format(const char* drive_name) {
|
bool format(const char* drive_name) {
|
||||||
return format::start(drive_name);
|
return format::start(drive_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void print() {
|
void print() {
|
||||||
Serial.println("Available files:");
|
debuglnF("Available files:");
|
||||||
|
|
||||||
// Close file(s)
|
// Close file(s)
|
||||||
if (file.isOpen()) file.close();
|
if (file.isOpen()) file.close();
|
||||||
|
|
||||||
while (!file_stack.empty()) file_stack.pop();
|
while (!file_stack.empty()) file_stack.pop();
|
||||||
|
|
||||||
SdFile root;
|
SdFile root;
|
||||||
root.open("/");
|
root.open("/");
|
||||||
|
|
||||||
while ( file.openNext(&root, O_RDONLY) ) {
|
while (file.openNext(&root, O_RDONLY)) {
|
||||||
file.printFileSize(&Serial);
|
file.printFileSize(&Serial);
|
||||||
Serial.write(' ');
|
debugF(" ");
|
||||||
file.printName(&Serial);
|
file.printName(&Serial);
|
||||||
if (file.isDir()) {
|
if (file.isDir()) {
|
||||||
// Indicate a directory.
|
// Indicate a directory.
|
||||||
Serial.write('/');
|
debugF("/");
|
||||||
}
|
}
|
||||||
Serial.println();
|
debugln();
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -131,7 +141,7 @@ namespace msc {
|
||||||
fs_changed = false;
|
fs_changed = false;
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool exists(const char* filename) {
|
bool exists(const char* filename) {
|
||||||
return fatfs.exists(filename);
|
return fatfs.exists(filename);
|
||||||
}
|
}
|
||||||
|
@ -152,7 +162,7 @@ namespace msc {
|
||||||
if (file.isOpen()) file.close();
|
if (file.isOpen()) file.close();
|
||||||
|
|
||||||
// Create a new file element and push it to the stack
|
// Create a new file element and push it to the stack
|
||||||
if(add_to_stack) {
|
if (add_to_stack) {
|
||||||
file_element_t file_element;
|
file_element_t file_element;
|
||||||
file_element.path = std::string(path);
|
file_element.path = std::string(path);
|
||||||
file_element.pos = 0;
|
file_element.pos = 0;
|
||||||
|
@ -261,6 +271,7 @@ namespace msc {
|
||||||
|
|
||||||
size_t write(const char* path, const char* buffer, size_t len) {
|
size_t write(const char* path, const char* buffer, size_t len) {
|
||||||
FatFile wfile;
|
FatFile wfile;
|
||||||
|
|
||||||
wfile.open(path, (O_RDWR | O_CREAT));
|
wfile.open(path, (O_RDWR | O_CREAT));
|
||||||
if (!wfile.isOpen()) return 0;
|
if (!wfile.isOpen()) return 0;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue