English | 中文
Runtime code injection for ARM Cortex-M. Replace any function on a running MCU through a serial connection — no reflashing, no debugger, no downtime.
FPBInject uses the Flash Patch and Breakpoint (FPB) hardware unit to intercept function calls and redirect them to your custom code in RAM, while the original Flash stays untouched.
flowchart LR
A["caller()<br/>calls foo()"] -->|"FPB intercepts<br/>foo's address"| B["Trampoline<br/>in Flash"]
B -->|"Jump to RAM"| C["Your Code<br/>in RAM"]
The FPB unit matches the target function's address, redirects execution through a trampoline in Flash, which jumps to your replacement function in RAM. All handled by hardware — zero software overhead on the call path.
FPBInject ships with a browser-based workbench for the full workflow: browse symbols, read disassembly, write patches, and inject — all from one interface.
Search the firmware's symbol table, click a function to view its disassembly or decompiled source.
Write your replacement function in C, then hit inject. The workbench compiles, uploads, and patches — typically under a second.
Point the workbench at your source directory and enable file watching. Add /* FPB_INJECT */ before any function you want to patch, then just save the file — the workbench detects the change, recompiles, and re-injects automatically.
FPBInject also supports file transfer over serial — browse, upload, and download files on the device's filesystem. Supports drag-and-drop (files and folders), CRC verification, and progress tracking.
Filesystem backends: POSIX (NuttX VFS, Linux), FatFS, standard C library (stdio), or custom implementations via the fl_fs_ops_t interface.
git clone https://github.com/FASTSHIFT/FPBInject.git
cd FPBInject
cmake -B build -DAPP_SELECT=3 -DCMAKE_TOOLCHAIN_FILE=cmake/arm-none-eabi-gcc.cmake
cmake --build build
st-flash write build/FPBInject.bin 0x08000000cd Tools/WebServer
pip install -r ../requirements.txt
python main.pyOpen http://127.0.0.1:5500 in your browser, connect to the serial port, load your ELF file, and start patching.
All commands output JSON, designed for scripting and AI agent integration.
# Search for functions
python fpb_cli.py search firmware.elf "gpio"
# View disassembly
python fpb_cli.py disasm firmware.elf digitalWrite
# Inject a patch
python fpb_cli.py --port /dev/ttyACM0 --elf firmware.elf \
--compile-commands build/compile_commands.json \
inject digitalWrite patch.cSee the CLI Guide for the full command reference.
Create a C file with the /* FPB_INJECT */ marker. The function signature must match the original.
#include <Arduino.h>
/* FPB_INJECT */
__attribute__((section(".fpb.text"), used))
void digitalWrite(uint8_t pin, uint8_t value) {
printf("Patched: pin=%d val=%d\n", pin, value);
value ? digitalWrite_HIGH(pin)
: digitalWrite_LOW(pin);
}Calling the original function from injected code is not supported — the FPB redirect applies to all callers, so it would cause infinite recursion.
| Feature | Spec |
|---|---|
| Architecture | ARMv7-M, ARMv8-M |
| Tested MCU | STM32F103C8T6 |
| Patch Slots | 6 (FPB v1) or 8 (FPB v2) |
| Patch Modes | Trampoline / Direct (ARMv7-M REMAP), DebugMonitor (ARMv8-M BKPT) |
| RTOS Support | Bare-metal, NuttX |
| Connection | Serial (USB-to-UART or USB CDC) |
CMake Build Options
| Option | Default | Description |
|---|---|---|
APP_SELECT |
1 | Application selection (3 = func_loader) |
FL_ALLOC_MODE |
STATIC | Memory allocation: STATIC or LIBC |
FPB_NO_DEBUGMON |
OFF | Disable DebugMonitor mode |
Project Structure
FPBInject/
├── Source/ # FPB driver, trampoline, DebugMonitor
├── App/
│ ├── func_loader/ # Serial protocol, memory allocator, FPB control
│ ├── inject/ # Injection helpers
│ └── tests/ # Firmware unit tests (host-based, with coverage)
├── Project/ # Platform HAL (STM32F10x, Arduino API)
├── Tools/
│ └── WebServer/ # Workbench (Flask backend + JS frontend) & CLI
└── Docs/ # Architecture, CLI reference, WebServer guide
| Document | Description |
|---|---|
| Architecture | FPB internals, patch modes, memory layout, protocol |
| CLI Reference | All CLI commands with examples and JSON output format |
| WebServer Guide | Workbench setup and usage |





