Grego
Grego

Reputation: 2250

Unique CPU ID on Windows via C++

Well I would like to get an unique CPU ID so I can get an UNIQUE identification for each machine. I did check __cpuid() from windows.h library, but the problem is that the ID it gets, it's the ID of all types of CPU, if you have an I3 Core processor and I have an I3 core processor, it will give the same "Unique ID".

Here is what I came up with to make a CPU ID from the __cpuid() that returns the same information on processors of the same type:

std::string GetCPUID(){

            int CPUInfo[4] = {-1};
            __cpuid(CPUInfo, 0);
             if (CPUInfo[0] < 4)
            return ""; //Error on retrieving

            stringstream st;
            for(int i = 0; i <= 3; i++){ 
                         st << CPUInfo[i];
                    }

            return st.str();

}

I also checked a program called "Hardware ID Extractor" that works fine, it actually returns a UNIQUE CPU ID as the GUI as I wanted, so they made available a DLL so we can extract the CPU ID it generated , I tried everything with the cleanest code with the DLL and following their example but it seems that it returns nothing when ran on Windows 7. a lot of other people were complaining about this on Windows 7 via the DLL, even though the GUI on windows 7 returns the correct CPU ID.

Showing my work in the Hardware ID Extractor,

Here is the site where I downloaded the DLL (Where I chose the link of C++, VB, .NET): http://www.soft.tahionic.com/download-hdd_id/free-download/free%20download.html

And here is the DLL itself to download: http://www.soft.tahionic.com/download-hdd_id/free-download/DLL%20compressed/HardwareIDExtractorC.dll

This is the code I got from Hardware ID Extractor (I'm using Visual Studio 2008):

#include <iostream>
#include <windows.h>
#include <conio.h>
using namespace std;

int main (){

    char* (__stdcall *GetIDESerialNumber)(BYTE);

    HINSTANCE DllInst = NULL;
    if (DllInst == NULL) DllInst = LoadLibrary("C:\\HardwareIDExtractorC.dll");
    printf( "LoadLibrary error %d\n", GetLastError() );
    if (DllInst) {
        GetIDESerialNumber = (char* (__stdcall*)(BYTE))GetProcAddress(DllInst, "GetIDESerialNumber");

    //Now call the imported function
        cout << "SN: " <<  GetIDESerialNumber(0);   // 0 = first IDE hard drive in your system 
    }else{
        printf(" - Not Loaded");
    }

    _getch();



return 0;
}

In the visual studio output it shows that the DLL was executed by saying:

'Test.exe': Loaded 'C:\HardwareIDExtractorC.dll', Binary was not built with debug information.

And the program output that I get is: LoadLibrary error 998 - Not loaded

Someone know what I can do to get a CPU ID Unique, like in the application Hardware ID Extractor? I need to get a CPU ID because if I get HDD information, the user may format their Hard Drive and the program will stop working, as I'm designing it to work only that specified computer.

I'm using Windows 7 32 bits Ultimate and Intel I3 Core Processor (if that helps in anyway).

I hope I was clear in my question. Thanks in advance!

Upvotes: 1

Views: 19825

Answers (2)

IceCold
IceCold

Reputation: 21154

Hardware ID Extractor is reliable and easy to use. I have it. Because I purchased the DLL and the source code long time ago I didn't had to purchased the upgrades. I just changed the code by myself.

Hans thanks for the answer, you know this program called "Hardware ID Extractor" it claims it retrieves a CPU ID

Yes. The DLL provides not only the CPU ID and the HDD IDE ID but many other hardware related statistics (IDs). I have tried it on multiple CPUs (both AMD and Intel) and it works like a charm.

The scheme

The cheapest 'protection' is the serial number. That just sucks big time. A single mindless customer makes it available on Internet and everybody has your program FOR FREE! Not mentioning that ‘hackers’ today don’t bother to break your software protection. They will buy your software with a fake credit card and will publish the key on web OR they will buy the software with a valid credit card and then they will use the 30 days money back policy to get the money back. Some mad software resellers such as Plimus (yes, stay away from Plimus) are enforcing this on the software vendors. Classic serial numbers are as dead as dinosaurs.

The other recommendation, the server-based protection, is also not good at all. A bit harder to cheat by fake credit card ‘hackers’ and also won’t leak keys all over the Internet. But you will lose at least half of your customers because these days everybody has a firewall/antivirus that will block your program from connecting to the server. And what about those that are mobile? Or that have only random/rare access to internet? I don't even dare to speak about those that are working behind of the firewall of an institution/company/organization. Most of those companies are 'ruled' by mindless network administrators that cut ANY program except Internet Explorer (not even Firefox) from accessing the Internet. I have been there. I have done that. Believe me, IT IS NIGHTMARE! In other to have a program connected to internet you have to go to administration fill lots of request forms and finally MAYBE, MAYBE, they will let the program access the Internet. Through a proxy maybe.

Anyway, it is quite easy to do a reliable key-based based protection for your program: send a key to the customer BUT don't send a classic key but a hardware-based key. This way the key will work only in that SPECIFIC system. You can even post an announcement on your web site: "Please feel free to make this key public. I don't give a damn" :)

Just don't rely on a single hardware ID (CPU only for example) but on all of them. Allow the user to change/upgrade all its hardware components except one. So, as long as they won't change the entire computer the license will work. Since a new computer is purchased every 3.4 years (I have found the statistics on Internet) you should allow the user to ask for 3 new keys (license reactivation). Probably you will release a new version before the 3.4 years interval expires. So, the customers will have to buy the upgrade and get a new key anyway.

Upvotes: 3

Hans Passant
Hans Passant

Reputation: 941465

You cannot make this work. Intel introduced a Processor Serial Number back in the Pentium III design, readable with cpuid. That raised a huge stink because of privacy concerns and Intel was forced to back down. The feature got removed in later Pentium III designs and has never been put back.

You are going to have to use another source for a fingerprint. Don't use just one, collect a bunch and only declare it invalid when more than one changed. Use the NIC MAC address, RAM size, disk volume serial number, stuff like that. There are already thousands of questions about that at SO.

Upvotes: 3

Related Questions