Русский
Русский
English
Статистика
Реклама

Перевод NANDкромантия трансплантация флэш-памяти наживую


Нередко при анализе встроенной системы происходят преднамеренные, а иногда и нет, изменения, которые приводят к тому, что целевая система выходит из строя и впадает в так называемое состояние кирпича. В некоторых случаях для ее реанимации достаточно выполнить сброс к заводским настройкам, в иных же приходится прошивать систему при помощи интерфейса отладки (JTAG/SWD/*) или вручную через внешнее устройство памяти (SPI/NOR/Nand/eMMC). В данной статье мы рассмотрим весьма креативный метод раскирпичивания системы после подобного сбоя.

Как-то в свободное время я возился с памятью маршрутизатора, где в качестве загрузчика использовалась прошивка CFE (Common Software Environment). В ходе моего взаимодействия с CFE в попытке определить аргументы, передаваемые при загрузке в ОС устройства, конфигурация системы была случайно повреждена:

CFE> bPress:  <enter> to use current value        '-' to go previous parameter        '.' to clear the current value        'x' to exit this command94908AC5300R               ------ 0394906REF                   ------ 07GT-AC2900                  ------ 08Board Id                          :  8  X     <---- whoopsNumber of MAC Addresses (1-64)    :  10  ^C   <---- more whoopsxMemory Configuration Changed -- REBOOT NEEDED <---- whoops saved. flow memory allocation (MB)       :  14  ----

В тот момент я понял, что для сохранения этих случайных изменений осталось выполнить заключительную операцию сохранения/записи, поэтому решил просто физически перезапустить устройство, чтобы избежать внесения изменений. После перезапуска возникла ошибка:

Shmoo WR DMWR DM   0000000000111111111122222222223333333333444444444455555555556666666666   012345678901234567890123456789012345678901234567890123456789012345678900 ------++++++++++++++++++++++++++X+++++++++++++++++++++++++++----------01 --+++++++++++++++++++++++++X++++++++++++++++++++++++++----------------02 X---------------------------------------------------------------------03 X---------------------------------------------------------------------MEMSYS init failed, return code 00000001MEMC error:  0x00000000PHY error:  0x00000000SHMOO error:  0x10c00000  0x00000082 0x00000000

Когда маршрутизатор снова заработал, то тут же выдал вышеприведенную ошибку и в CFE не вошел. Без возможности обратиться к загрузчику конфигурацию изменить было нельзя, а процесс его восстановления тоже не представлялся возможным. Онлайн-поиск решения по этой ошибке ничем не помог и привел в тупик. Единственным выводом было, что при повреждении CFE подобным образом устройство впадает в состояние кирпича. Тогда я переключился на работу с резервным девайсом, чтобы получить ответ на изначальный вопрос по интересовавшим меня аргументам. К слову говоря, установка kernp mfg_nvram_mode=1 mfg_nvram_url=BADURL была особенно интересна.

Позже я вернулся к своему кирпичу, чтобы найти способ его восстановления. В нем используется Broadcom SoC, и, как выяснилось, доступ к JTAG обеспечивается через нераспаянные контакты на плате:


После перебора контактов JTAG с помощью JTagulator мне удалось подключиться, используя OpenOCD.

$ openocd -f ../interface/jlink.cfg -f bcm49.cfgOpen On-Chip Debugger 0.11.0-rc2+dev-gba0f382-dirty (2021-02-26-14:07)Licensed under GNU GPL v2For bug reports, read    http://openocd.org/doc/doxygen/bugs.htmlDEPRECATED! use 'adapter speed' not 'adapter_khz'Info : Listening on port 6666 for tcl connectionsInfo : Listening on port 4444 for telnet connectionsInfo : J-Link V10 compiled Dec 11 2020 15:39:30Info : Hardware version: 10.10Info : VTarget = 3.323 VInfo : clock speed 1000 kHzInfo : JTAG tap: bcm490x.tap tap/device found: 0x5ba00477 (mfg: 0x23b (ARM Ltd), part: 0xba00, ver: 0x5)Info : JTAG tap: auto0.tap tap/device found: 0x4ba00477 (mfg: 0x23b (ARM Ltd), part: 0xba00, ver: 0x4)Info : JTAG tap: auto1.tap tap/device found: 0x0490617f (mfg: 0x0bf (Broadcom), part: 0x4906, ver: 0x0)Info : JTAG tap: auto2.tap tap/device found: 0x0490617f (mfg: 0x0bf (Broadcom), part: 0x4906, ver: 0x0)Info : bcm490x.a53.0: hardware has 6 breakpoints, 4 watchpoints

Другой способ восстановления системы реализуется через флеш-память, а именно микросхему Macronix NAND:


И здесь я задумался. У меня ведь есть рабочее устройство, на котором я вполне могу запустить загрузчик. А что, если при этом попробовать заменить его рабочий чип NAND на поврежденный, чтобы перепрошить?

Прежде, чем что-либо пробовать, я спросил коллегу, что он думает по поводу столь дурацкой идеи. Оптимистичных прогнозов он не дал, да и я, честно говоря, на них не особо рассчитывал. В итоге мы заключили небольшое пари по результату моего эксперимента, и я вернулся к работе.

Первым делом предстояло выяснить, переживет ли система удаление NAND в работающем состоянии? Я понимал, что для ответа на этот вопрос мне потребуется более методический подход, нежели просто обдать работающее устройство горячим воздухом и извлечь микросхему. Для начала нужно было выяснить, как NAND запитана. Судя по схеме, Vcc подключены к микросхеме в следующих местах:


Определив дорожки подключения Vcc, проще всего ответить на основной вопрос можно было отключив их от NAND при работающей системе. Чтобы это сделать, изначально я попробовал отсечь эти дорожки и добавить проводные перемычки (рекомендую 36 AWG Magnet Wire), которые можно будет разъединить после запуска загрузчика:


С правой стороны я отсек трассу питания подальше, решив, что это место будет более удачным, поскольку от него запитывается несколько контактов NAND. При установке первой перемычки трассу я отсек небольшим ножом и зачистил покрытие абразивным карандашом:


Получилось так себе, потому что карандаш оказался великоват, и в итоге я оголил чересчур большой участок. Лучше использовать остроконечный нож, чтобы не натворить бардак и получить что-то подобное:



Припаяв и соединив провода, я запустил маршрутизатор и, дождавшись старта загрузчика (CFE), с помощью команды dn (dump nand) убедился в доступности NAND, затем обесточил микросхему, разъединив провода.

CFE> dn------------------ block: 0, page: 0 ------------------00000000: 00000000 00000000 00000000 00000000    ................00000010: 00000000 00000000 00000000 00000000    ................00000020: 00000000 00000000 00000000 00000000    ................<CUT FOR LENGTH>----------- spare area for block 0, page 0 -----------00000800: ff851903 20000008 00fff645 c2b9bf55    .... ......E...U00000810: ffffffff ffffffff ffee9423 4ba37819    ...........#K.x.00000820: ffffffff ffffffff ffee9423 4ba37819    ...........#K.x.00000830: ffffffff ffffffff ffee9423 4ba37819    ...........#K.x.*** command status = 1CFE>web info: Waiting for connection on socket 1.[JCFE>web info: Waiting for connection on socket 0.[JCFE> ----       <----- VCC Removed (reboot)

После отключения питания (отмечено как Vcc removed), устройство перезагрузилось и не смогло запустить загрузчик, так как NAND была недоступна. Проблема оказалась в том, что точка отсечения питания справа отключала его подачу не только на NAND, но и на SoC. Чтобы не усложнять, я просто восстановил этот отрезок и проделал всю ту же процедуру с установкой перемычки в точке ближе к NAND:


Вернув систему в строй и повторив предыдущий тест, я получил ответ на изначальный вопрос: когда питание отключается разъединением проводов перемычки, система продолжает работать, что подтверждается командой dn:

<----- NAND VCC Removed CFE> dn------------------ block: 0, page: 2 ------------------Status wait timeout: nandsts=0x30000000 mask=0x80000000, count=2000000Error reading block 000001000: 00000000 00000000 00000000 00000000    ................<CUT FOR LENGTH>Status wait timeout: nandsts=0x30000000 mask=0x80000000, count=2000000----------- spare area for block 0, page 2 -----------00000800: 00000000 00000000 00000000 00000000    ................00000810: 00000000 00000000 00000000 00000000    ................00000820: 00000000 00000000 00000000 00000000    ................00000830: 00000000 00000000 00000000 00000000    ................Error reading block 0 *** command status = -1      <----- Expected error reading NAND CFE>CFE>CFE><----- NAND VCC Enabled CFE>CFE> dn------------------ block: 0, page: 3 ------------------00001800: 00000000 00000000 00000000 00000000    ................00001810: 00000000 00000000 00000000 00000000    ................<CUT FOR LENGTH>----------- spare area for block 0, page 3 -----------00000800: ffffffff ffffffff ffee9423 4ba37819    ...........#K.x.00000810: ffffffff ffffffff ffee9423 4ba37819    ...........#K.x.00000820: ffffffff ffffffff ffee9423 4ba37819    ...........#K.x.00000830: ffffffff ffffffff ffee9423 4ba37819    ...........#K.x.*** command status = 1      <----- Successful NAND readCFE>

После того, как я убедился в возможности отключения NAND на работающей системе без влияния на загрузчик, очередным шагом было попробовать физически извлечь отключенную NAND из платы.

Прогрев микросхему горячим воздухом, я поочередно приподнял пинцетом сначала правую, а затем левую стороны:


В результате этого процесса система перезапустилась и провалила попытку войти в загрузчик:

CFE> ----    <----- NAND Removed (reboot)BTRMV1.6CPU0L1CDMMUIMMU7DATAZBBSMAINOTP?OTPPUSBTNANDIMG?FAIL----         <----- FAIL boot loop

Так как стороны микросхемы при ее отсоединении я поднимал поочередно, посматривая при этом в консоль, то стало очевидно, что перезагрузка произошла при подъеме именно левой стороны:


Наиболее вероятной причиной было изменение состояния контактов Read Enable (RE#) или Ready/Busy (R/B#). Чтобы это проверить, я добавил к обоим перемычки:


Тут NAND пришлось установить на место, чтобы вернуть систему в загрузчик. Затем я в очередной раз отключил ее питание, разъединив ведущие на Vcc провода, а дорожкиRE# и R/B# привязал к земле (заземлил?):


Затем я снова поочередно извлек правую-левую стороны микросхемы, поглядывая в консоль загрузчика:


На этот раз он остался активен, и система в перезагрузку не ушла. Закончив очередной этап головоломки, я перешел к следующему установке поврежденной NAND в работающее устройство.

Для припаивания NAND снова использовался горячий воздух. Первая попытка оказалась безуспешной, так как некоторые контакты замкнуло при моей попытке выровнять чип по обеим сторонам. На этом этапе ввиду сбоя в очередной раз пришлось ставить обратно рабочую NAND.

Во второй попытке я уже использовал небольшой листок бумаги для изолирования одной стороны NAND на время выравнивания и закрепления другой:


После установки первой стороны бумажку я убрал и припаял вторую. Загрузчик остался активен. Следующим шагом нужно было восстановить контакты RE#, RB# удалением заземляющей перемычки, а также вновь соединить перемычку Vcc. После окончательного восстановления подключения я выполнил dn, чтобы убедиться в доступности NAND:

CFE> dn------------------ block: 0, page: 0 ------------------00000000: 00000000 00000000 00000000 00000000    ................00000010: 00000000 00000000 00000000 00000000    ................00000020: 00000000 00000000 00000000 00000000    ................<CUT FOR LENGTH>----------- spare area for block 0, page 0 -----------00000800: ff851903 20080000 00c2b822 c978ff97    .... ......".x..00000810: ffffffff ffffffff ffee9423 4ba37819    ...........#K.x.00000820: ffffffff ffffffff ffee9423 4ba37819    ...........#K.x.00000830: ffffffff ffffffff ffee9423 4ba37819    ...........#K.x.*** command status = 1   <----- Success!CFE>

Тест чтения завершился успешно, и через веб-интерфейс загрузчика я прошил микросхему заводским образом:

web info: Waiting for connection on socket 1.[Jweb info: Upload 70647828 bytes, flash image format.[J   <----- Image UploadCFE> ........Setting JFFS2 sequence number to 13Flashing root file system at address 0x06000000 (flash offset 0x06000000): <-----Image Write.................................................................... .............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................Resetting board in 0 seconds...----BTRMV1.6CPU0L1CDMMUIMMU7DATAZBBSMAINOTP?OTPPUSBTNANDIMG?IMGLUHD?UHDPRLO?RLOPUBI?UBIPPASS    ----<CUT FOR LENGTH>CFE version 1.0.38-161.122 for BCM94908 (64bit,SP,LE)Build Date: Mon May 13 08:23:21 CST 2019 (defjovi@ubuntu-eva02)Copyright (C) 2000-2015 Broadcom Corporation.Boot Strap Register:  0x6fc42Chip ID: BCM4906_A0, Broadcom B53 Quad Core: 1800MHzTotal Memory: 536870912 bytes (512MB)Status wait timeout: nandsts=0x50000000 mask=0x40000000, count=0NAND ECC BCH-4, page size 0x800 bytes, spare size used 64 bytesNAND flash device: , id 0xc2da block 128KB size 262144KB<CUT FOR LENGTH>Initalizing switch low level hardware.pmc_switch_power_up: Rgmii Tx clock zone1 enable 1 zone2 enable 1.Software Resetting Switch ... Done.Waiting MAC port Rx/Tx to be enabled by hardware ...DoneDisable Switch All MAC port Rx/Tx*** Press any key to stop auto run (1 seconds) ***Auto run second count down: 0Booting from only image (address 0x06000000, flash offset 0x06000000) ...  <----- Success!!111!Decompression LZMA Image OK!Entry at 0x0000000000080000Starting program at 0x0000000000080000/memory = 0x20000000Booting Linux on physical CPU 0x0Linux version 4.1.27 (jenkins@asuswrt-build-server) (gcc version 5.3.0 (Buildroot 2016.02) ) #2 SMP PREEMPT Fri Jun 19 13:05:44 CST 2020CPU: AArch64 Processor [420f1000] revision 0Detected VIPT I-cache on CPU0


Как видно из вывода, прошивка прошла успешно, и система загрузила ОС устройства.

Уверен, некоторые читатели спросят: Почему просто не использовать для перепрошивки NAND специализированный программатор? Это абсолютно уместный вопрос, и, быть может, так даже правильнее, чем заниматься всей этой чепухой.

И все же считаю, что здесь будет уместна цитата персонажа из к/ф Парк Юрского периода, которого играл Джефф Голдблюм:

Ваши ученые настолько озабочены вопросом о том, могут ли они что-то сделать, что забывают приостановиться и подумать, а надо ли вообще это делать.


Источник: habr.com
К списку статей
Опубликовано: 31.05.2021 16:13:25
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Блог компании ruvds.com

Восстановление данных

Компьютерное железо

Накопители

Diy или сделай сам

Ruvds_перевод

Flash-память

Nand

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru