Wnętrze wielkiego telewizora UE55MU6452U, analiza, dekodowanie i symulacja flash za środka
TL;DR
- Rozebrano telewizor Samsung UE55MU6452U 55” 4K UHD Smart TV i przeanalizowano jego zasilacz, płytę główną oraz trzy pamięci Flash, w tym układ T-Con.
- Kluczową techniką było 32-bitowe odwrócenie kolejności bajtów, dekodowanie napisów w Ghidra ARM:LE:32:Cortex oraz emulacja firmware w Capstone i Unicorn.
- W pamięci T-Con znaleziono komunikaty dla aeabi Cortex-M0, UART_RDY, datę 20170825_0922 i wsparcie dla układów w25x10, w25q80 oraz gd25q32c.
- Emulator PoC przechwycił 237 bajtów boot logu, ujawniając m.in. "Warm Booting!!!!!", "60Hz USIT Mode" i poprawną inicjalizację peryferiów.
- Druga kość Flash przy CPU wygląda na firmware inicjalizacyjne, ale nie BIOS, a trzeciej kości na matrycy nie udało się zachować ani zbadać.
Wygenerowane przez model językowy.
Zastanawialiście się kiedyś, co siedzi w pamięci Flash ze współczesnego telewizora? Zapraszam na krótką prezentację wnętrza telewizora Samsung UE55MU6452U 55” 4K UHD Smart TV połączoną z inżynierią wsteczną i emulacją firmware kontrolera T-Con. Pokażę tutaj, jak zbudowany jest taki telewizor, jak zrealizowane jest jego podświetlenie i jakie elementy można odzyskać ze środka. Na koniec spróbuję też zgrać zawartość pamięci Flash ze środka, odpowiednią ją zdekodować, określić jej architekturę, adresy UART i odpalić ją w prostym emulatorze.
Demontaż i podświetlenie
Demontaż zacząłem od samego ekranu. W telewizorach LCD obraz generowany jest przez matrycę ciekłokrystaliczną, natomiast podświetlenie stanowi osobny moduł znajdujący się za nią. Kiedyś realizowane było ono w oparciu o świetlówki CCFL, teraz mamy telewizory LEDowe. Pasek LED jest tylko na dolnej krawędzi tego egzemplarza, ale ich światło przechodzi przez kilka warstw dyfuzorów i folii rozpraszających, które równomiernie oświetlają całą powierzchnię panelu.
Po zdjęciu tylnej pokrywy można zobaczyć dwa główne moduły telewizora - zasilacz i płytę główną. Są też oczywiście głośniki.
Zasilacz L55E6R_KHS
Zasilacz zbudowany jest zasadniczo z dwóch modułów. Mamy tu osobno zasilanie dla płyty głównej, w tym przypadku 12.8 V przy prądzie nieco ponad 5 A, i osobno mamy stałoprądowy zasilacz dla podświetlenia LED, w zależności od wersji może to być 198 V 370 mA przy 300 Hz.
Tego typu zasilacze to zazwyczaj płytki jednostronne. Część komponentów, zwłaszcza te większe, jest montowana przewlekanie, a część, w tym układy scalone, są w technologii SMT. Co ciekawe, transformatory impulsowe oraz kondensator na 400 V zostały specjalnie zamontowane w wycięciach PCB, tak aby zmniejszyć jej wysokość.
Z komponentów mamy tu tranzystory MOSFET 10N60M2, 60S380CE i ultraszybkie diody U10A6C1.
Płyta główna
Płyta główna jest zrealizowana w oparciu o montaż powierzchniowo. PCB jest dwustronne, ale elementy są tylko z wierzchu. Mamy tu zasadniczo mały komputer, wraz z procesorem, pamięciami, sekcją przetwornic i wejść/wyjść.
Głośnikami steruje wzmacniacz audio klasy D TAS5749M:
Po zdjęciu radiatora:
Elementy takie jak CPU, pamięć RAM i Flash montowane są już w technologii BGA (Ball Grid Array). Zapewnia to większą gęstość upakowania połączeń, lepsze właściwości elektryczne oraz bardziej kompaktową konstrukcję układu, jednocześnie niestety utrudniając ręczną naprawę i lutowanie tych komponentów.
Po wyczyszczeniu pasty można zidentyfikować CPU - SDP1601 ver. 05:
Nie znalazłem o nim informacji w sieci, za wyjątkiem strony wikimedia z galerią z dość podobnego telewizora:
https://commons.wikimedia.org/wiki/File:Samsu...E40MU6409U_-_board_-_Samsung_SDP1601-5286.jpg
Pamięć Flash od T-Con?
T-Con (Timing Controller) to kontroler sterujący matrycą LCD, odpowiedzialny m.in. za generowanie sygnałów sterujących dla pikseli. Pierwsza kość 25Q80DVSIG znajduje się na skraju PCB. Jej linia SPI prowadzi do padów od brakującego złącza.
Entropia danych jest dość wysoka, ale tylko do offsetu 0x19000. Dalej pamięć jest pusta.
Tu już znalazłem ciekawe sekcje, które wyglądają na napisy, ale w jakimś dziwnym języku. A może coś jest poprzestawiane?
Szybka analiza literek pokazuje, że mamy zmienioną kolejność bajtów. Przykłady potwierdzające mój pomysł dałem do tabelki:
| Surowe (jak w pliku) | Dekodowane (32-bit byte-swap) | locnIcerrhc tskce | Incorrect checksum | oB dnito!! g | Booting!! | CIMPATS_ER_TT_DA_EPYS | SYS_TYPE_AD_TT_RE_STAM PIC | NOCTamI I eg ofns% | TCON Image Info sd% |
Zrobiłem program do przerzucenia wszystkich bajtów:
Kod: Python
W napisach znalazłem informacje o procesorze - aeabi Cortex-M0. Dodatkowo jest dużo komunikatów o błędach, o pamięci Flash oraz o T-Con:
0x00884F: Current Task ID : %d, BaseSP:0x%08x, SP:0x%08x, Name:%s
0x008889: [Task %02d] BaseSP:0x%08x, SP:0x%08x,StkSize:Assert Remain:[%06d][%06d], ID:%02d, Name:%s
0x0088E4: -----------------------------------------------------------
0x008921: Oops!!! HardFault_Handler
0x00893C: TIME : Preempt : %d us, OneCmd Op :%d us
0x00899A: OutPut Hz :
0x0089A7: 60 Hz
0x0089AF: 120 Hz
0x0089B8: idle
0x0089BD: user_debug
0x0089C8: usr_boot_main
0x0089D6: Enter Multi Tasking
0x0089EB: UART RDY
0x0089F5: TIMESTAMP : %s
0x008A05: 20170825_0922
0x008A13: I2C M Init
0x008A1F: sf_wp_check
0x008A2C: MEMIF_CMD_SRAM_REFLASH
0x008A44: Current Version : 0x%02X
0x008A5E: Release Date : 0x%06X
0x00AFDC: ----------FGT Status Information---------
0x00B007: init_skip : 0x%04x
0x00B01B: fw_model : 0x%04x
0x00B02E: test_mode : 0x%04x
0x00B042: chip_ids : 0x%04x
0x00B055: chip_corner : 0x%04x
0x00B06B: chip_revision : 0x%04x
0x00B083: booting_done : 0x%04x
0x00B19C: Source Address : 0x%08x
0x00B1B5: Err Size:0x%x
0x00B1C4: Header CRC : 0x%x, Result CRC Val:0x%x
Wygląda też, jakby była tam jakaś linia komend:
0x00B40D: Input 1. Register, 2. Print list, 3. Select Remove Register, 4. All Remove Register, 5. Trace Start, 99.Exit :
0x00B47E: Full!!!
0x00B487: Register Address[%d] :
0x00B49F: [%02d] Addr:0x%08x, Val:0x%08x
0x00B4BF: Remove Line :
0x00B4CE: Select [ 1.Debug Buffer Mode] or[ 2. Print Mode] ??? :
0x00B506: Stop!!!
0x00B50F: [%08d]Temperature : %d'C
0x00B529: [Test] 1: Trace OneCommand Toggle
0x00B54C: [Test] 2: UART ReInit
0x00B563: [Test] 3: Access Address
0x00B57D: [Test] 4: Trace Address
0x00B596: [Test] 5: manual onecmd
0x00B5AF: [Test] 6: DBG Buffer Mode
0x00B5CA: [Test] 7: Force Booting Done
0x00B5E8: [Test] 8: OSD Image
0x00B5FD: [Test] 9: DDR RW Limit Check
0x00B61B: [Test] 10: IDLE Task Monitoring On/Off
0x00B643: [Test] 11: SPI Flash RW Limit Check
0x00B668: [Test] 15: 3DC 60
0x00B67B: [Test] 17: TCON CRC
0x00B691: [Test] 18: EW DDR Test
0x00B6AA: [Test] 19: Temperature Test
0x00B6C8: [Test] 98 : FT Status Info
0x00B6E4: [Test] 99 : Exit
0x00B6F6: [Test] Input :
Wspierane są różne typy Flash:
0x00B730: w25x10
0x00B768: w25x20
0x00B7A0: w25x40
0x00B7D8: w25x80
0x00B810: w25q80
0x00B848: w25x16
0x00B880: w25q16
0x00B8B8: w25x32
0x00B8F0: w25q32
0x00B928: w25x64
0x00B960: w25q64
0x00B998: w25q32
0x00B9D0: w25q64
0x00BA08: gd25q32c
0x00BA40: gd25q32c
0x00BB94: SF[%d]:%s, JEDEC ID : 0x%x,
0x00BBB1: Quad Mode
0x00BBBC: Single Mode
0x00BBC9: SF[%d]: No Exist : 0x%08x
Czym jest Demura? Demura to technika kalibracji matrycy LCD polegająca na kompensacji nierównomierności jasności i kolorów pomiędzy poszczególnymi pikselami. Dane korekcyjne przechowywane są zazwyczaj w postaci tablic LUT.
0x014DF6: Fail / Retry
0x014E04: TCON Demura Register Data Uploading
0x014E29: fail - Incorrect checksum / Read : 0x%X / Calc : 0x%X
0x014E60: TCON Demura LUT Data Uploading
0x014E80: fail - Incorrect checksum / Read : 0x%x / Calc : 0x%x
0x014EB7: ACC FCnt Init
0x014EC6: Demura bypass
0x014ED5: No Demura Image
0x014EE7: Write Fcnt ISR Routine
0x014EFF: M49B6U0Fxx
LUT? Lookup table? Ale czym jest SDC? Chodzi o mapowanie kolorów?
0x015201: 120Hz Vx1 Mode
0x015211: TCON RDY
0x01521B: Tcon Init(us): %d
0x01522E: DCC/VCC/VA Init(us): %d
0x015247: ACC
0x01524C: ACC Init(us): %d
0x01525E: SDC Post LUT Uploading
0x015278: SDC Post LUT Uploading fail
0x015294: SDC Pre LUT Uploading
0x0152AD: SDC Pre LUT no.%d Uploading fail
0x0152CE: SDC IP Init(us): %d
0x0152E3: accept from FRC
0x0152F4: Demura Init(us): %d
Pamięć Flash od T-Con - część 2 - analiza i określenie rejestrów UART
Wczytałem Flash do Ghidra, użyłem ustawień ARM:LE:32:Cortex. Instrukcje i funkcje są poprawnie dekodowane.
Szybko można znaleźć tam odniesienia do napisów, przykładowo do UART_RDY, na zrzucie ekranu poniżej mamy instrukcję ldr która ładuje wskaźnik do tego napisu, tuż po tym wywoływana jest funkcja 74f8. Ciekawe co ona może z tym napisem robić...
Pierwszy rzut oka jeszcze tego nie wyjaśnia, ale nie poddawajmy się:
Jedna z podfunkcji wygląda jak iteracja napisu zakończonego zerowym bajtem:
Każdy znak jest przetwarzany przez kolejną procedurę, która najpierw zdaje się czekać w pętli aż UART będzie wolny, a potem wysyła jeden bajt:
FUN_00004d60 tylko bada zapalanie trzeciego bitu na wartości o adresie DAT_00004d6c. Flaga ready? Natomiast coś zapisuje do wartości z DAT_00004de0... ale DAT_00004de0 to wskaźnik, co jest tam w pamięci?
Tam jest adres rejestru UART_TX_DATA, czyli 0x009D0E20! To ten rejestr wysyła dalej znaki. Analogicznie, można określić pozostałe rejestry:
- 0x009D0E00 = UART_CTRL (on/off, wartość 0x3)
- 0x009D0E04 = UART_BAUD (baud, wartość 0x3085)
- 0x009D0E10 = UART_STATUS (bit 2 = TX gotowe)
- 0x009D0E20 = UART_TX_DATA (bajt do wysłania)
- 0x009D0E28 = UART_FIFO_CFG (głębokość FIFO 0x50?)
Poprawność tego dopiero można zweryfikować.
Pamięć Flash od T-Con - część 3 - emulacja
Na koniec przygotowałem prosty emulator PoC (Proof of concept) w deassemblerze Capstone i emulatorze Unicorn w języku Python. Dodatkowo całość emuluje podstawowe peryferia i ma poprawki niektórych instrukcji. Przechwyciłem operacje na wyodrębnionych rejestrach UART. Rezultatem jest następujący boot log:
Captured output (237 bytes):
────────────────────────────────────────────────────────────
UART RDY
TIMESTAMP : 20170825_0922
#I2C M Init
.SF[0]: No Exist : 0x00000000
KTCON Image Info : M55A6U1F20
hTCON Register LUT uploading done
Warm Booting !!!!!
USIT En!
60Hz USIT Mode
USIT Phy 0 Init done
USIT Phy 1 Init done
PMIC Write
────────────────────────────────────────────────────────────
Potwierdza to identyfikację rejestrów i daje nadzieję na to, że po samodzielnej kompilacji firmware bylibyśmy w stanie też wyświetlać tekst.
Pamięć Flash przy CPU
Druga znaleziona pamięć Flash znajduje się tuż przy CPU. Jej oznaczenie to 25Q40CLSIP, z czego można wywnioskować jej rozmiar: 512 KB. Obstawiałem, że tu tak jak na komputerze, siedzi jakiś BIOS.
Odlutowałem i zgrałem ją za pomocą CH341:
Zacząłem od analizy entropii. Entropia to miara nieuporządkowania danych - im wyższa, tym bardziej losowe są bity w pamięci. W kontekście pamięci Flash pozwala szybko ocenić, które fragmenty są uporządkowane, a które zawierają losowe lub skompresowane dane.
Tu też napisy są przestawione:
Szybko można znaleźć ciekawe identyfikatory. Data kompilacji:
Image Info: Ver: %04 Build Date: %s[%s] - e
Date: Sep 25, 2017 Time: 6:07:12
Magistrala I2C:
I2C CHAN%d: FIFO CTR=0x%08x, DBG=0x%08x, DATA=0x%08x, STA=0x%08x
I2C CHAN%d: CORE CON=0x%03x, STAT=0x%02x, ADDR=0x%02x, DS=0x%02x, CONE=0x%02x
I2C CHAN%d: INTR PEND=0x%02x, MAS ENK(=0x%02x)
I2C CHAN%d: P%d.SCL(%d) direction=%s, len=, level=
I2C CHAN%d: P%d.SDA(%d) direction=%s, len=, level=
Kontroler CEC HDMI (Consumer Electronics Control):
RX_ERROR Pend 0! a:
RX_ERROR FIFO Flush O Fl timeout!
RX_NACK Pend 0! a:
RX_NACK FIFO Flush O Fl timeout!
CEC CHANGE: %dLine%d(P)%d.direction=%level, s
Komunikaty ADC:
ASR: ADC%d not EOC pending%d
A!: ADC%d not interrupt pending! 0x%x%s
[%ums]: ADC%ld %ums Timeout! EOC(0x%08x, INT 0x%08x) %s
AD: value C0 0x%
ADC value 1 0x%0
ADC2 value 0 0x%08xS: %s
MiCom - komunikacja z mikrokontrolerem?
MiCom ON Assign not ready already own . 0x
ResetMasterWait: %s timeout! wait count %unt %is
od: as already assigned not AON Mic . om 0x%x%s
ow: gen timeout %l(t)suu 0x!
Tu też wszystko się ładnie wczytuje do Ghidra po wybraniu trybu ARM Cortex, kolejność bajtów Little Endian. Wcześniej też odwracam słowa tak by napisy wyglądały poprawnie:
Ważniejsze funkcje się wręcz rzucają w oczy. Spójrzmy chociażby na ten losowo wybrany fragment kodu - czym jest FUN_00010068?
To pewnie wyświetlanie komunikatów o błędach, argumentem jest napis z pamięci Flash:
Trzecia pamięć Flash
Na koniec jeszcze mała ciekawostka - na samej matrycy też była kość pamięci, jednak nie zachowałem jej po demontażu i nie zbadałem jej zawartości. Muszę to zrobić przy kolejnym telewizorze:
Podsumowanie
Co za niespodzianka, to miała być prezentacja wnętrza telewizora, a po drodze zmieniła się w próby inżynierii wstecznej pamięci Flash od TCON. W podobny sposób też udało się nieco zdekodować drugą pamięć, tą z okolic CPU. Obie charakteryzowały się odwróceniem bajtów w słowach, co widać było po rozmaitych pozostawionych komunikatach. Po wykonaniu prostego 32-bitowego byte-swapa napisy w pamięci zaczęły układać się w zrozumiałe teksty, co znacznie ułatwiło analizę firmware. Dzięki temu udało się ustalić, że kontroler T-Con korzysta z procesora ARM Cortex-M0 oraz zidentyfikować fragmenty systemu wielozadaniowego i obsługę UART. Analiza kodu pozwoliła też określić adresy rejestrów UART, co umożliwiło stworzenie prostego emulatora Proof-of-Concept, który potrafi przechwycić log startowy firmware. Drugiej pamięci Flash, tej przy CPU, poświęciłem nieco mniej czasu, ale wygląda ona na niewielki firmware inicjalizacyjny. W jej zawartości można znaleźć obsługę różnych peryferiów, takich jak I2C, HDMI-CEC czy ADC, a także komunikację z dodatkowym mikrokontrolerem. To jednak nie BIOS.
Ostatecznie okazuje się, że nawet pojedyncze moduły telewizora mają własne mikrokontrolery i firmware, które można analizować podobnie jak inne systemy embedded. Już prosta analiza binarki potrafi ujawnić sporo informacji o działaniu całego urządzenia.
Rezultaty są dość zachęcające i dają poniekąd nadzieję, na skompilowanie i uruchomienie własnego programu na tego typu układy. Na początek wystarczyłby nawet prosty klasyk migający diodą LED, choć analiza UART daje również nadzieję na wyświetlanie własnych komunikatów. Być może podejmę też i takiej próby, choć przyznam, że muszę najpierw znaleźć płytkę, gdzie działa klips od CH341, albo znaleźć sposób programowania bez wylutu pamięci, bo jednak wielokrotne przelutowywanie układów nieco zwiększa czasochłonność takiej zabawy.
Nie wiem, na ile podziałam jeszcze w kontekście tej konkretnej płyty, ale mam już w zapasie kilka innych, kompletnych i sprawnych, z telewizorów-rozbitków i tam też określiłem, że jest pole do eksperymentów.
Czy uda się zamienić telewizor w Arduino? Przekonamy się wkrótce!
Komentarze
Na jakim układzie jest głowica tj. moduł RF? Widać go na jednym ze zdjęć? [Czytaj dalej]