- Die Systemsounds der Tozo-T6-Earbuds für Pairing, Verbinden und Trennen waren viel zu laut; gelöst wurde das Problem, indem die Verstärkung der Audiodateien in der Firmware direkt abgesenkt wurde
- Als Chipsatz wurde ein Modell aus der Airoha-AB1562-Familie vermutet, und mit der App AirReps156X wurde bestätigt, dass sich Diagnosedaten auslesen und potenziell modifizierte Firmware hochladen lassen
- Der Update-Check-Traffic der Tozo-App wurde mit mitmproxy abgefangen, wodurch sich aus der Antwort von
/api/v1/getOtaVersionV3die Links zu den Firmware-Binärdateien beschaffen ließen - Die Firmware bestand aus zwei FotaPackages und zwei FileSystemImages für linken und rechten Earbud; im zu modifizierenden Dateisystem-Image waren die mp3-Dateien unverändert enthalten
- Die mp3s wurden mit
mp3gainum -19.5dB abgesenkt, ohne sie neu zu encodieren oder ihre Länge zu verändern; anschließend wurden die Bytes im Image ersetzt und die Firmware geflasht, worauf das Gerät normal funktionierte und deutlich leiser wurde
Zu laute Systemsounds und erste Annahmen
- Die Tozo-T6-Earbuds spielten bei jedem Pairing, Verbinden und Trennen Töne ab, und diese waren deutlich lauter als vom Nutzer gewünscht
- Das Absenken aller Frequenzbänder im Equalizer um ein paar dB löste das Problem nicht, und eine Anfrage per E-Mail an Tozo wurde mit dem Hinweis beantwortet, dass das Unternehmen nichts tun könne
- Ziel war es, die auf dem Gerät laufende Firmware zu modifizieren, um die Lautstärke der betreffenden Sounddateien zu verringern
- Zunächst wurde mit einigen Annahmen gearbeitet
- Die Firmware-Binärdateien für das Gerät lassen sich online beschaffen
- Die Firmware könnte eine verständliche Binärstruktur wie ELF haben
- Die Audiodateien sind möglicherweise in der Firmware enthalten und können modifiziert werden, wenn Offset und Länge bekannt sind
- Das Audio könnte ein einfaches Format wie PCM sein
- Die modifizierte Firmware lässt sich mit Tools für das Gerät oder den Chipsatz flashen
- In der Praxis erwiesen sich mehrere Annahmen als falsch, und mehr Zeit als für das eigentliche Reverse Engineering floss in den Aufbau von Analyse-Infrastruktur wie Proxys und in die Suche nach Umwegen
Identifikation von Gerät und Chipsatz
- Bei günstiger Elektronik sind üblicherweise mehrere Akteure und Ebenen beteiligt
- Der Vendor, der das Produkt unter seiner Marke verkauft, ist hier Tozo
- Es gibt einen Chipsatz als zentrale Hardware, auf der die Firmware läuft
- Der Chipsatz kann eine ISA verwenden, die von Basistechnologien wie ARM oder MIPS abgeleitet ist
- Zusätzliche Coprozessoren oder Funktionen für Hardware-Schnittstellen können integriert sein
- Beim Disassemblieren der Tozo-Android-App wurden Verweise auf das Airoha SDK, konkrete Chipmodelle und grundlegende Funktionen zur Kommunikation mit dem Gerät gefunden
- Aus der Reddit-Community
/r/airrepsrund um AirPods-Klone kamen Hinweise zur weiteren Richtung, und auch die App AirReps156X wurde dort gefunden - Die App AirReps156X nutzt das Airoha SDK und konnte Diagnosedaten von Airoha-Geräten auslesen
- Nach dem Verbinden des Geräts zeigte die App den Diagnose-String
QW_1562U_SDK1.5.1, woraus geschlossen wurde, dass der Geräte-Chipsatz zur Airoha-AB1562-Serie gehört - AirReps156X bot außerdem eine Funktion zum Flashen neuer Firmware, womit eine entscheidende Voraussetzung für das Aufspielen modifizierter Firmware erfüllt war
Firmware-URL im Traffic der Tozo-App finden
- Die Tozo-App zeigte nach dem Verbinden der Earbuds die aktuelle Firmware-Version und an, ob sie auf dem neuesten Stand ist
- Da die App dafür offenbar mit dem Server kommunizierte, wurde beschlossen, die echten Firmware-Datei-URLs im Update-Check zu suchen
- Statt den dekompilierten Code vollständig statisch zu analysieren, fiel die Wahl auf dynamische Analyse, also das direkte Beobachten der Netzwerk-Anfragen
- Dafür wurde mit WLAN-NIC,
hostapdundmitmproxyein Abfang-Proxy aufgebaut - Die Tozo-APK wurde mit
apktoolunduber apk signergepatcht, damit sie das mitmproxy-TLS-Zertifikat aus dem User-CA-Store akzeptiert- Android-Apps greifen oft standardmäßig nur auf den System-CA-Store zu
- Durch das Patchen der APK konnte auch der User-CA-Store genutzt werden; danach wurde die App erneut signiert, damit sie unter Android ausführbar blieb
- Zur Proxy-Konfiguration gehörten AP-Setup, das Umleiten des 80/443-Traffics per
iptablesauf den mitmproxy-Port sowie NAT-Einstellungen - Wenn die App neben der Firmware-Version „current“ anzeigte, ging eine Anfrage an den Endpoint
/api/v1/getOtaVersionV3; in der Antwort standen die benötigten Firmware-bin-Links
Struktur und Analyse der Firmware-Dateien
- Die beschaffte Firmware bestand insgesamt aus vier Dateien
- je ein
FotaPackagefür linken und rechten Earbud - je ein
FileSystemImagefür linken und rechten Earbud
- je ein
- Die beiden Dateisystem-Images waren identisch, sodass es faktisch drei eindeutige Dateien gab: zwei FotaPackages für links und rechts sowie ein Dateisystem-Image
- Mit
file,strings,hexdumpundbinwalkwurde versucht, Format und eingebettete Dateien zu identifizieren - Im Dateisystem-Image waren einige Dateinamen-Strings sichtbar, aber
binwalkfand die erwarteten mp3-Dateien nicht - Bei mp3-Dateien fehlten klare Magic Numbers oder Footer, wodurch sich Offset und Länge in einem beliebigen Binärblob nur schwer sicher bestimmen ließen
- Der Anfang kann
0xFFFFoder0xFFFEsein - Beides ist als Dateikennung nicht eindeutig genug
- Der Anfang kann
- Daher wurde die Richtung geändert: Wenn sich die Struktur des Dateisystem-Images verstehen lässt, sollten sich auch Anfang und Ende der einzelnen Dateien ermitteln lassen
Entropieanalyse und ROFS
- Eine Entropieanalyse hilft dabei, sichtbar zu machen, welche Dateibereiche eher konstant, zufällig verrauscht oder ASCII-Text ähnlich sind und wo Übergänge dazwischen liegen
- Das Dateisystem-Image zeigte eine erkennbare Struktur, während die FotaPackage-Dateien komprimiert oder verschlüsselt wirkten
- Die FotaPackages für links und rechts unterschieden sich nur an wenigen Stellen im Header; die Hauptdaten waren fast identisch und wichen erst in den letzten etwa 7 KB vollständig voneinander ab
- Es wurde nicht abschließend geklärt, was dieser Unterschied genau bedeutete, aber aufgrund der offenbar undurchsichtigen Transformation schien ohne großen Aufwand kein sinnvoller Erkenntnisgewinn möglich
- Das Dateisystem-Image begann mit dem ASCII-String
ROFS - Öffentliche Dokumentation oder passende Formatbeschreibungen zu
ROFSließen sich nicht finden; später zeigte sich jedoch, dass das gefundene Airoha SDK eine Implementierung zum Lesen dieses Images enthielt - Zeitweise wurde ein Ansatz zur Entschlüsselung der FotaPackages verfolgt, letztlich wurde aber nur bestätigt, dass das SDK die Firmware vor dem Senden nicht transformiert; weiter führte das nicht
mp3 leiser machen, ohne neu zu encodieren
- Dass es sich bei den Dateien um mp3 handelte, war anfangs ein Risikofaktor
- mp3-Encoder haben viele Optionen, und ein unbekannter Decoder könnte bestimmte formal gültige Dateien womöglich nicht korrekt verarbeiten
- Wenn ausgerechnet das Audio direkt nach dem Verbinden Probleme verursachte, könnte das Gerät abstürzen, bevor eine erneute Verbindung zur Wiederherstellung möglich wäre
- Durch ein Re-Encoding der mp3-Dateien hätte sich ihre Länge ändern können, was möglicherweise auch präzise Anpassungen der Längenangaben im Dateisystem-Image erfordert hätte
- Glücklicherweise ließ sich bei mp3 die Verstärkung anpassen, ohne neu zu encodieren, die Länge zu ändern oder Metadaten zu verändern
- Das ähnelt eher dem verlustfreien Drehen einer JPEG-Datei ohne Re-Encoding: Es werden nur Teile der internen Datenstruktur angepasst
Der entscheidende Hinweis aus dem SDK
- Durch die Suche nach dem Chipsatznamen wurde eine Kopie des Airoha SDK gefunden, in der dieselben
.mp3-Dateien enthalten waren, die auf dem Gerät zu hören sind - Ein einfaches Python-Programm
bincontains.pywurde geschrieben, um zu prüfen, welche Dateien unverändert in einer anderen Binärdatei enthalten sind - Damit ließ sich verifizieren, dass die mp3-Dateien aus dem SDK bytegenau unverändert im Dateisystem-Image enthalten waren
- Sie waren nicht komprimiert
- Sie waren nicht in Blöcke aufgeteilt
- Dadurch ließen sich Offset und Länge im Image bestimmen
- Ein kurzer Blick in den SDK-Code rund um ROFS zeigte keine Symbole, die stark auf Checksummen hindeuteten
- Ab diesem Punkt waren die Voraussetzungen für die Modifikation ohne weiteres Reverse Engineering gegeben
- Die Firmware-Dateien und eine Flash-Methode waren vorhanden
- Position und Länge der mp3-Dateien im Image waren bekannt
- Die mp3-Verstärkung ließ sich ohne Längenänderung anpassen
- Es wurde angenommen, dass der Austausch des betreffenden Bytebereichs die Dateisystem-Metadaten nicht beschädigt
Modifikation und Flashen des Dateisystem-Images
- Ein Bash-Skript lief die mp3-Dateien aus dem SDK durch und suchte die jeweils enthaltene Datei im Dateisystem-Image
- Die eingebettete mp3 wurde in eine temporäre Datei kopiert und dann mit
mp3gainleiser gemacht - Verwendet wurde ein Anpassungswert von -19.5dB
- Anschließend wurde geprüft, ob die Größe der modifizierten mp3 mit der des Originals übereinstimmt; dann wurden die Bytes mit
ddan den entsprechenden Offset im Dateisystem-Image zurückgeschrieben - Ein binärer Diff des finalen Firmware-Images zeigte wie erwartet nur Änderungen an wenigen Bytes
- Die modifizierte Firmware wurde auf das Gerät geflasht; das Gerät funktionierte normal und die Systemsounds waren deutlich leiser als zuvor
Ergebnis und Grenzen
- Es war nicht nötig, die Firmware-Verschlüsselung zu brechen oder das
ROFS-Dateisystemformat vollständig zu verstehen - Tatsächlich floss viel Reverse-Engineering-Zeit in Umwege, die für die endgültige Lösung gar nicht direkt erforderlich waren
- Wäre die Lautstärkeregelung für Systemsounds eine normale Gerätefunktion gewesen, wäre diese Modifikation nicht nötig gewesen
- Bei Geräten, die Audio abspielen, wäre eine Lautstärkeregelung auf UI-Ebene für sämtliche vom Gerät erzeugten Töne die sinnvollere Lösung
- In diesem Fall reichte jedoch ein pragmatischer Workaround aus, indem lediglich die Verstärkung der mp3-Dateien innerhalb des Firmware-Images abgesenkt wurde
1 Kommentare
Meinungen auf Hacker News
Ich wünschte, jemand würde meine Bluetooth-Schlafmaske auch so reparieren.
Insgesamt ist sie ziemlich gut, aber wenn der Akku fast leer ist oder sie sich ausschalten will, teilt sie einem das bei maximaler Lautstärke mit.
Bei einer Schlafmaske.
Ich hatte mal einen ähnlich fehlerhaften Wecker mit MSF-Funkzeitsynchronisierung.
Aber jedes Mal, wenn er sich wieder mit dem MSF-Zeitsignal synchronisierte, gab er 2–3 Sekunden lang denselben Ton wie der Alarm von sich, und man konnte das nicht abschalten.
Das passierte immer zu einer furchtbaren Zeit, etwa um 3 Uhr morgens, also habe ich ihn schließlich geöffnet, die MSF-Antenne abgetrennt und schlafe seitdem besser, obwohl ich weiß, dass die Uhr immer ein bisschen falsch geht.
Währenddessen versuche ich aufzuholen, was die Person am anderen Ende des Anrufs in den paar Sekunden gesagt hat, schaffe es aber nicht wirklich.
Diese Benachrichtigung ist viel schlimmer als gar nichts. Ohne Warnung wäre der schlimmste Fall, dass der Ton abbricht und ich die andere Person verpasse; der Ohrclip erzeugt genau diesen Effekt absichtlich, nur nach einem vorgezogenen Zeitplan.
Es gibt keinen Grund, warum man das nicht als unaufdringliches Piepton-Muster in den bestehenden Audiostream mischen könnte. Das würde nicht einmal eine Sekunde dauern und nicht selbst das Problem erzeugen, das es verhindern soll.
Ein weiteres kaum vorstellbar schlechtes Bluetooth-Verhalten ist, dass bei der Nutzung von Voice-Chat das normale Computer-Audio komplett verschwindet. Wenn der Voice-Chat den Mikrofoneingang nutzt, wechselt das Bluetooth-Gerät in den „Headset“-Modus; dieser Modus macht aus Stereo Mono und wird zur einzigen erlaubten Ausgabe, solange Audioeingabe bereitgestellt wird oder bereitgestellt werden könnte.
Apps, die keine Audioeingabe verwenden, versuchen weiter, auf ein Bluetooth-Kopfhörergerät abzuspielen, das nicht mehr existiert, und können deshalb keinen Ton mehr ausgeben.
Ich verstehe nicht, warum es mehrere Gerätemodi geben muss. Ich sehe keinen Grund, warum ich als Nebeneffekt davon, mit meiner Familie zu sprechen, Funktionen verlieren sollte. Ich verstehe nicht, was so schwierig daran sein soll, gleichzeitig unterschiedliche Audiosignale auf beiden Ohren wiederzugeben, nur weil das Mikrofon möglicherweise eingeschaltet wird. Nicht-Bluetooth-Geräte bekommen das hin, und es gilt nicht einmal als bemerkenswerte Funktion. Warum sollte „die Kopfhörer schalten sich nicht aus, während man das Mikrofon benutzt“ etwas Besonderes sein?
Stark! Respekt an den ursprünglichen Autor, dass er das bis zum Ende durchgezogen hat.
Wo wir gerade bei lauten Earbuds sind: Ich habe vielleicht das gegenteilige Problem. Auf dem Laufband nutze ich Bose-Sport-Earbuds auf einer Lautstärke, die ich für angenehm und konservativ halte, aber mein iPhone warnt mich, dass die Lautstärke zu hoch sei und mein Gehör schädige.
Hat das Handy recht? Falls ja, bin ich bereit, der Ohrgesundheit zuliebe etwas Genuss zu opfern. Aber es gibt auch eine plausible andere Hypothese: Diese Earbuds sind bei derselben Lautstärkeeinstellung physisch deutlich leiser als andere Produkte, die ich ausprobiert habe, sodass Apples träges Modellieren falsche Warnungen wie die bei mir erzeugen könnte.
Wenn Apple eine Datenbank erstellt hätte, die Produktmodell und Lautstärkeeinstellung auf die tatsächliche physische Lautstärke abbildet, würde ich das loben. Aber in der Warnung und der Funktionsbeschreibung fehlen jegliche Details, daher traue ich dem nicht, und ich möchte mein Training nicht schlechter machen, nur weil Apple ein Modell auf Uni-Hausaufgaben-Niveau in ein echtes Produkt gesteckt hat.
Weiß jemand, ob die Data Science hinter dieser Warnung solide ist?
Erstens ist unter iOS die minimale Lautstärke meiner Bluetooth-Earbuds zu hoch. Das war bei allen Drittanbieter-Kopfhörern so, die ich ausprobiert habe, und online beschweren sich Leute seit zehn Jahren darüber. Die EU hat sogar ein Gesetz verabschiedet, das eine Behebung verlangt, aber Spoiler: Es hat nichts gebracht.
Bitte, die minimale Lautstärke in der UI sollte auf den Hardware-Lautstärke-Integer 1 abgebildet werden.
Zweitens können Drittanbieter-Apps keine Musik oder Podcasts im Bluetooth-Mediennavigationsmenü des Autos anzeigen. Unter Android geht das.
Deshalb kann ich unter Android mit dem Jogwheel des Autos Podcasts hören und Tidal streamen, unter iOS aber nicht.
Ich habe noch weitere Bluetooth-Beschwerden. Warum setzt meine Apple Watch das Autoradio auf eine Blacklist? Bluetooth in iOS-Version N und N-1 ist wirklich sehr buggy.
Das ist einfach eine offensichtlich dumme Funktion. Wenn ich es nur rooten könnte, könnte ich irgendwo in einer Konfigurationsdatei diesen Schalter umlegen, aber auf dem Samsung Galaxy J1 (2016) ist mir das nie gelungen.
Meine Bose verhalten sich je nach Bluetooth-Chipsatz auch unterschiedlich. Unter Linux muss ich die Lautstärke auf 150 % stellen, um überhaupt etwas vernünftig zu hören.
Aber es gibt keinen Grund zu glauben, dass sie so etwas getan haben. Interessant wäre es, wenn Kopfhörerhersteller beim Bluetooth-Verbindungsaufbau den dB-Bereich melden würden und so eine Funktion möglich machten, aber davon habe ich noch nie gehört. Anders als bei 3,5-mm-Klinke wäre Bluetooth allerdings ein Bereich, in dem so etwas prinzipiell möglich wäre.
Mit Noise Cancelling kann man die Lautstärke unter 20 % halten und trotzdem angenehm hören, ohne die Ohren zu strapazieren.
In meinem Fall bekam ich vor ein paar Jahren nach langen Workouts Ohrenschmerzen, deshalb denke ich, dass die Apple-Warnungen wahrscheinlich recht hatten. Seit ich Noise Cancelling nutze, ist das komplett verschwunden.
Solche Arbeiten finde ich wirklich großartig. Plötzlich wirkt dieses In-Ear-Modell ziemlich interessant.
Nebenbei: Die Systemtöne von Bluetooth-Geräten sind einer der Faktoren, die Produkte am stärksten voneinander unterscheiden. Manche sind einfach furchtbar: https://youtu.be/J2wPsH64JEM
Allerdings habe ich noch nie gesehen, dass Reviews oder Produktseiten verraten, wie ein Produkt klingt. Obwohl man diese Töne mehrmals am Tag hören muss und sie sich nicht abschalten lassen.
Allein die Möglichkeit, diese Töne zu ändern, wäre vermutlich schon eine ziemlich einfache Differenzierung.
Mit Ohrstöpseln in einer lauten Werkstatt ist er perfekt, aber wenn ich in einem ruhigen Büro Musik leise im Hintergrund laufen lasse, um mich zu konzentrieren, ist er unangenehm und erschreckt mich.
Ich verstehe nicht, warum Systemtöne sich nicht nach der Lautstärkeeinstellung richten.
Es wäre schön, wenn das Handy erkennen könnte, ob das verbundene Headset ein Lautsprecherset, In-Ear-Monitore, Knochenschallkopfhörer usw. ist.
Wenn ich ein normales Lautsprecherset nutze und es absichtlich laut aufdrehen will, damit man es überall im Haus hört, nervt die Warnung „Lautstärke zu hoch“.
Bei Knochenschallkopfhörern ist es doppelt nervig, weil man eine ziemlich hohe Lautstärke braucht, um gut zu hören.
Gut, dass das hier ein Airoha-Ziel ohne Firmware-Verschlüsselung ist.
Falls es interessiert: Es gibt auch ein 010-Editor-Template für das Firmware-Format.
https://github.com/ramikg/airoha-firmware-parser
Respekt vor den Fähigkeiten, aber es ist schade, dass für etwas so Grundlegendes wie das leichte Ändern der Wiedergabelautstärke einer Datei so viel Aufwand nötig ist.
Es sollte nicht so viel Mühe erfordern, ein Werkzeug dazu zu bringen, sich so zu verhalten, wie man es möchte.
Das ist nicht „verständlich“. Man hat für das Produkt bezahlt, und das ist ein Produktproblem, das behoben werden sollte.
Nachdem ich diesen Artikel gelesen hatte, habe ich gebrauchte Tozo T6 gekauft. Äußerlich schienen sie ziemlich neu produziert zu sein, aber ich konnte es nicht reproduzieren.
Die offizielle Tozo-App hat das Headset nicht einmal erkannt, und ich konnte auch nicht bestätigen, ob ein Airoha-Chipsatz verwendet wird, was sich an AAC-Unterstützung erkennen ließe. Meine unterstützen nur SBC.
Entweder habe ich Fälschungen gekauft, oder es gab nach dem Kauf des Autors interne Änderungen.
Einige Audiodateien klingen wie die aus einem im Internet verfügbaren, unvollständigen Airoha-SDK, aber sie spielen auch andere neue Sprachdateien ab.
Wenn man dieses Ergebnis unabhängig verifizieren oder damit herumspielen möchte, könnten Fake-AirPods der bessere Weg sein.
Ich wünschte, mehr Leute würden sich über laute und schlechte Systemtöne beschweren.
Meine Sony WH-1000XM4 haben genau dasselbe Problem, aber Sony scheint die Firmware-Payloads zu verschlüsseln und auf dem Gerät zu entschlüsseln.
Ich war kurz davor, sie fast komplett zu zerlegen, alles zu dumpen und zu untersuchen, aber meine Hände zittern, und die Wahrscheinlichkeit, sie dabei kaputtzumachen, ist zu hoch.
Für ein hackbares Noise-Cancelling-Headset wäre ich bereit, ziemlich viel Geld zu zahlen.