Jaa


GetDeviceUniqueID

There is a new API available for retrieving a device id in Windows Mobile 5.0 for both Pocket PC and Smartphone. The first question: why do we need a new way of getting the device ID, what’s wrong with the old? To answer this you need to know what a device ID is. There is a very good and detailed explanation here, but in essence it’s a 16 byte code derived from hardware specific information that is unique to each device. This ID is not the same as an IMEI or a phone number found on a phone based device, both of which can be changed, but instead this code lives and dies with the device.

So the device ID is a very useful thing for software that wants to target just your device, e.g. copy protection, or to provide immutable identity to web service calls. Equally so it’s a resource that should be protected to mitigate the risk of identity theft.

Getting at the device id is relatively straight forward but requires either some C++ or a reasonable amount of interop code. The api is something like this:

KernelIoControl(IOCTL_HAL_GET_DEVICEID, 0, 0, buffer, GuidLength,out, bytesReturned);

Protecting Device ID has always been present as part of the Smartphone security model by making the KernelIoControl API a privileged operation, meaning your code must be running in the trusted code group to be able to access this API. But there are two problems with this:

1> Up to and including Pocket PC 2003SE there is no security model to protect the API, so Pocket PC didn’t have any protection on the Device ID.

2> what do untrusted applications do when they want to get access to this API?

3> having lots of applications read and use the device id potentially increases the attack surface for identity theft.

GetDeviceUniqueID attempts to address these issues and to reduce applications dependency on the precious device id. Firstly GetDeviceUniqueID can be called from the trusted or untrusted code group, but the code returned is not the same as a call to KernelIoControl, its a 20 byte code not a 16 byte code. GetDeviceUniqueID takes an additional parameters of an application defined char array, and uses a one way hash to combine the real device id and the char array parameter to generate the new 20 byte code. This means that an application will always get the same 20 byte code if it calls GetDeviceUniqueID on the same device, with the same char array. It also means there is no practical way of asserting the true device id from the 20 byte key an application uses.

This is a native API exposed by coredll.dll so here is a managed code snippet showing how to get the info through interop. Standard Code disclaimer applies

/*

HRESULT GetDeviceUniqueID(

  LPBYTE pbApplicationData,

  DWORD cbApplictionData,

  DWORD dwDeviceIDVersion,

  LPBYTE pbDeviceIDOutput,

  DWORD* pcbDeviceIDOutput

);

*/

[DllImport("coredll.dll")]

private extern static int GetDeviceUniqueID([In, Out] byte[] appdata,

                                            int cbApplictionData,

                                            int dwDeviceIDVersion,

                                            [In, Out] byte[] deviceIDOuput,

  out uint pcbDeviceIDOutput);

private byte[] GetDeviceID(string AppString)

{

    // Call the GetDeviceUniqueID

    byte[] AppData = new byte[AppString.Length];

    for (int count = 0; count < AppString.Length; count++)

        AppData[count] = (byte)AppString[count];

    int appDataSize = AppData.Length;

    byte[] DeviceOutput = new byte[20];

    uint SizeOut = 20;

    GetDeviceUniqueID(AppData, appDataSize, 1, DeviceOutput, out SizeOut);

    return DeviceOutput;

}

The full project code is here.

 

Marcus

Comments

  • Anonymous
    January 19, 2006
    Hi

    Thanks for this, it's working without any problem. For a project I need to have this in VB.NET but I can't seem to convert it correctly with some tools on the net...

    Could you post the VB.NET-Code of this?

    Thanks

    Sven

  • Anonymous
    January 20, 2006
    Using the same salt but on 3 different smartphone mobile 5 devices I'm getting back the exact same ID. I do not have that problem on CE mobile 5 devices. Has anyone seen this problem? Thanks.

  • Anonymous
    January 20, 2006
    Hi Joe, Can you e-mail me and tell me which models of smartphones you're seeing this behavior with? (scyost at microsoft.com) Thanks, Scott

  • Anonymous
    January 20, 2006
    Scott, I just did. Let me know if you don't received it. Thanks.

  • Anonymous
    February 01, 2006
    Thanks for the couple of references and the information. The documentation in CE5.0 for IOCTL_HAL_GET_DEVICEID is incorrect. They have transposed the description of the Platform and Preset ID and there is no restriction/recommendation to the length of the returned ID. This created some incompatibilities for our device with other third party SW until we implemented it as a standard GUID with the description of Platform and Preset ID as per 4.1 documentation.

  • Anonymous
    February 02, 2006
    HI,
    I have the same problem too. The GetDeviceUniqueID returns the same number on O2 Atom even for different devices. But the same routine works perfectly fine on Dell X51V.
    Is there any solution ?

  • Anonymous
    February 03, 2006
    The unique part of the data that goes into that function comes out of the BSP for the platform. The OEM implements that code, so I can't comment that behavior.

  • Anonymous
    February 08, 2006
    Has anyone found a solution to this? We really need to find a way to uniquely identify the device so that we can protect our software... and we have found several devices giving the same results using GetDeviceUniqueId.

    So, it seems that the OEMs have once again spoiled the party.

    We then thought of combining the results from GetDeviceUniqueId with the "old" KernelIoControl(IOCTL_HAL_GET_DEVICEID), but still that shows the same results on some devices.

    So, what else is left to determine the uniqueness of the device? We are thinking of the Bluetooth Address and the WIFI card MAC... but is that guaranteed to be unique? I mean, if the OEMs can't correctly implement GetDeviceUniqueId() then how can we be sure that they haven't done the same mistake with any piece of hardware that comes inside the device.

    Advise anyone?

  • Anonymous
    February 09, 2006
    I was able to use KernelIoControl(IOCTL_HAL_GET_DEVICEID), instead of GetDeviceUniqueId(), to get a unique ID on SP mobile 5 devices.  Of course the app has to be signed or it won't work.

  • Anonymous
    February 14, 2006
    The comment has been removed

  • Anonymous
    February 17, 2006
    use windows

  • Anonymous
    February 23, 2006
    Sorry to digress from device id. I just remembered mid last year there were news that Flextronics was making ready (nearly complete) a lowcost WM5 unit code name Peabody.

    I cannot find any more news regarding that development? Has it evaporated?

    Thanks for sharing your info

  • Anonymous
    March 14, 2006
    Is it possible to get the IMEI number for windows mobile 2003 for smartphones?

  • Anonymous
    April 05, 2006
    At our Technet Mobility event we asked the attendees to text questions to us for the Q&amp;amp;A session......

  • Anonymous
    May 18, 2006
    I am developing an application for the smartphone platform (windows mobile 2003, second edition), in my case a secure phone. I need to get an unique device information in order to implement a copy protection for my application.The GetDeviceUniqueID  is a very nice solution, but only works with windows mobile 5.
    Do you have an easy solution for this kind of problem that doesn't need the privileged access to the kernel functions using certificates?

  • Anonymous
    May 21, 2006
    is there any guarantee that an application, using the same AppData, will always get a different DeviceID when calling GetDeviceUniqueID an different devices?

    Or is there a mathematical chance that two different devices will return the same DeviceID ?

  • Anonymous
    July 09, 2006
    Can this code work with windows mobile2.0..?

  • Anonymous
    July 17, 2006
    Is it a IMEI of Pocket PC and SmartPhone
    Can it work on all device

  • Anonymous
    July 26, 2006
    When I run this code within my VB .Net (CF 1.0) Application for WM 5.0 on Pocket PC, I just get back an empty Byte Array. Anyone an Idea why this might happen?

  • Anonymous
    August 10, 2006
    智能设备的唯一编号,可以用于实现更好的智能设备软件的授权机制,还可以利用它来限制智能设备客户端软件访问后台服务的权限,从而提高系统的安全性。本文介绍了获取智能设备唯一编号的各种方法。

  • Anonymous
    August 10, 2006
    http://www.cnblogs.com/upto/archive/2006/08/11/GetDeviceUniqueID.html

  • Anonymous
    August 22, 2006
    Thanks for the code snippet to get the unique ID...

    Not sure where to ask this, so I'll ask here.  How does one programmatically check for presence of the following hardware on a given WM device?

    - infrared
    - bluetooth
    - wi-fi
    - camera

    I would've also added 'keyboard' to this list, but I already saw your post on how to do this.

    Any insight is greatly appreciated!
    Keith

  • Anonymous
    September 22, 2006
    private byte[] GetDeviceID(string AppString)


    what's parameter AppString used?

    what's "AppString" means?How can I catch it?

  • Anonymous
    September 23, 2006
    It's a string that identifies the caller of the API. It gets hashed into the data that is returned, so different callers will get different results. There's more explanation on the MSDN page.

  • Anonymous
    September 27, 2006
    How do you retrieve the imei from a Pocket PC Phone Edition or smartphone?

  • Anonymous
    October 26, 2006
    Anyone know whether MS have fixed the problems with this API call?  If not should we be reverting back to KernelIoControl() call with signed applications?

  • Anonymous
    November 29, 2006
    How does knowing a deviceID pose an identity theft threat? Mike Landis http://pnmx.com

  • Anonymous
    December 20, 2006
    iam having the same problem with GetDeviceUniqueID. It is always the same on my Qtek 8310 and Orange C600, the ID i get is: 8EE62802387C5E9E2B7892DDAED3ECE6AB0CE2E2 please paste yours!

  • Anonymous
    January 03, 2007
    Feel free to a free trial of LicenseKey2Go.

  • Anonymous
    January 29, 2007
    Is there any way out  to retrieve Pocket PC DeviceID from a desktop application? Please help me in this context iff any solution exists.  

  • Anonymous
    February 12, 2007
    Any way to Get Owner name for device

  • Anonymous
    April 16, 2007
    The comment has been removed

  • Anonymous
    April 17, 2007
    GetDeviceUniqueId and the IOCTL method will give you different data back. That's expected.

  • Anonymous
    June 11, 2007
    is there any problem using GetDeviceUniqueID() native call in Windows Mobile 5.0 I'm getting always the same result a list of 0000000000, in my emulator. is there any difference using KernelIoControl() I heard that the function returns a 16 bytes instead of the 20 on GetDeviceId, but how really affects my software, that issue? My mail is jpena@isthmusit.com Thanks,

  • Anonymous
    June 19, 2007
    I got the device ID by using your code. But I still have another problem. I want to get the device ID via desktop programm. How can I do? I want use it like this: There is a winform has a button and a textbox in it. When click the button,the win programm to get the device ID and show it in the textbox(device already connected to the PC by ActiveSync). Is there has a solution? Thanks. My mail is burningsnow@163.com

  • Anonymous
    June 21, 2007
    获取 Windows Mobile 设备的唯一标识各种方法。

  • Anonymous
    September 07, 2007
    thanks a lot, i am get the guid successfuly!

  • Anonymous
    October 14, 2007
    It's not the problem with OEMs. It is problem with Microsoft who didn't controlled OEMs. This would never happen on Symbian devices. Someone should pay for GetDeviceUniqueID non working.

  • Anonymous
    October 18, 2007
    Anyone who have managed to use the GetDeviceUniqueID or the IOCTL_HAL_GET_DEVICEID so that it corresponds to the device id shown in Exchange 2003/2007?

  • Anonymous
    October 25, 2007
    is the deviceid that shows up in the exchange 2003 interface related to the imei or meid of that device? is there a way to find the device id based on the imei/meid or vice versa?

  • Anonymous
    October 30, 2007
    Can I use the hashed output of KernelIoControl as the unique identifier of the mobile device? Thanks.

  • Anonymous
    October 31, 2007
    You can do that if you want, but don't count on being able to call IOCTL_HAL_GET_DEVICEID on Windows Mobile Standard/Smartphone or in future versions. GetDeviceUniqueId is the supported way to do it.

  • Anonymous
    February 21, 2008
    Thanks for this post.  I would like to access the "Device Serial No" on our Windows Mobile 5 device programmatically.  This is the number that can be found in settings->system->systemInformation->identity->device serial no.   Can anyone tell me how to access that number?  It doesn't seem to be in the registry. We need to access it to do inventory tracking.  It matches the bar code on the device. Thanks!

  • Anonymous
    February 21, 2008
    @MK: That control panel is provided by the OEM, not Microsoft, so I don't actually know what it's doing. Does it match anything like what IOCTL_HAL_GET_DEVICEID returns?

  • Anonymous
    February 29, 2008
    Thanks, Scott.  No, it doesn't match any part of the value returned by IOCTL_HAL_GET_DEVICEID.  There may be some hidden relationship there, but I don't see it in any case.  There is a file call SystemInfo.cpl in Windows, but it appears to be a ROMMODULE file and hence I can't seem to read it.  Any suggestions there?

  • Anonymous
    March 01, 2008
    No, you won't be able to easily read the contents of the in-rom binaries. Try calling that IOCTL with both the sizeof(UNIQUE_DEVICEID) and the sizeof(DEVICE_ID). Sometimes it's implemented to return a different value in those cases. Maybe one of those values is the one you're looking for.

  • Anonymous
    March 28, 2008
    Can someone tell me if the results of GetDeviceUniqueID remain the same after a device is upgraded from wm5 to 6/6.1?

  • Anonymous
    March 28, 2008
    The simple answer is "yes" The complicated answer is: We require of our partners that the results of that API are consistent in the field. If you buy a WM5 device and the OEM provides an upgrade to WM6, it is one of our requirements that the ID does not change. We have some certification tests around it. There are cases where it would have to change, like if the WM5 version were returning inconsistent results. In those cases we waive the test in favor of fixing the behavior.

  • Anonymous
    March 28, 2008
    Thanks for the info, Scott.  I appreciate it.

  • Anonymous
    March 30, 2008
    We have two E-TEN Glofiish X600 devices here and GetDeviceUniqueID returns exactly the same value for them. This method is definitely not reliable.

  • Anonymous
    April 22, 2008
    The comment has been removed

  • Anonymous
    May 10, 2008
    Hi, this function is not supported by WM because the file Pkfuncs.h is missing. Where can i get this file ?

  • Anonymous
    May 20, 2008
    Translation for vb.net Declare Function GetDeviceUniqueID Lib "Coredll" (ByVal appdata As Byte(), ByVal cbApplictionData As Integer, ByVal dwDeviceIDVersion As Integer, ByVal deviceIDOuput As Byte(), ByRef pcbDeviceIDOutput As Integer) As Integer Private Function GetUniqueDeviceId() As String        Dim AppString As String = "Appication Name"        Dim AppData(AppString.Length) As Byte        Dim count As Integer = 0        While count < AppString.Length            AppData(count) = Convert.ToByte(AppString.Chars(count))            count += 1        End While        Dim appDataSize As Integer = AppData.Length        Dim DeviceOutput(20) As Byte        Dim SizeOut As UInteger = 20        GetDeviceUniqueID(AppData, appDataSize, 1, DeviceOutput, SizeOut)        Dim sb As StringBuilder = New StringBuilder()        Dim x As Integer = 0        While x < DeviceOutput.Length            sb.Append(String.Format("{0:x2}", DeviceOutput(x)))            x += 1        End While        Return sb.ToString()    End Function

  • Anonymous
    June 04, 2008
    This code compiles OK but produced zeros. I found success using an 11+ AppString. Carriers want to hide the natural ID and don't want it found out too easily. using System; using System.Runtime.InteropServices; //needed to use [dllimport], <dllimport> in vb.net namespace sdGetID {    public class GetDeviceIdentity_Class    {        [DllImport("coredll.dll")]        private extern static int GetDeviceUniqueID([In, Out] byte[] AppData, int cbApplictionData, int dwDeviceIDVersion, [In, Out] byte[] deviceIDOuput, out uint pcbDeviceIDOutput);        // The article shows getting more then one ID so I added        // IDVer as an integer - only 1 works but left it in.        public byte[] GetDeviceID(string AppString, int IDVer)        {            // Call the GetDeviceUniqueID            byte[] AppData = new byte[AppString.Length];            for (int count = 0; count < AppString.Length; count++)                AppData[count] = (byte)AppString[count];            int AppDataSize = AppData.Length;            byte[] DeviceOutput = new byte[20];            uint SizeOut = 20;            GetDeviceUniqueID(AppData, AppDataSize, IDVer, DeviceOutput, out SizeOut);            return DeviceOutput;        }    } }

  • Anonymous
    August 05, 2008
    im using this code to get device unique id. it works well in wm5.0 and 6.0 but it not works on windows mobile 2003(pocketpc and smartphone). it throws missing method exception.. is there any other way?

  • Anonymous
    December 13, 2008
    Thanks for your info... the Vb.NET sample will help me a lot.

  • Anonymous
    February 09, 2009
    I've read through all these comments and the question is...  Does GetUniqueDeviceID return a unique ID or not?  At least 3 people are saying the ID's returned from different devices are the same, but the author has not commented on this?

  • Anonymous
    February 28, 2009
    The comment has been removed

  • Anonymous
    March 01, 2009
    While there is not a comprehensive list of devices affected, we are aware of some older device models that do not have a unique device ID.   Since the rollout of our certification tests (during the Windows Mobile 6.x era), OEM devices are now required by Microsoft to have a unique device ID.  This blog entry is thus only relevant for getting the unique device ID of properly certified devices.

  • Anonymous
    March 03, 2009
    GetUniqueDeviceID and IOCTL_HAL_GET_DEVICEID gives the same values on different devices Gigabyte GSmart MS802 with WM6 (5.2.1623).

  • Anonymous
    March 10, 2009
    Got this link from google on searching for "retrieve imei windows mobile" . http://www.venkydude.com/?p=31 Will this work?