
Эксплойт PSP для GPU AMD navi31 (RX 7900), который отключает проверки подписи прошивки, чтобы карта загружала неподписанную прошивку SMU, SDMA, MEC, IMU и RLC; не сохраняется после холодной загрузки.
Эксплойт для PSP (Platform Security Processor) для карт AMD navi31 (серия RX 7900). Вероятно, адаптируем и к другим смежным семействам продуктов.
Он отключает проверку подписи прошивки PSP, поэтому карта будет загружать неподписанную прошивку IP-блоков (SMU, SDMA, MEC, IMU, RLC), которую иначе отказалась бы загружать. Представьте себе кастомное управление питанием, ограничения частот или что угодно ещё, что живёт в прошивке, которую подписывает вендор, а вы — нет.
Ничего не прошивается во флеш. Патч живёт в памяти PSP и применяется при тёплой перезагрузке; холодный цикл питания стирает его, и карта снова в стоковом состоянии. Эта тёплая перезагрузка и есть «Wake and Break»: карта просыпается, мы убеждаем её сразу же стать по-настоящему под кайфом и принуждаем её отключить проверки подписи. :-)
Протестировано на карте RX 7900 XTX. См. Status.
python3 wakebreak.py 25=/path/to/firmware.bin
Он внедряет патч, выполняет тёплую перезагрузку карты и отправляет ваш образ как прошивку типа 25. Если выводится accepted, значит PSP принял образ, который обычно отклонил бы.
Нужно что-то, чтобы это проверить? ipfw_images.py выводит список прошивок, которые фактически загружает ваш драйвер, и записывает тестовую пару — подлинный образ и копию с одним перевёрнутым битом в подписи, так что сама прошивка побайтово идентична:
python3 ipfw_images.py # what does this card load?
python3 ipfw_images.py 25 # -> /tmp/fw_25_{ok,bad}.bin
python3 wakebreak.py 25=/tmp/fw_25_bad.bin
Прошивка со склада отклоняет fw_25_bad.bin. С применённым патчем он принимается.
Вот и вся демонстрация.
python3 -m venv venv
venv/bin/pip install -r requirements.txt
make verify # are the shipped artifacts intact?
make selftest # offline sanity checks, no card touched
Вам нужен Linux-хост с картой, доступной через AMD-драйвер
tinygrad (PCIe или его USB-мост).
См. requirements.txt для одного патча tinygrad, необходимого вашему хосту.
Известны четыре сборки прошивки navi31, и патч должен соответствовать вашей.
Профиль a используется по умолчанию и охватывает наиболее распространённую из них. Если у вас есть дамп
SPI-флеша вашей карты, identify.py сообщит вам:
python3 identify.py FLASH.bin
# -> sos-build c: wakebreak.py --sos-build c
В остальных случаях просто попробуйте их. Ошибочное предположение безвредно: патч проверяет то, что собирается изменить, обнаруживает нечто незнакомое, ничего не записывает, и карта загружается нормально.
python3 wakebreak.py --sos-build c 25=/tmp/fw_25_bad.bin
Подтверждено на протестированной карте (RX 7900 XTX, профиль a):
| изменённая прошивка, стоковая карта | отклонено |
| изменённая прошивка, пропатченная | принято |
| после полного отключения питания | снова отклонено — карта в стоковом состоянии |
ПРИМЕЧАНИЕ: Профили b, c и d собраны и проверены офлайн, но никогда не запускались на реальном оборудовании. Если у вас есть карта, соответствующая профилю b, c или d, пожалуйста, сообщите, работает ли это!
Сам патч представляет собой несколько сотен байт ARM-ассемблера в hook/*.S. Собранные бинарные файлы поставляются вместе с репозиторием, поэтому для использования не нужен кросс-компилятор. Если вы всё же хотите пересобрать их:
make rebuild # needs arm-none-eabi binutils
make rebuild CROSS=/path/to/arm-none-eabi-
Сборка отказывается устанавливать что-либо, чей хеш не совпадает с байтами, протестированными на карте, поэтому другая цепочка инструментов не может незаметно изменить то, что записывается на ваш PSP.
wakebreak.py the exploit
identify.py which --sos-build does this card need?
ipfw_images.py build a signed/tampered firmware pair to test with
selftest.py offline checks
hook/ the patch: ARM sources and built blobs
firmware/ two stock AMD firmware images the exploit needs to get in
firmware/ содержит неизменённые публично поставляемые образы AMD. Это старые
версии, сохранённые потому, что путь к доступу проходит через них.
Здесь намеренно не описано: читайте код. wakebreak.py — это ~600 строк с
комментариями, и комментарии объясняют механизм, проверки безопасности и
почему каждый шаг упорядочен именно так. TL;DR: загружаются два штатных
доверенных приложения AMD, одно из них уговаривают выполнить цепочку, способную
писать в память PSP, патч размещается в резидентной копии загрузчика, а
затем карта тёплой перезагрузкой загружается в него.
MIT, см. LICENSE. Делайте с этим что хотите.
При создании этой работы активно использовалась помощь LLM. Это не означает, что автор не имеет представления о том, что здесь на самом деле происходит. немало сопротивления и ручной работы потребовалось, чтобы вообще дойти до этого момента. Вам могут не понравиться эти небрежные артефакты Python или что-то ещё, но вы не сможете поспорить с тем фактом, что ваша карта Navi31 теперь вдруг загружает неподписанные блобы компонентов прошивки. Благодарю за внимание.