Началась эта история с того, что в результате неудачных экспериментов с ядром смартфона 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)


  1. kay
    20.06.2017 18:24

    Вот как бы мне Samsung Duos s7562 (чипсет MSM7x27a) из QHSUSB_DLOAD вывести. Точно также по неосторожности dd запорол GPT. Единственный вариант на данный момент JTAG. Но если найти QPST загрузчик, которые переведет телефон в download mode, то можно и без JTAG.


    Спасительная флэшка + JIG тоже не работает.


  1. IvUyr
    20.06.2017 19:04

    Спешу заверить, пытаться записать «левый» IMEI таким образом бесполезно

    Вы пробовали, или предостережение «любопытным»? И на сколько сильно данный аппарат отличается от SGS Plus (хочу кастом прошить, но боюсь окирпичить зверька).


    1. RadicalDreamer
      20.06.2017 19:06

      И то и другое :) Пробовал записать что-то рандомное, т.к. не сильно-то мне хотелось публиковать способ, который мог бы позволять смену IMEI. В этом случае телефон просто перезагружается и ничего не происходит.


    1. RadicalDreamer
      20.06.2017 19:17

      И на сколько сильно данный аппарат отличается от SGS Plus (хочу кастом прошить, но боюсь окирпичить зверька).

      Настолько же отличные, как и любые два аппарата на разных процессорах… Не понимаю, чего бояться, когда все разжевано и протестировано другими пользователями — просто найдите мануал по прошивке на 4pda или xda.


      1. IvUyr
        21.06.2017 23:07

        Спасибо, оба эти сервиса мне знакомы (во времена WinMobile экспериментировал с «кухнями» и сборками прошивок), боязно испортить «трёхкнопочный режим», без которого всё будет очень печально.


  1. BBB93
    20.06.2017 19:06

    Добрый день, у меня тоже самое случилось с моим GT-I8160. Пару дней назад он сам перезагрузился и стал выдавать сообщения процесс такой то остановлен и так по кругу. Сделал хард резет, все заработало но не видит сеть — состояние отключено. IMEI на месте. WIFI работает. Подскажите как вернуть к жизни телефон?


    1. RadicalDreamer
      20.06.2017 19:12

      IMEI на месте

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

      Не путем форматирования всех доступных разделов из рекавери, надеюсь? В этом случае могли снести раздел Modem FS или EFS, это легко лечится. Начните с данного способа по восстановлению Modem fs.


      1. BBB93
        20.06.2017 20:41

        зажал 3 кнопки, потом в меню выбрал «wipe data/factory reset» потом перезагрузил и все связи нет. прошивка стоит с завода 2.3.6 версия прошивки ХХХХ сборка GINGERBREAD.XXLK6


        1. RadicalDreamer
          20.06.2017 21:20

          Не знаю, что конкретно произошло именно в вашем случае, но суть способа восстановления тот же, что и для прошивки 4.1.2. Поищите на форуме в топике по стоку 2.3.6 — самому не довелось долго пользоваться этой версией прошивки, возможно найдется что-то и для 2.3.6.


          1. BBB93
            21.06.2017 13:31

            может есть видеоролик как это сделать? опыта нет боюсь испортить.


            1. RadicalDreamer
              21.06.2017 14:49

              Видеоролик — вряд ли, зато есть подробная инструкция по перепрошивке. Вы пробовали банально накатить трехфайловую прошивку?


          1. BBB93
            21.06.2017 16:49

            нет не пробовал, боюсь испортить. Дайте ссылку на подробную инструкцию.


            1. RadicalDreamer
              21.06.2017 17:06

              http://4pda.ru/forum/index.php?showtopic=354110&st=12740
              Ищите в шапке, в разделе инструкций.
              P.s. поиском пользоваться тоже никто не запрещает.


              1. 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)
                Что делать?


                1. RadicalDreamer
                  24.06.2017 02:03

                  Ну таки что-то форматнуло у вас efs.
                  Скачайте образ efs отсюда (я залил образ EFS после того, как угробил свой в результате экспериментов) и прошейте через dd.
                  UPD. да, и еще, не следовало шить 4.1.2 модем на прошивку 2.3.6 — они не совместимы.


                  1. BBB93
                    24.06.2017 10:55

                    и прошейте через dd… Что такое dd и как через него прошить? Есть инструкция?


                    1. RadicalDreamer
                      24.06.2017 18:18

                      Вам сюда. В разделе инструкций есть мануал по восстановлению IMEI (EFS).


                      1. 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 что вы дали…


                        1. 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.


                          1. BBB93
                            29.06.2017 14:38

                            без эмоций…
                            сделал на телефоне рут спасибо что объяснили что он нужен для того чтобы выполнить команду из скирншота. Также спасибо что объяснили куда вводить эту команду и что надо скачать приложение Terminal Emulator.
                            И наконец я сделал то что вы написали:
                            $ su
                            # dd if=/sdcard/efs.img of=/dev/block/mmcblk0p7 bs=4096

                            И в итого модуль связи не появился ХХХХ