SALIOT: Galeriebeleuchtung ohne Hersteller-App steuern
Reverse Engineering der motorisierten SALIOT-Spots, damit sich ~160 Leuchten aus Code statt einzeln per Tablet-App steuern lassen.
Rolle: Analyse und Umsetzung
Über das Projekt
Die motorisierten SALIOT-Spots in den Ausstellungshallen lassen sich nur mit der Hersteller-App bedienen, eine Leuchte nach der anderen, von Hand. Bei rund 160 Leuchten ist alles, was gleichzeitig über viele davon laufen soll, so nicht möglich. Ein dokumentiertes Protokoll oder eine API zum Automatisieren gibt es nicht.
Ziel war, die Leuchten aus Code ansprechen zu können. Ausgangspunkt war einzig die Android-App.
Vorgehen
- APK zerlegen: die App von einem APK-Mirror gezogen und mit apktool + jadx aufgemacht.
- Stack identifizieren: im Package-Tree stand
com/csr/mesh: die Leuchten sprechen CSRmesh, Qualcomm/CSRs Bluetooth-Mesh-Stack, für den es Vorarbeit gibt. - Krypto herauslesen: Schlüsselableitung, Nonce und Frame-Format aus den obfuskierten Klassen rekonstruiert und byte-für-byte gegen die App verifiziert.
- Nach Python übersetzen: Payload, Verschlüsselung, Framing und der CSRmesh-Best-Effort-Versand als kompakte Python-Implementierung.
- Fehlersuche mit Instrumentierung: als die Writes stumm ignoriert wurden, ein Capture-Rig gebaut: Frida-Gadget in die App (altes Android-Telefon, ohne root), um zu sehen, was die App auf GATT-Ebene anders macht.
Ergebnis
Volle lokale Steuerung der Leuchten aus Python. Der eigentliche Fehler waren zwei vertauschte GATT-Control-Points bei älteren Leuchten. Eine Woche habe ich an der falschen Stelle gesucht, der Fix waren zwei Zeilen.
Protokoll, Code und Fallen stehen ausführlich im Blogpost.