Началась эта история с того, что в результате неудачных экспериментов с ядром смартфона Samsung Galaxy Ace 2 (он же GT-I8160, aka codina), приводящих к ребутам девайса, оказалось так, что раздел EFS перестал читаться. Собственно, сами эксперименты отношения к данному вопросу не имеют — возможно, как-нибудь дойду и до них, но это выходит за рамки данной статьи. Хотя и раздел EFS – один из наиболее важных на этом смартфоне, убийство данного раздела само по себе не приводит к катастрофическим последствиям, поскольку его все еще можно восстановить, например, с другого телефона, после чего, при желании сменить WIFI MAC и BT MAC. На данном устройстве IMEI хранится не на разделе EFS, а CSPSA (Crash Safe Parameter Storage Area, дословно переводится как «Область хранения параметров, устойчивая к крашам»). Вот если с этим разделом пойдет что-то не так, это уже будет не столь весело, собственно об этом и пойдет речь далее. Кого заинтересовал, прошу под кат.
После выхода из строя раздела EFS, я, в первую очередь, снял его дамп и попытался поднять его при помощи e2fsck. Неудача – суперблок EXT4 поврежден, да и вообще все выглядело так, словно содержимое раздела превратилось в фарш. Самое время было поискать бэкап, но, какова беспечность (!), в самый неподходящий момент его не оказалось ни на компе, ни на флешке. Всех дальнейших мучений можно было избежать, только если бы у меня были своевременно сделанные бэкапы. Дело было поздним вечером, принявшись искать дампы этого раздела в интернете и найдя один на зарубежном ресурсе, я тут же принялся его прошивать. Наверное, одна из самых страшных вещей, что может произойти при пользовании утилитой
dd
— это опечатка или ошибка при наборе пути к разделу. Сейчас мне только остается удивляться собственной неосторожности (или криворукости, называйте, как хотите), но именно это и произошло… Раздел EFS на данном девайсе – это /dev/block/mmcblk0p7, но я почему-то в тот момент не имел ни тени сомнения, что это, якобы, должен быть /dev/block/mmcblk0p6. Собственно, дальнейшее не требует особых объяснений, обо всей катастрофичности произошедшего я уже понял только тогда, когда dd вывел сообщение о том, что при записи был достигнут конец раздела. Вроде далеко не первый год пользуюсь устройством и являюсь одним из тех немногих оставшихся разработчиков под этот богом забытый девайс. Как же я мог оказаться в такой, с какой стороны не посмотри, дурацкой ситуации? Не спрашивате меня, самому хотелось бы знать… Так телефон с легкой руки стал если не «кирпичом», то «инвалидом» точно.Исследование раздела CSPSA
Итак, раздел EFS оказался убит крашем во время активной записи на диск, раздел же CSPSA, усточивый к крашам, не устоял к моей опрометчивости. Пойди я в СЦ, даже там наверняка бы развели руками. Прошивка CSPSA от другого девайса дела также не исправит, т.к. IMEI, очевидно, хранится где-то помимо данного раздела и сравнивается с тем, что находится в CSPSA. Да и статья не о смене IMEI, а об его восстановлении.
Ситуация безвыходная, как ни посмотри, думал я. Я оказался втянут в то, чем явно не планировал заниматься, ковырять внутренности раздела CSPSA. Оказалось, что среди утекших в 2014 году исходников для чипсета ST-Ericsson Novathor U8500 есть исходники на утилиты, позволяющие работать с данным разделом:
root@:/ # cd ramdisk
root@:/ramdisk # ./cspsa-cmd
[CSPSA]: open CSPSA0
[CSPSA]: <CSPSA_Open('CSPSA0').>
[CSPSA]: <Result 'T_CSPSA_RESULT_OK'>
[CSPSA]: ls
Key Size
0 4
1 96
2 96
3 96
1000 38
66048 497
-8192 41
-4 4
-3 4
-2 4
-1 4
Number of keys in CSPSA : 11
Total size of all values: 884
[CSPSA]: read_to_file 3e8 /sdcard/1000.bin
[CSPSA]: <Read (000003e8) to file '/sdcard/1000.bin'>
[CSPSA]: CSPSA_GetSizeOfValue(000003e8): T_CSPSA_RESULT_OK
[CSPSA]: <CSPSA_Read(000003e8).>
[CSPSA]: <CSPSA_ReadValue(000003e8, 38): T_CSPSA_RESULT_OK>
[CSPSA]: <38 bytes written to file '/sdcard/1000.bin'.>
[CSPSA]: write_from_file 3e8 /sdcard/1000.bin
[CSPSA]: <Write (000003e8) from file '/sdcard/1000.bin'>
[CSPSA]: <38 bytes read from file '/sdcard/1000.bin'.>
[CSPSA]: <CSPSA_WriteValue(000003e8, 38).>
[CSPSA]: <CSPSA_WriteValue(000003e8, 38): T_CSPSA_RESULT_OK>
Команда «open CSPSA0» открывает сокет CSPSA0, таким образом подключаясь к процессу cspsa-server. Как можно видеть, команда ls отображает хранимые в CSPSA параметры и их размер.
Далее, командой read_to_file можно записать параметр (здесь это номер 1000, указаный в HEX, — 3e8) в файл, и точно также записать параметр из файла в раздел командой write_from_file.
Это конечно здорово, что удалось найти такую утилиту, но не давало мне никаких подсказок по поводу того, что должно было находиться в данных параметрах, чтобы IMEI снова читался нормально. По факту, утилита могла «скрывать» часть правды, выдавая не все параметры, и скрывая тот, в котором хранится IMEI. Для того, чтобы понять, что могло находиться в этих параметрах, нужно было иметь несколько таких различных разделов CSPSA, но в самом деле, не могу же я просить кого-то слить раздел со столь приватной информацией. В интернете нашлись два различных раздела CSPSA, но сравнение считанных через cspsa-cmd параметров выдало слишком большую разницу, около 512-768 байт суммарно при сравнении их друг с другом. Даже при наличии всех исходников, могло пройти немало времени до того, пока я бы разобрался (если разобрался вообще). Идею о восстановлении CSPSA «в лоб» пришлось оставить, обратив взгляд на другие части слитых исходников, которые бы могли помочь восстановить телефон.
Я наткнулся на еще одну утилиту, которая выглядела многообещающе.
По ссылке приведен список комманд поддерживающихся данной утилитой.
(...)
static const struct {
const char *str;
cops_return_code_t (*func)(cops_context_id_t *ctx,
int *argc, char **argv[]);
} api_funcs[] = {
{"read_imei", cmd_read_imei},
{"bind_properties", cmd_bind_properties},
{"read_data", cmd_read_data},
{"get_nbr_of_otp_rows", cmd_get_nbr_of_otp_rows},
{"read_otp", cmd_read_otp},
{"write_otp", cmd_write_otp},
{"authenticate", cmd_authenticate},
{"deauthenticate", cmd_deauthenticate},
{"get_challenge", cmd_get_challenge},
{"modem_sipc_mx", cmd_modem_sipc_mx},
{"unlock", cmd_simlock_unlock},
{"lock", cmd_simlock_lock},
{"ota_ul", cmd_ota_simlock_unlock},
{"get_status", cmd_simlock_get_status},
{"key_ver", cmd_verify_simlock_control_keys},
{"get_device_state", cmd_get_device_state},
{"verify_imsi", cmd_verify_imsi},
{"bind_data", cmd_bind_data},
{"verify_data_binding", cmd_verify_data_binding},
{"verify_signed_header", cmd_verify_signed_header},
{"calcdigest", cmd_calcdigest},
{"lock_bootpartition", cmd_lock_bootpartition},
{"init_arb_table", cmd_init_arb_table},
{"write_secprofile", cmd_write_secprofile},
{"change_simkey", cmd_change_simkey},
{"write_rpmb_key", cmd_write_rpmb_key},
{"get_product_debug_settings", cmd_get_product_debug_settings}
};
(...)
Как и в предыдущем случае с cspsa-cmd, cops_cmd подключается к процессу-серверу, copsdaemon (COPS расшифровывается как COre Platform Security).
Этот самый бинарник copsdaemon на девайсе оказался отличным от того, что в исходниках (или у меня не получилось правильно сконфигурировать Android.mk), так или иначе, собранный из исходников отказывался работать. Однако, похоже утилита cops_cmd была совместима с остальным проприетарным ПО и запускалась нормально.
Первое, что я попробовал сделать — запустить команду
cops_cmd read_imei
— точно сейчас не вспомню, выдало, что-то вроде «error 13, device is tampered». Ага, конечно, чего еще можно было ожидать, с запоротым-то разделом CSPSA. Недолгое чтение исходников привело к команде «bind_properties»:static cops_return_code_t cmd_bind_properties(cops_context_id_t *ctx,
int *argc, char **argv[])
{
cops_return_code_t ret_code;
cops_imei_t imei;
(...)
usage:
(...)
fprintf(stderr,
"Usage: bind_properties imei <imei> (15 digits)\n"
"Usage: bind_properties keys <k1 k2 k3 k4 k5> (keys are space delimited)\n"
"Usage: bind_properties auth_data <auth_number> <auth data file name>\n"
"Usage: bind_properties data <data file name> <optional don't merge flag 0, otherwise merge will occur>\n");
return COPS_RC_ARGUMENT_ERROR;
}
Как можно видеть из исходников, функция предназначена для записи IMEI в устройство. Но вот незадача, только непосредственно перед записью необходимо произвести аутентификацию при помощи закрытого ключа, которого у меня, очевидно, нет. Оставалось только продолжать ковырять copsdaemon, с тем чтобы попытаться избежать необходимость аутентификации, к счастью, все обошлось и без этого.
В поиске идей
Прошло несколько дней в поисках и размышлениях. После общения с одним своим знакомым с xda-developers я узнал, что для разновидности GT-I8160 с чипом NFC, GT-I8160P, есть прошивка с неким дефолтным, «полу-пустым» разделом CSPSA, и что прошивка этого РОМа на данном девайсе приводит к тому, что IMEI «обнуляется», то есть все 15 цифр IMEI становятся нулями (не помню точно, происходит ли это в случае запоротого раздела CSPSA или вообще независимо от того). Первым же делом скачал данную прошивку и прошил раздел CSPSA — безрезультатно. Коллега предлагал частичную прошивку (т.е. прошивку отдельных разделов, не включая такие «опасные», как загрузчик и другие) данного РОМа. Довольно бесперспективное занятие, это могло окончательно «окирпичить» девайс. Наконец по прошествию еще пары дней, в то время, как я был занят исходниками выше, коллега с XDA сделал поистине невероятную и бесценную находку:
#TA Loader to write default IMEI
service ta_load /system/bin/ta_loader recovery
user root
group radio
oneshot
Это вырезка содержимого файла init.samsungcodina.rc рамдиска из стоковой прошивки Android 4.1.2, где прямо указано в комментарии, что это сервис для восстановления IMEI по умолчанию.
Недолго думая, я запустил из терминала:
/system/bin/ta_loader recovery
Девайс перезагрузился в режим рекавери, затем еще одна перезагрузка вручную в систему, и вуаля! IMEI уже отображается не как «null», а обнуленный, регистрация в сети доступна, прогресс, однако. Тайна «обнуленного» IMEI была раскрыта.
Но это, разумеется, совсем не здорово ходить вот с таким IMEI «по умолчанию». Совсем недолгих поисков хватило, на то, чтобы глянуть на бинарник ta_loader в HEX-редакторе (исходников на эту тулзу уже не нашлось) и подменить нулевой IMEI на свой командой типа:
sed -i "s,<15_zeroes>,<IMEI>," /ramdisk/ta_loader
sed -i "s,<IMEI>0,<16_zeroes>," /ramdisk/ta_loader
Почему команда sed вызывается два раза? В бинарнике есть последовательность из более, чем 15 нулей, не относящаяся к IMEI, поэтому, чтобы вернуть нежеланное изменение, необходимо вызвать команду второй раз. Спешу заверить, пытаться записать «левый» IMEI таким образом бесполезно, утилита работает так, что записать можно только IMEI с коробки (либо дефолтный). Еще одна перезагрузка в рекавери, потом в систему, и, о чудо — IMEI на месте! Более подробно процесс восстановления я описал на форуме XDA Developers. Такие вот дела, повезло, что производитель оставил лазейку для восстановления исходного IMEI. Не случись злоключений выше, наверно, мне и в голову бы не пришло ковыряться во всем этом, но с другой стороны, и не было бы всей этой истории.
Комментарии (20)
IvUyr
20.06.2017 19:04Спешу заверить, пытаться записать «левый» IMEI таким образом бесполезно
Вы пробовали, или предостережение «любопытным»? И на сколько сильно данный аппарат отличается от SGS Plus (хочу кастом прошить, но боюсь окирпичить зверька).RadicalDreamer
20.06.2017 19:06И то и другое :) Пробовал записать что-то рандомное, т.к. не сильно-то мне хотелось публиковать способ, который мог бы позволять смену IMEI. В этом случае телефон просто перезагружается и ничего не происходит.
RadicalDreamer
20.06.2017 19:17И на сколько сильно данный аппарат отличается от SGS Plus (хочу кастом прошить, но боюсь окирпичить зверька).
Настолько же отличные, как и любые два аппарата на разных процессорах… Не понимаю, чего бояться, когда все разжевано и протестировано другими пользователями — просто найдите мануал по прошивке на 4pda или xda.IvUyr
21.06.2017 23:07Спасибо, оба эти сервиса мне знакомы (во времена WinMobile экспериментировал с «кухнями» и сборками прошивок), боязно испортить «трёхкнопочный режим», без которого всё будет очень печально.
BBB93
20.06.2017 19:06Добрый день, у меня тоже самое случилось с моим GT-I8160. Пару дней назад он сам перезагрузился и стал выдавать сообщения процесс такой то остановлен и так по кругу. Сделал хард резет, все заработало но не видит сеть — состояние отключено. IMEI на месте. WIFI работает. Подскажите как вернуть к жизни телефон?
RadicalDreamer
20.06.2017 19:12IMEI на месте
Ну это другой случай тогда. У вас скорее всего стоит стоковая прошивка 4.1.2, с ней всякие глюки бывали, помимо обычных лагов после продолжительного пользования.
Сделал хард резет
Не путем форматирования всех доступных разделов из рекавери, надеюсь? В этом случае могли снести раздел Modem FS или EFS, это легко лечится. Начните с данного способа по восстановлению Modem fs.BBB93
20.06.2017 20:41зажал 3 кнопки, потом в меню выбрал «wipe data/factory reset» потом перезагрузил и все связи нет. прошивка стоит с завода 2.3.6 версия прошивки ХХХХ сборка GINGERBREAD.XXLK6
RadicalDreamer
20.06.2017 21:20Не знаю, что конкретно произошло именно в вашем случае, но суть способа восстановления тот же, что и для прошивки 4.1.2. Поищите на форуме в топике по стоку 2.3.6 — самому не довелось долго пользоваться этой версией прошивки, возможно найдется что-то и для 2.3.6.
BBB93
21.06.2017 13:31может есть видеоролик как это сделать? опыта нет боюсь испортить.
RadicalDreamer
21.06.2017 14:49Видеоролик — вряд ли, зато есть подробная инструкция по перепрошивке. Вы пробовали банально накатить трехфайловую прошивку?
BBB93
21.06.2017 16:49нет не пробовал, боюсь испортить. Дайте ссылку на подробную инструкцию.
RadicalDreamer
21.06.2017 17:06http://4pda.ru/forum/index.php?showtopic=354110&st=12740
Ищите в шапке, в разделе инструкций.
P.s. поиском пользоваться тоже никто не запрещает.BBB93
24.06.2017 01:37Установил трехфайловую прошивку. Изменений нет. Как я понял мне нужна прошивка радиомодуля из описания данной проблемы нашел что надо поставить ME7 modem.zip скачал его на телефон. При загрузке в recovery телефон пишет:
E:failed to mount /efs (No such file or directory)
E:failed to mount /efs (Invalid argument)
E:failed to mount /efs (Invalid argument)
Что делать?RadicalDreamer
24.06.2017 02:03Ну таки что-то форматнуло у вас efs.
Скачайте образ efs отсюда (я залил образ EFS после того, как угробил свой в результате экспериментов) и прошейте через dd.
UPD. да, и еще, не следовало шить 4.1.2 модем на прошивку 2.3.6 — они не совместимы.BBB93
24.06.2017 10:55и прошейте через dd… Что такое dd и как через него прошить? Есть инструкция?
RadicalDreamer
24.06.2017 18:18Вам сюда. В разделе инструкций есть мануал по восстановлению IMEI (EFS).
BBB93
25.06.2017 13:32там описано для 4.1.2 и тоже не совсем понятно что где брать.
Для этого нужно:
1.стоковая 4.1.2 (MG2)
2.Odin
3.гoot.zip
4.разовый cwm
5.zip-архив с модемом.
разовый cwm — где брать? и нет ни слова про образ efs что вы дали…RadicalDreamer
25.06.2017 21:47Не там смотрите
https://habrastorage.org/web/4a4/0c5/de4/4a40c5de46684f97bbfb26da5969b72e.png
Переход на 4.1.2 не нужен, т.к. efs везде один. А вот для восстановления modemfs лучше накатить 2.3.6 и впредь не прошивать модемы от 4.1.2.BBB93
29.06.2017 14:38без эмоций…
сделал на телефоне рут спасибо что объяснили что он нужен для того чтобы выполнить команду из скирншота. Также спасибо что объяснили куда вводить эту команду и что надо скачать приложение Terminal Emulator.
И наконец я сделал то что вы написали:
$ su
# dd if=/sdcard/efs.img of=/dev/block/mmcblk0p7 bs=4096
И в итого модуль связи не появился ХХХХ
kay
Вот как бы мне Samsung Duos s7562 (чипсет MSM7x27a) из QHSUSB_DLOAD вывести. Точно также по неосторожности dd запорол GPT. Единственный вариант на данный момент JTAG. Но если найти QPST загрузчик, которые переведет телефон в download mode, то можно и без JTAG.
Спасительная флэшка + JIG тоже не работает.