Android: IMEI number and the emulator

Update: Please see my latest post about this topic.

It is a common practice for mobile applications to identify the user by IMSI number (associated with the SIM card) or IMEI number (unique ID of the device). Of course, it is also possible on Android:

TelehponyManager manager = (TelehponyManager)getSystemService(TELEPHONY_SERVICE);
String imei = manager.getDeviceId();
String imsi = manager.getSubscriberId();

This code works perfectly fine on a real device, however under emulator IMEI is always all-zero and it’s not configurable. It quickly becomes awkward when debugging a network-enabled application which uses IMEI as a user ID.

Trying to resolve the problem I first looked at the TelephonyManager service, just to find the following snippet:

    private IPhoneSubInfo getSubscriberInfo() {
        // get it each time because that process crashes a lot
        return IPhoneSubInfo.Stub.asInterface(ServiceManager.getService("iphonesubinfo"));
    }

Fair comment, isn’t it? It really made my day 🙂

Anyway, code analysis shows that IMEI/IMSI request goes down through all the telephony layers (see the diagram), eventually getting to  the baseband device. In case of emulated system, rild daemon is used together with libreference-ril.so – reference Vendor RIL library which talks to the baseband modem device using plain, old AT commands.

The modem device itself is emulated outside the Android system, as part of qemu (which is the heart of the emulator). Details of the communication between the emulator and the Android system running inside the emulator are interesting on its own (all the communication goes through a virtual serial port, Android system’s qemud daemon is used to (de)multiplex the data). I’ll try to post a brief introduction to the topic soon.

Virtual modem implementation can be found in external/qemu/telephony/android_modem.c. The most important part of the file is this function:

const char*  amodem_send( AModem  modem, const char*  cmd );

This function is called for each received AT command. For each command sDefaultResponses array is searched for a given command and either predefined response is sent, or a command handler is executed. The array itself looks like:

static const struct {
    const char*      cmd;     /* command coming from libreference-ril.so, if first
                                 character is '!', then the rest is a prefix only */

    const char*      answer;  /* default answer, NULL if needs specific handling or
                                 if OK is good enough */

    ResponseHandler  handler; /* specific handler, ignored if 'answer' is not NULL,
                                 NULL if OK is good enough */
} sDefaultResponses[] =
{
    /* ... */
    { "+CIMI", OPERATOR_HOME_MCCMNC "000000000", NULL },   /* request internation subscriber identification number */
    { "+CGSN", "000000000000000", NULL },   /* request model version */
    /* ... */
};

Two array rows cited above are responsible for IMSI and IMEI retrieval. As you can see, both values are hardcoded and there is no chance to modify them without recompiling the emulator.

However, an old-school hack comes in handy. The emulator binary is not encrypted nor compressed, so the string literals should be visible inside the emulator binary. In fact they are, and IMEI number can be modified in a few simple steps:

  • backup the emulator binary
  • open the binary with your favourite hex editor
  • search for +CGSN string followed by a null byte, it should be followed by 15 digits of the IMEI number
  • edit the number, be careful not to change the number of digits
  • save the file, that’s all!

Sure, it’s not a perfectly comfortable solution, yet better than nothing. In the next part I’ll explain how to make IMEI number a configurable option. Enjoy!

29 Responses to “Android: IMEI number and the emulator”

  1. Tony Says:

    Sorry if this is a silly question, but which binary file are you referring to? It’s not the SDK Setup executable I assume?

    • codepainters Says:

      No, I refer to the Android emulator binary. Look for a file named emulator.exe on Windows (I’m not sure, I have no Windows machine here), and emulator on Linux/Mac.

  2. PL Says:

    Thank you! I can now modify both IMEI and IMSI. But do you have any idea where we can modify the 20-digit sim serial number?

  3. codepainters Says:

    You should look at sim_card.c, it seems to contain hardcoded responses to AT commands requesting various SIM card records. I believe it can be hacked in the same way as IMEI or IMSI.

    However, unfortunately, I’m not familiar with AT commands for GSM modems enough to guess which response needs to be modified. I suggest consulting some modem reference manual.

    Look here, search for answers[] :

    http://android.git.kernel.org/?p=platform/external/qemu.git;a=blob;f=telephony/sim_card.c;h=a5a32498d5eab3bcfa5693757230cd85ebf89940;hb=HEAD

  4. John Ray Says:

    I would like to change the IMEI of my ADP2 developer phone, as the emulator cannot provide the functionality that I need for testing purposes.

    Do you know if the IMEI behaves the same way on actual hardware?

    Cheers

    • codepainters Says:

      Nope, it is so easy to change in the emulator because the whole GSM modem is emulated by code running in QEMU, sending hardcoded responses. On real hardware the telephony subsystem will communicate with a real GSM modem. For sure it is possible to hack it around, but it is far from being that trivial.

  5. GuZ Says:

    I seem to be too stupid to find this string with a hex editor. Or at least im finding serveral .. and don’t know which one the right one is.

  6. GuZ Says:

    Thanks for the fast reply.
    I think if found it now …
    So it seems like it didnt change in the new version.

    How can i see what my IMEI on my virtual device is?

  7. GuZ Says:

    And sometimes changing IMEI results in connection issues on my SDK. Is that normal?

  8. GuZ Says:

    To explain what i am trying to do: im trying to run an app on the SDK and try to connect to it.
    This all works ..but i of course connect on a test-account. Everyone connects into this account using the SDK.
    So i thought changing the IMEI or the IMSI would identify my SDK as “another” phone and would allow me to create a new account.
    Changing the IMEI does nothing. Changing the IMSI results in connection-problems.

    Is there any other ID that could probably be the one this app is checking? Device_ID or something like this?

  9. Samik Says:

    So, I am guessing, that I can’t spoof different IMEI for different AVD’s with this trick, right? I test on various AVD’s and would have ideally liked each emulator reporting different IMEI’s.

    • codepainters Says:

      Indeed, if you edit the emulator binary the way I’ve described, all your AVD’s would share the same IMEI. As a workaround, you can use multiple copies of the binary (but that would only work if you spawn the emulator manually).

      I have done a little patch adding the IMEI number property to the AVD configuration file. It works, but is not really a clean solution, so I’ve never published it. Perhaps it’s worth posting it upstream to Google 🙂

      • John Says:

        I would love to have a copy of that package if you could provide it to me before I wait for the update from Google. I could keep it to myself if you would like to. I am testing my program, and not being able to use different IMEI for different AVD is a blocking issue for me. Thank you in advance!

      • codepainters Says:

        What is your development platform? I’ve only tried that change on Linux, building the SDK for Windows is a painful process according to Google, I haven’t tried it myself (as I rarely use Windows, anyway).

  10. John Says:

    Unfortunately my development platform is Windows. I could probably search for how to compile it online though. Did you get the Android source using git? Thanks!

  11. CVirus Says:

    Thanks a lot that was really useful to me. I hope they provide an easier way to alter the IMEI and SIM serial numbers in the future versions of the emulator.

    Thanks again 🙂

  12. Adrian Says:

    Hi, is this to change the IMEI on an Android phone? or is it for other purposses? if that’s the case then i’m really interested 🙂

    • codepainters Says:

      No, it has nothing to do with real phones, it’s for emulator only. It’s for developers of Android applications that e.g. use IMEI/IMSI to identify the user. Keep in mind that changing the IMEI of a real device is pretty much illegal, and usually done to reenable a stolen phone. Thus, you won’t see any hints about hacking the real phone’s IMEI on my blog.

      Also, note that my blog has moved to http://blog.codepainters.com

  13. Prasenjit Says:

    Hi excellent! Great article, really helped in testing apps which permit registration against single imei no. 🙂
    Thanx!

  14. Sindhu Says:

    I made changes in binary file now the emulator IMEI Number is displayed like this: 0375839278758463+CUSD=2
    But i want exactly 15 number what can do for this?

  15. sauby Says:

    changing the imsi number leads to network connection error i.e. I cannot connect to the internet. Is there a way to fix it??? please advise.

  16. Archit Says:

    I recently lost my LG Optimus 2X and rumors about changing IMEI number has scared the sh** out of me.

    Please tell me very honestly if it is possible to change the IMEI number on my phone and more importantly how easy will it be for someone to do it and how can the phone be recovered.

    Your work has prompted me to ask you this. I believe this is hard coded and it should be extremely difficult to do(change) so. Please reply soon as I have lodged a complaint and waiting to get things moving really fast as I have a lot of personal data in it.

  17. Zzzz Says:

    thanks for the excellent post


Leave a reply to Samik Cancel reply