Manual-trigger firmware toolkit for pentesting owned devices: - Pin Scan: UART/JTAG/SWD detection (baud est + IDCODE reads) - V-Sense: target voltage probe w/ logic-family guess - UART Sniff: passive capture + manual-only frame replay - USB Enum: ESP32-S3 host, read-only descriptor fingerprinting - DefCred: single-host factory-default login check, rate-limited Modular shell (core/ + modules/), PlatformIO build, hardware/safety docs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AAhMHMRAQLQ9hSbBECKNfn
72 lines
1.8 KiB
C++
72 lines
1.8 KiB
C++
#include "shell.h"
|
|
#include "ui.h"
|
|
#include <M5Cardputer.h>
|
|
|
|
// Module factories (defined in each module .cpp).
|
|
Module* makePinScan();
|
|
Module* makeVSense();
|
|
Module* makeUartSniff();
|
|
Module* makeUsbEnum();
|
|
Module* makeDefCred();
|
|
|
|
void Shell::begin() {
|
|
add(makePinScan());
|
|
add(makeVSense());
|
|
add(makeUartSniff());
|
|
add(makeUsbEnum());
|
|
add(makeDefCred());
|
|
M5.Display.fillScreen(ui::bg());
|
|
drawMenu();
|
|
}
|
|
|
|
void Shell::drawMenu() {
|
|
M5.Display.fillScreen(ui::bg());
|
|
ui::titleBar("Card-Crack", CARDCRACK_VERSION);
|
|
for (int i = 0; i < nmods; i++) {
|
|
bool cur = i == sel;
|
|
ui::lineC(i, cur ? ui::accent() : ui::fg(), "%c %-10s %s",
|
|
cur ? '>' : ' ', mods[i]->name(), mods[i]->blurb());
|
|
}
|
|
ui::hintBar("arrows move [enter]open home-lab only");
|
|
}
|
|
|
|
void Shell::enter(int i) {
|
|
active = i;
|
|
M5.Display.fillScreen(ui::bg());
|
|
ui::titleBar(mods[i]->name(), mods[i]->blurb());
|
|
mods[i]->onEnter();
|
|
mods[i]->draw();
|
|
}
|
|
|
|
void Shell::back() {
|
|
if (active >= 0) mods[active]->onExit();
|
|
active = -1;
|
|
drawMenu();
|
|
}
|
|
|
|
void Shell::loop() {
|
|
M5Cardputer.update();
|
|
|
|
if (M5Cardputer.Keyboard.isChange() && M5Cardputer.Keyboard.isPressed()) {
|
|
auto st = M5Cardputer.Keyboard.keysState();
|
|
for (char c : st.word) {
|
|
if (c == '`') { if (active >= 0) back(); continue; }
|
|
if (active < 0) {
|
|
if (c == ';') { sel = (sel - 1 + nmods) % nmods; drawMenu(); } // up
|
|
else if (c == '.') { sel = (sel + 1) % nmods; drawMenu(); } // down
|
|
else if (c == '\r' || c == ' ') enter(sel);
|
|
} else {
|
|
mods[active]->onKey(c);
|
|
}
|
|
}
|
|
if (st.enter && active < 0) enter(sel);
|
|
}
|
|
|
|
// ~30 Hz tick for the active module.
|
|
if (active >= 0 && millis() - lastTick > 33) {
|
|
lastTick = millis();
|
|
mods[active]->tick();
|
|
mods[active]->draw();
|
|
}
|
|
}
|