The story of an unexpected “bricking” and restoration of one smartphone

    This story began with the fact that as a result of unsuccessful experiments with the core of the Samsung Galaxy Ace 2 smartphone (aka GT-I8160, aka codina), leading to reboots of the device, it turned out that the EFS section stopped reading. Actually, the experiments themselves have nothing to do with this issue - perhaps I will somehow get to them, but this is beyond the scope of this article. Although the EFS section is one of the most important on this smartphone, the killing of this section does not in itself lead to catastrophic consequences, since it can still be restored, for example, from another phone, after which, if desired, change the WIFI MAC and BT MAC. On this device, IMEI is not stored on the EFS partition, but CSPSA (Crash Safe Parameter Storage Area, literally translated as “Crash Resistant Parameter Storage Area”). Now, if something goes wrong with this section, it will not be so much fun, actually this will be discussed further. Who interested, I ask under the cat.

    After the EFS partition failed, I first removed its dump and tried to raise it using e2fsck. Failure - the EXT4 superblock is damaged, and indeed everything looked as if the contents of the section had turned into mincemeat. It was about time to look for a backup, but, what carelessness (!), At the most inopportune moment it was not on my computer or on a flash drive. All further torment could be avoided only if I had backups done in a timely manner. It was late in the evening, starting to search for dumps of this section on the Internet and finding one on a foreign resource, I immediately began to flash it. Probably one of the worst things that can happen when using the utilitydd- This is a typo or an error while typing the path to the section. Now I just have to wonder at my own carelessness (or curvature, call it what you want), but that’s exactly what happened ... The EFS section on this device is / dev / block / mmcblk0p7, but for some reason I had no doubt at that moment that it supposedly should be / dev / block / mmcblk0p6. Actually, the further one does not require any special explanations; I already understood the catastrophic nature of what happened only when dd showed a message that the end of the section was reached during recording. It seems that I have been using the device for many years and am one of the few remaining developers under this god-forgotten device. How could I find myself in such a stupid situation on which side? Do not ask me, I myself would like to know ... So the phone with a light hand became if not a "brick"

    CSPSA Section Study

    So, the EFS partition was crashed during active burning to disk, while the CSPSA partition, which is crash-resistant, could not resist my recklessness. I’d go to the SC, even there they would probably have shrugged. CSPSA firmware from another device will not fix things either, because IMEI, obviously, is stored somewhere besides this section and is compared with what is in CSPSA. And the article is not about changing IMEI, but about its restoration.

    A hopeless situation, no matter how you look, I thought. I found myself embroiled in something that I clearly did not plan to do, pick the insides of the CSPSA section. It turned out that among the sources that leaked in 2014 for the ST-Ericsson Novathor U8500 chipset there are sources for utilities that allow you to work with this section:

    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>

    The “open CSPSA0” command opens the CSPSA0 socket, thus connecting to the cspsa-server process. As you can see, the ls command displays the parameters stored in CSPSA and their size.

    Further, with the read_to_file command, you can write a parameter (here it is the number 1000 specified in HEX - 3e8) to a file, and just as write a parameter from a file to a section with the write_from_file command.

    It is certainly great that I managed to find such a utility, but it did not give me any hints about what should have been in these parameters so that IMEI was read again normally. In fact, the utility could “hide” part of the truth, giving out not all parameters, and hiding the one in which IMEI is stored. In order to understand what could be in these parameters, it was necessary to have several different sections of CSPSA, but in fact, I can’t ask someone to merge the section with such private information. There were two different sections of CSPSA on the Internet, but comparing the parameters read through cspsa-cmd produced too much difference, about 512-768 bytes in total, when comparing them with each other. Even with all the sources, it could take a long time before I figured out (if I figured out at all).

    I came across another utility that looked promising.

    The link contains a list of commands supported by this utility.

    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}

    As in the previous case with cspsa-cmd, cops_cmd connects to the process server, copsdaemon (COPS stands for COre Platform Security).

    This copsdaemon binary on the device turned out to be different from the one in the source (or I couldn’t configure correctly), anyway, the one compiled from the source refused to work. However, it seems the cops_cmd utility was compatible with other proprietary software and started normally.

    The first thing I tried to do was run the command cops_cmd read_imei— I just won’t remember it now, it issued something like “error 13, device is tampered”. Aha, of course, what else could be expected, with the CSPSA section which is screwed up. A short reading of the source led to the bind_properties command:

    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: 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;

    As you can see from the source, the function is designed to write IMEI to the device. But this is bad luck, only immediately before recording it is necessary to authenticate using a private key, which I obviously do not have. It only remained to continue to pick copsdaemon in order to try to avoid the need for authentication, fortunately, everything was done without it.

    In search of ideas

    Several days passed in search and reflection. After talking with one of my acquaintances with xda-developers, I found out that for the GT-I8160 variety with an NFC chip, GT-I8160P, there is firmware with some default, “half-empty” CSPSA section, and that the firmware of this ROM on this device leads to the fact that IMEI is “nullified,” that is, all 15 digits of IMEI become zeros (I don’t remember exactly whether this happens in the case of a CSPSA partition or if it doesn’t work at all). The first thing I did was to download this firmware and flash the CSPSA section - to no avail. A colleague offered partial firmware (i.e., firmware for individual partitions, not including such “dangerous” ones as the bootloader and others) of this ROM. Quite a futile exercise, this could finally “brick” the device. Finally, after a couple more days, while I was busy with the source code above,

    #TA Loader to write default IMEI
    service ta_load /system/bin/ta_loader recovery
        user root
        group radio

    This is a clipping of the contents of the init.samsungcodina.rc file of the ramdisk from the Android 4.1.2 stock firmware, which explicitly states in the comment that this is a service to restore IMEI by default.
    Without thinking twice, I ran from the terminal:

    /system/bin/ta_loader recovery

    The device rebooted into recovery mode, then another reboot manually into the system, and voila! IMEI is already displayed not as “null”, but zeroed, network registration is available, progress, however. The secret of the "nullified" IMEI has been revealed.

    But, of course, it’s not at all great to go with such default IMEI. Quite a short search was enough to look at the ta_loader binary in the HEX editor (there were no sources for this tool yet) and replace the zero IMEI with your own command like:

    sed -i "s,<15_zeroes>,<IMEI>," /ramdisk/ta_loader
    sed -i "s,<IMEI>0,<16_zeroes>," /ramdisk/ta_loader

    Why is the sed command called twice? There is a sequence of more than 15 zeros in the binary that is not related to IMEI, therefore, to return an unwanted change, you need to call the command a second time. I hasten to assure you that trying to write the "left" IMEI in this way is useless, the utility works so that you can only write IMEI from the box (or default). Another reboot into recovery, then into the system, and, lo and behold, IMEI is in place! I described the recovery process in more detail on the XDA Developers forum . Such things, it was fortunate that the manufacturer left a loophole to restore the original IMEI. If there had not been the misadventures above, I probably would never have thought of tinkering with all this, but on the other hand, this whole story would not have happened.

    Also popular now: