четверг, 6 октября 2016 г.

Редактируем Splash Screen в смартфонах на Qualcomm.

Давненько я не писал интересных исследовательских статей, и вот недавно появился очередной повод к проведению такого исследования. Речь пойдет о редактировании Splash Screen'ов для смартфоном на базе Android с чипсетами от Qualcomm. Сразу скажу что статья носит скорее исследовательский характер, воспользовавшись рекомендациями приведенными в ней можно будет отредактировать splash на вашем собственном устройстве или написать ПО для упрощения такого редактирования, однако, уровень подготовки читателя должен быть чуть выше среднего. Т.е. здесь вы не найдете готовых решений в стиле нажмите туда-то, кликните там-то и ваш splash screen поменяется. Однако, если вы попробуете хотя бы немного разобраться в теме, как это сделал я, то безусловно у вас все получится.

Небольшая предыстория ... что такое Splash Screen думаю многие представляют (не стоит путать его с boot animation), это как раз та картинка, которая появляется на вашем аппарате сразу после включения, также, отдельные splash screen'ы могут быть встроены в ваш телефон для различных событий, например, при разряженной батарее, переходе аппарата в download mode и т.п. Например в Alcatel Idol 3 6045Y (да и в Alcatel Idol 4 6055K) в прошивке встроены несколько таких splash screen'ов, вот они (всего их 4, правда здесь я привел только 3 картинки):


Давайте разберемся где же они хранятся в аппарате, как их извлечь и как заменить. Общеизвестно что на аппаратах построенных на базе Qualcomm (ну по крайней мере на большинстве) существует определенный раздел на eMMC Flash, который как раз и называется splash. Давайте извлечем этот раздел с аппарата (сделать это можно, например, при наличии root-прав) и попробуем разобраться с его внутренней структурой:


На скриншоте дамп раздела splash открытый в hex-редакторе Hacker's View. Как мы видим, раздел начинается с заголовка SPLASH!!, а дальше уже идут какие-то данные. При этом сигнатура SPLASH!! встречается в файле несколько раз из чего можно сделать вывод что каждая картинка в разделе (в нашем с вами примере их 4) состоит из некоего заголовка, начинающегося с этой сигнатуры и непосредственно данных.

В разборе структуры заголовка мне существенно помог скрипт генерации лого - logo_gen.py с CodeAurora. Начнем с заголовка, если использовать C, то описать его структура можно следующим образом:

    struct logo_header {                                            
       unsigned char[8]; // "SPLASH!!"                              
       unsigned width;   // logo's width, little endian             
       unsigned height;  // logo's height, little endian            
       unsigned type;    // 0, Raw Image; 1, RLE24 Compressed Image 
       unsigned blocks;  // block number, real size / 512           
       ......                                                       
    };                                                              

В рассматриваемом нами примере width = 1080 (0x0438), height = 1920 (0x0780), тип изображения - 1, т.е. RLE24 Compressed Image и количество блоков - 226 (0xE2). Размер блока при этом равен - 512 байтам (1 сектор), а сам заголовок тоже занимает 512 (0x200 байт). Отлично. Теперь мы знаем куда больше, чем изначально. Теперь настало время познакомиться с тем что такое RLE и почерпнуть немного теоретической информации. Сделать это можно здесь:

Основное здесь - это статья на Хабре про алгоритм RLE, в Qualcomm'овских девайсах применяется примерно такой же алгоритм (различия очень незначительные), если вы поняли смысл, то без труда поймете и отличия.

https://github.com/DeckerSU/run_length_imager - в этом репозитории я выложил все свои наработки, которые касаются RLE-декодирования изображений из SPLASH'а, в частности там есть два Python скрипта, один для декодирования RLE Encoded RGB24 RAW изображения, другой для его кодирования. Также, там есть модифицированная версия утилиты rlimager.c от makers_mark с форума XDA. В нее я добавил ключ -d 5 , с помощью которого можно декодировать RLE Encoded RGB24 RAW изображения от Idol 3 6045 и Idol 4 6055. Доступны как исходники, так и собранный с помощью MinGW под Win32 бинарник.

Теперь немного практики, т.к. многие не понимают как и чем можно открыть даже несжатое RLE RAW RGB24 изображение, немного расскажу об инструментарии. Первое что мы делаем это ставим x86 или x64 версию IrfanView и обязательно все плагины к нему (!), без плагинов raw изображение у вас не откроется. Далее вырезаем в HIEW (или любом другом hex-редакторе) блок бинарных данных из дампа раздела splash, начиная со смещения 0x200 (т.е. 512 байт заголовка splash мы пропускаем) и вплоть до следующей сигнатуры SPLASH!! в файле и сохраняем получившийся блок как image.rle.raw. Далее берем IrfanView и пробуем открыть в нем изображение как RAW - File -> Open AS ... -> RAW File и выставляем следующие параметры:


Но в результате картинка у нас совсем непохожа на то что должно быть в оригинале:


Это из-за RLE кодирования. Используем python скрипт или доработанную мной утилиту rleimager.exe для декодирования, запускаем:

rleimager.exe -d 5 -m 1080 < image.rle.raw > image.raw

И получаем файл image.raw, который еще раз пробуем открыть в IrfanView способом который уже описан выше и получаем то, что и должны:


Отлично, не так ли? Собрать все это дело назад можно закодировав RAW RGB24 изображение с помощью RLE, затем добавить корректный заголовок и, если картинок в образе раздела splash несколько, просто объединить блоки разных картинок в раздел и прошить в телефон. Подготовка образа splash.img - это уже "задание на дом".

Специальных утилит для редактирования splash.img для Qualcomm, к сожалению нет (для MTK в свое время написали LogoBuilder, который позволяет перепаковывать logo.bin), но основываясь на полученных знаниях вы вполне можете создать нечто подобное. Или же использовать модифицированный python скрипт для сборки splash.img от GokulNC, например, отсюда (естественно, что перед тем как использовать, нужно разобраться как он работает и модифицировать под свою модель устройства). Также, вы можете добавить корректное RLE кодирование в утилиту rleimager (я дописал только декодирование) и использовать ее в повседневной работе.

Ну и естественно статья была бы не полной без демонстрации работоспособности всего описанного на реальном аппарате. Для примера я нарисовал такое лого, давайте посмотрим как оно будет смотреться на реальном аппарате:

 

Надеюсь что статья была полезной для вас. Ну а вариантов применения подобной кастомизации можно найти массу, начиная от простого получения удовольствия от новой красивой картинки при загрузке телефона и заканчивая различными полезными функциями персонализации, например, на splash logo можно поместить логотип собственной компании в целях поддержания корпоративного стиля (особенно если все сотрудники пользуются одинаковыми моделями аппаратов), или разместить там информацию о том, куда можно обратиться нашедшему ваш телефон и т.п. Здесь уже все зависит от вашей фантазии.

Комментариев нет :

Отправить комментарий