I was able to "break" my IMEI, i.e., set it to the infamous 004999010640000, via the following procedure (derived from http://forum.xda-developers.com/show....php?t=1264021 ):
0. Get an adb root shell
1. Back up the contents of `/factory`, e.g., with `adb pull`
2. Remount the `/factory` filesystem read-only with `mount -oremount,rw /dev/block/mtdblock0 /factory`
3. Delete `/factory/nv_data.bin` and `/factory/nv_data.bin.md5`
4. Delete `/data/radio/nv_data.bin` and `/data/radio/nv_data.bin.md5`
After this, the IMEI was reported as 004999010640000. Then I was able to restore my IMEI to its original value as follows:
0. Restore `/factory/nv_data.bin` (owned by root)
1. Restore `/data/radio/nv_data.bin` (owned by radio)
So it seems clear that the IMEI reported by the device depends on the contents of the firmware. But it's possible that the radio unit is hard-wired to only be in two possible states, 004999 and the true IMEI.
`/data/radio/nv.log` has log lines from code attempting to read `nv_data.bin`, in particular:
Fri Aug 24 01:10:53 2012: MD5 is turned on.
I searched all the repositories in the Google Android codebase for the string "MD5 is turned on" and couldn't find the code that generates this log line. Is it possible that it's generated by a proprietary binary blob?
So, the open questions:
1. Where is the code that knows how to interpret nv_data.bin?
2. Does nv_data.bin actually contain the IMEI?
Thanks for your time!