Reverse engineering 'nvdata'
reIntroduction
On mobile phone devices, there are different partitions/sections of data, which differs from vendor to vendor.
Samsung for example, keeps the partition information in a PIT file, and the partitions are various: radio (GSM/LTE/etc) firmware, bootloader, network vendor information, etc.
One of the most crucial ones, the EFS partition hold information which is never supposed to be overwritten, such as the IMEI, network vendor data, etc.
nvdata.bin
You probably guessed that “nvdata” stands for “network vendor data”.
Each phone vendor and network carrier probably have their own way of storing this information.
On Samsung’s phones, nvdata.bin is a file on the EFS partition which stores such information.
The file is verified on boot by RIL, and if the hash check fails, a backup is used. In case one would like to tamper with it, this check prevents that. How about the case in which YOU would like to tamper with it?
RIL
RIL stands for Radio Interface Layer. Android provides an API, which is linked against the vendor supplied libs (which are closed source).
The daemon is responsible for initializing the telephony modem, uploading the firmware, etc.
If you’d like to understand it better, it’s best to change the init to run strace (cross compile it if you don’t have it on your mobile). Such an example, and a nice blog post on this can be found at [1].
Reversing the hash
Currently, the only thing I’ve managed to do properly is to reverse the MD5 hash.
I popped up radare2, and loaded libsec-ril.so
. Looking through the symbols, and found some candidates which were responsible for computing the checksum. Luckily, they all ended up calling one of them, so that one became the only one worth inspecting.
Now, since I already knew where to look, I thought that it would be easier if I would decompile it. I used both ‘ghidra’ and ‘retdec’.
char *uStack256 = str.Samsung_Android_RIL._0_8_;
// ...
sym.imp.MD5_Init(auStack208);
sym.imp.MD5_Update(auStack208, *(undefined8 *)(arg1 + 0x360), iStack336);
char *uVar5 = sym.imp.__strlen_chk(&uStack256, 0x14);
sym.imp.MD5_Update(auStack208, &uStack256, uVar5);
sym.imp.MD5_Final(&uStack224, auStack208);
It’s quite obvious from the code snippet that the string Samsung_Android_RIL
is appended to the end of nvdata.bin
to create the hash.
After applying this method, I checked the logs and noticed that nvdata.bin was not reverted to a backup.
Reversing the network lock
This one hasn’t been successful yet.
After following the post on XDA Developers found in [2], I reached the conclusion that different models have different formats for this file. However, it would be quite intuitive that they would be similar.
Next thing I did was to fire up poke and look for 5 byte patterns, that match FF 01 XX XX XX
.
I tried some of them - only one yielded any results, and that result was the RIL daemon crashing. I stopped here. ^^
Appendix
[1] https://eighty-twenty.org/2020/09/10/booting-samsung-galaxy-s7-modem [2] https://forum.xda-developers.com/t/howto-root-required-remove-network-lock-using-nv_data-bin.1369474/