RP2040 Support

This commit is contained in:
Spacehuhn 2023-06-27 16:37:04 +02:00
parent ef4e77edd5
commit 8db0a6e881
8 changed files with 100 additions and 64 deletions

View File

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

View File

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

View File

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

View File

@ -3,6 +3,7 @@
#pragma once #pragma once
#include <Arduino.h> #include <Arduino.h>
#include "config.h"
#ifdef ENABLE_DEBUG #ifdef ENABLE_DEBUG

View File

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

View File

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

View File

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

View File

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