10/17/2013

Fixing Galaxy Nexus's IMEI Number

I have been using Galaxy Nexus for quite some time and it worked fine as an everyday+development phone until its IMEI number got blocked on T-Mobile recently. If your IMEI number is 004999010640000 (you can see your IMEI number by dialing *#06#), then this post might help you restore your connectivity. It did for me: I got my GN off eBay long ago. It was a DoCoMo phone from Japan and it was unlocked with the F*ckDoCoMo app by the seller.

For the confused audience

You used Galaxy Nexus on T-Mobile (or other networks) and someday you found it suddenly stop to register onto the cellular network. After rounds of unhelpful customer service calls, you were told that your IMEI number (004999010640000) is blocked on the T-Mobile network (and possibly other networks too). Furthermore, the customer representative could do absolutely nothing about it (aside from filing an effectless unblock request). If you have a blocked IMEI other than the stated one, this post will not help: it does NOT teach you how to change to an arbitrary IMEI. Legality aside, software-based IMEI change on Galaxy Nexus seems to remain an unsolved problem (unlike some other phones). 

Solution

The gist of my approach is to restore the original, unique IMEI number (it is on the sticker on the back of your phone under the battery) from your phone's /factory/.nv_data.bak file. And if you do your backups right, you shouldn't lose any of your data. The usual disclaimer for hacking guides applies: It worked for me and I believe it works in principle, but I cannot guarantee that it will work for you and I cannot be responsible for any damage. 

The basic ideas/facts behind the solution are:
  1. /factory/.nv_data.bak (and maybe /factory/nv_data.bin too?) stores the system backup of your IMEI (and other information). Note since this file is hidden (its filename starts with a dot), you can only list this file by "$ ls -a"
  2. similarly /data/radio/nv_data.bin stores your current IMEI (and other information)
  3. both files store the IMEI in some non-obvious way. This prevents easy IMEI modification with a Hex editor. This is why we cannot just make up a new IMEI number for your GN, unlike some other phones which lacks such protective mechanisms.
  4. the android system uses salted md5 checksums stored in /factory/.nv_data.bak.md5 and /data/radio/nv_data.bin.md5 to detect tempering of the aforementioned files. We don't know how to generate these salted checksums but a glitch/oversight in ICS (Ice Cream Sandwich, Android 4.0.x) can effectively generate them for us: it logs an offending checksum along with its correct counterpart.
  5. if both nv_data files fail the checksum test, the android system will create a "default" /data/radio/nv_data.bin containing the infamous generic IMEI (along with the unlock status). In fact, F*ckDoCoMo app achieved unlocking GN via this side-effect of tempering nv_data and leaving the checksums out-of-sync. The nice thing is that the app does edit your /factory/.nv_data.bak in a sensible way so your phone will remain unlocked with this nv_data file.

If your /factory/.nv_data.bak has not been overwritten inadvertently -- that is a big "if" which can only be tested by experimentation --, then we should be able to recover your original IMEI by acquiring the correct checksum for /factory/.nv_data.bak

Instructions

(I assume that you are familiar with adb, fastboot, and other basic tools or can easily acquire such knowledge via the Web. Upon requests, I will edit this post to expand/clarify on any unclear steps. The XDA threads mentioned at the end are also helpful.)

0. backup your entire phone to /sdcard with the ClockworkMod recovery (CWMR) boot image's backup utility. In additon, as there is risk that you will lose your unique IMEI forever, you should carefully backup the entire /factory and /data/radio directories onto your laptop/desktop/cloud/etc. You can do that by $ adb pull.

1. install a rooted ICS-based ROM (root is probably not necessary since you can get that in CWMR, but it will make life easier), e.g. cm-9.0.0-maguro-stable from cyanogenmod. The glitch we rely on is fixed in later versions. (I tried JellyBean 4.2 and it was no good.)

2. (You will need root to do this and the following steps.) Take note of the content in /data/radio/log/nv.log
$ cat /data/radio/log/nv.log 
It should look something like this:
Thu Jun 28 19:54:08 2012: /data/radio/nv_data.bin does not exist.
Thu Jun 28 19:54:08 2012: MD5 fail. orignal md5 '672f544c3d4c3c4f5bc699966bac6210' computed md5 '3b93401f8fb129a51aba4e70a8b47fbb' (rild)
Thu Jun 28 19:54:08 2012: MD5 fail. orignal md5 '92d39f2375e581f8bd8095486c8758b1' computed md5 'a4bc620886c51f712caa377adf90cf24' (rild)
Thu Jun 28 19:54:09 2012: default NV restored.
Find the original md5 that is the same as /factory/.nv_data.bak.md5 (in my case, it is 92d39f2375e581f8bd8095486c8758b1) and then you should copy the computed md5 in the same line (so in my case, it is a4bc620886c51f712caa377adf90cf24). The computed md5 is the salted md5 checksum we want. FYI- The other set of md5's corresponds to /factory/nv_data.bin. You don't really need to worry about them unless .nv_data.bak is corrupted and nv_data.bin is not. Then you might want to try the process with /factory/nv_data.bin.

3. Remount /factory as read/write and then replace .nv_data.bak.md5 with the correct salted md5 checksum from last step.
$ mount -oremount,rw /factory
$ echo salted-md5-checksum > /factory/.nv_data.bak.md5

4. $ rm /data/radio/nv_data.bin*

5. $ reboot. Now /data/radio/nv.log should contain no new complaints about failed checksums and the IMEI should be restored to some non-generic number! (If you don't care about restoring your data or the ROM/Android version you were using, you are done now.)

6. restore your backup from /sdcard using CWMR. Note that /data/radio (but not /factory) is replaced by your restored backup, so your IMEI is the generic one again! 

7. Since we have the correct salted md5 checksum in /factory/.nv_data.bak.md5 to go with /factory/.nv_data.bak, you only need to remove /data/radio/nv_data.bin* and then reboot to let the system automatically restore from /factory/.nv_data.bak. Finally, after rebooting, you should see the same non-generic IMEI as what you saw in step 5, while having your phone restored!

If this works and you want to thank me, buy me a cup of coffee and/or follow me on twitter: @falcondai :)


Additional Resource

You can check whether your IMEI is blocked on T-Mobile: http://www.t-mobile.com/VERIFYIMEI.ASPX (004999010640000 is confirmed to be blocked. Such a generic IMEI should never get blocked... maybe someone reported their phone with that IMEI as stolen to T-Mobile?) This IMEI number seems to be a default for many Samsung phones.

According to some people on Reddit, this generic IMEI number was blocked on T-Mobile as early as 2013/2: http://www.reddit.com/r/Android/comments/17yizs/anyone_else_running_a_custom_rom_and_have_your/ But mine somehow managed to survive till recently, about one month ago, i.e. 2013/9. I called T-Mobile to add the generic IMEI number to my account explicitly after the first time it showed symptoms (likely back in February) and that solved the problem for me until it happened again.

My method is inspired mainly by these two threads on XDA:
http://forum.xda-developers.com/showthread.php?t=1606982 (very insightful post that spotted the glitch)

Most, if not all, software-based IMEI modification discussions/methods do not generalize and almost certainly won't help in the case of Galaxy Nexus due to obfuscation in nv_data. (If you find anything applicable, feel free to share them in comments.)