Newer Bambu firmware refuses any LAN print command that isn't RSA-signed with a per-installation key held only by Bambu's phone app — a key that's guarded by Promon SHIELD whitebox crypto, the Android KeyStore, and encrypted storage, and has never leaked. beambam recovers it anyway, without breaking any of that. The app signs in pure Dart, so its prime factors sit in the heap as plaintext 128-byte little-endian integers. beambam reads the public modulus from the app's certificate and scans RAM for a 128-byte window that evenly divides it — any 1024-bit divisor of a 2048-bit modulus is a prime factor, and one factor reconstructs the whole private key. "Break RSA" becomes "find the right 128 bytes." The recovered key re-signs captured traffic bit-for-bit and pauses and resumes a live print for real.
That was the unlock. The rest of the repo is a full replacement for Bambu's
closed cloud+plugin stack: a pure-Python signed-MQTT client, and a from-scratch
reimplementation of the proprietary libbambu_networking.so — all ~60 ABI symbols
BambuStudio expects — so the real BambuStudio GUI, patched to build and run on an
aarch64 Android phone under Termux, drives printers through beambam's bridge with no
cloud login and no Developer Mode. On top sits a six-surface daemon: REST + SSE +
Prometheus, Home Assistant MQTT auto-discovery, sub-100ms WebRTC chamber camera, an
MCP server for Claude/Cursor, and a mobile web UI with a multi-printer queue and
type-vs-color AMS filament matching.
Along the way it documents a months-long reverse-engineering campaign done in the open: mapping the printer's five-stage signature-verification ladder by feeding it broken inputs, a surgically string-patched frida-server and a zero-footprint Zygisk SSL hook to get past SHIELD's tamper-detection, HPACK-decoding captured HTTP/2 to find the MakerWorld download API, and proving that its rate-limit wall is a GeeTest robot-score gate rather than a header trick. It even ships a cron canary that warns the day Bambu rotates the cert that every open LAN client depends on.
// Technical highlights
- Recovers a 2048-bit RSA signing key by heap-scanning for a 128-byte window that divides the public modulus — no factoring, no crypto hooking; validated bit-for-bit and against a live print (
runtime/handy_extract/extract_signing_key.py:71-121). - numpy pre-filter (odd LSB + top-bit-set) makes a ~140 MB heap scan resolve in seconds per region;
dd conv=noerror,syncsurvives Dart's uncommitted pages (extract_signing_key.py:71-83). - Clean-room reimplementation of the closed
libbambu_networking.so— ~60bambu_network_*ABI symbols marshalled to a Python bridge over a JSON Unix-socket protocol (runtime/network_shim/src/exports.cpp,PROTOCOL.md). - ~60-patch aarch64/Termux port of BambuStudio v02.06.00.51 with LD_PRELOAD GTK/EGL/locale shims (
patches/,runtime/preload_*.c). - Reverse-engineered the printer's staged verify ladder — 4 distinct err-codes behind one "verify failed" string — and disproved any self-cert shortcut (
beambam/mqtt_sign.py,DART_HEAP_KEY_EXTRACTION.md). - Six network surfaces off one state hub: ~38 REST/SSE routes, Prometheus, HA MQTT auto-discovery, aiortc WebRTC (<100ms), and a 21-tool MCP server (
beambam/serve_http.py,runtime/{ha,webrtc,mcp}/).