Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

How to generate a unique hardware ID / fingerprint


  • Please log in to reply
37 replies to this topic
Icarus
  • Members
  • 851 posts
  • Last active: Jan 02 2012 11:17 AM
  • Joined: 24 Nov 2005
I am not really familiar with how different applications generate a unique hardware ID key.

I would like to build a registration engine with AHK, that asks the user to enter a license key, based on his hardware fingerprint.

Does anyone have a lead for me?

Thanks in advance

tic
  • Members
  • 1934 posts
  • Last active: May 30 2018 08:13 PM
  • Joined: 22 Apr 2007
you could perhaps hash all the following together into one key:

A_OSType
A_OSVersion
A_Language
A_ComputerName
A_UserName
A_WinDir

tic
  • Members
  • 1934 posts
  • Last active: May 30 2018 08:13 PM
  • Joined: 22 Apr 2007
perhaps see if you can get something like:

<!-- m -->http://grafi.ii.pw.e.../x86/cpuid.html<!-- m -->

to work if youre feeling adventurous

Icarus
  • Members
  • 851 posts
  • Last active: Jan 02 2012 11:17 AM
  • Joined: 24 Nov 2005
Thanks tic,

I thought about these variables, but they are too simple.
The url is definitely adventurous, but is more along the lines of what I am looking for.

Is there a Windows API function that gets some system information about the hardware - one that I can use with DllCall?

tic
  • Members
  • 1934 posts
  • Last active: May 30 2018 08:13 PM
  • Joined: 22 Apr 2007
<!-- m -->http://www.codeproje...omputerinfo.asp<!-- m -->

<!-- m -->http://msdn2.microso...y/ms724381.aspx<!-- m -->

<!-- m -->http://msdn2.microso...y/ms776270.aspx<!-- m -->

and there are many more.....that 1st link will tell you about all of them. please report any results you find! as this would be incredibly useful, especially for trial versions etc...

Mustang
  • Members
  • 421 posts
  • Last active: Dec 26 2010 10:08 PM
  • Joined: 17 May 2007

especially for trial versions etc...

opensource = win

tic
  • Members
  • 1934 posts
  • Last active: May 30 2018 08:13 PM
  • Joined: 22 Apr 2007

opensource = win


not if youre a software developer and you start to use ahk as an alternative to C++ as you can make programs quicker with ahk, because then you have no job! :wink:

Icarus
  • Members
  • 851 posts
  • Last active: Jan 02 2012 11:17 AM
  • Joined: 24 Nov 2005
Many thanks, will check it out.
I am also for open source and nice, free utilities - but it will be nice to know that you can protect your application if you need to, for one reason or another.

besides, it will be a nice experiment and a nice library to add to "Functions and Scripts" no?

tic
  • Members
  • 1934 posts
  • Last active: May 30 2018 08:13 PM
  • Joined: 22 Apr 2007
quickly put this together from cmdret topic. volume serial is quite unique:

SetBatchLines -1
AutoTrim Off

Serial := CMDret_RunReturn("cmd /c Vol")
;RegExMatch(Serial,"is " . ".*" . "\Q-\E" . ".*", Serial)
StringTrimRight, Serial, Serial, 1
StringRight, Serial, Serial, 9
InputBox,OutVar,Vol,The serial of your main volume is:,, 200, 200,,,,, %Serial%


CMDret_RunReturn(CMDin)
{
  VarSetCapacity(lpBuffer,1024)
  VarSetCapacity(sui,68, 0)
  VarSetCapacity(pi, 16, 0)
  VarSetCapacity(pa, 12, 0)
  InsertInteger( 12, pa, 0)
  InsertInteger( 1,  pa, 8)

  IF (DllCall("CreatePipe", "UInt*",hRead, "UInt*",hWrite, UInt,&pa, Int,0) <> 0) {
    InsertInteger(68,    sui, 0)
    DllCall("GetStartupInfo", "UInt", &sui)
    InsertInteger(0x101, sui, 44)
    InsertInteger(0,     sui, 48)
    InsertInteger(hWrite,sui, 60)
    InsertInteger(hWrite,sui, 64)

    IF (DllCall("CreateProcess",Int,0,Str,CMDin,Int,0,Int,0,Int,1,UInt,0,Int,0,Int,0,UInt,&sui,UInt,&pi)<>0) {
      cmdretPID := GetUInt(pi, 8)
      Loop {
        IF DllCall("PeekNamedPipe",uint,hRead, uint,0, uint,0, uint,0, "UInt*",bSize, uint,0) = 0
          break
        Process Exist, %cmdretPID%
        IfEqual ErrorLevel,0, break
        IfEqual bSize, 0, Continue
        VarSetCapacity(lpBuffer, bSize)
        IF (DllCall("ReadFile",UInt,hRead, Str,lpBuffer, Int,bSize, "UInt*",bRead, Int,0) > 0) {
          IFEqual bRead,0, Continue
          DllCall("lstrcpyn", UInt,&lpBuffer, UInt,&lpBuffer, Int,bRead)
          CMDout = %CMDout%%lpBuffer%
          }
        Sleep 0
      } ; Loop
    } ; IF CreateProcess

    DllCall("CloseHandle", UInt, hWrite)
    DllCall("CloseHandle", UInt, hRead)
  } ; IF CreatePipe

  Return CMDout
}

InsertInteger(pInteger, ByRef pDest, pOffset = 0, pSize = 4) {
   Loop %pSize%
      DllCall("RtlFillMemory", UInt,&pDest+pOffset+A_Index-1, UInt,1, UChar,pInteger >> 8*A_Index-8)
}

GetUInt(ByRef pSource, pOffset = 0, Len = 4) {
   Loop %Len%
      result += *(&pSource+pOffset+A_Index-1) << 8*A_Index-8
   Return result
}

but dont stop looking into the cpu stuff, as i would like to know that! :)

Icarus
  • Members
  • 851 posts
  • Last active: Jan 02 2012 11:17 AM
  • Joined: 24 Nov 2005
impressive! :shock:
but i do not understand what you are doing here. i am very DllCall-Neanderthal
going to read cmdret to hopefully get a better clue.

you are talented you know that?

EDIT:
HEY! Did you see this thread by Laszio

Just started reading it so it may not have all the answers, but the beginning looks promising.
Thought Id hurry up and post.

Laszio is also excellent.

tic
  • Members
  • 1934 posts
  • Last active: May 30 2018 08:13 PM
  • Joined: 22 Apr 2007

you are talented you know that?


not really :/ im rubbish with dllcalls!

Laszio is also excellent.


dont think i quite compare :wink:

In addition one can use disk volume identifiers by running the consol command VOL > info.txt:

Volume in drive C has no label.
Volume Serial Number is 24B5-2345

.............

Instead of saving this data in a temporary file, one can use CMDret - return output from console programs [DLL version]


yeh thats what i did on my above post, but didnt use the dll, just used the raw functions i had found on the forums.

Ive come up with a very good way to copy protect a program, but it is a lot of work! involves large amounts of ahk, and php, but is very secure.

What is the reason you are wanting a computer identifier? as i can share my method if you wish.

Edit:

With Lazslos method, Ive only had one read through, but what prevents the user from just deleting the ini and getting another 1 with a new username and email at the end of the 15 day trial?

Icarus
  • Members
  • 851 posts
  • Last active: Jan 02 2012 11:17 AM
  • Joined: 24 Nov 2005
With laszlos method, your AHK software gets the following as input:
username, email, registration code (provided by the software author)

the registration code was generated by the username, email and hardware fingerprint

so, if a wrong registratino code is entered, or if the INI is not found, or if you have replaced some components of your system, the software will not work.

or did i misunderstand your question?

i dont think i want something complicated.
i am now wrapping laszlos concept into some functions, like:
Fingerprint := SWP_GetPcFingerprint()
UserOK := SWP_IsUserAuthenticated( username, email, key )
Key := SWP_GenerateKey( username, email, fingerprint )

so that it will be easy to incorporate as an include and use in your ahk software.

tic
  • Members
  • 1934 posts
  • Last active: May 30 2018 08:13 PM
  • Joined: 22 Apr 2007

i am now wrapping laszlos concept into some functions


yeh good idea. i was thinking something liek this:

SetBatchLines -1
AutoTrim Off

Gui, 1: Add, Text, x10 y10 w100 -Multi -Wrap, Enter username:
Gui, 1: Add, Edit, x120 w250 -Multi -Wrap vUserName
Gui, 1: Add, Text, x10 y+50 -Multi -Wrap, Enter email address:
Gui, 1: Add, Edit, x120 w250 -Multi -Wrap vEmail
Gui, 1: Add, Button, x315 y170 w75 -Multi -Wrap gOK, &OK
Gui, 1: Show, w400 h200, Details

SplitPath, A_WinDir,,,,, WinDrive
RunCommand := "cmd /c Vol " . WinDrive
Sleep, 200
Serial := CMDret_RunReturn(RunCommand)
StringTrimRight, Serial, Serial, 1
StringRight, Serial, Serial, 9
Serial := A_ComputerName . "`n" . Serial
Return

OK:
Gui, 1: Submit
MsgBox, % "Username: " . Username . "`n" . "Email: " . Email . "`n`n" . "Hash: " . "`n" . Serial
Return

CMDret_RunReturn(CMDin)
{
  VarSetCapacity(lpBuffer,1024)
  VarSetCapacity(sui,68, 0)
  VarSetCapacity(pi, 16, 0)
  VarSetCapacity(pa, 12, 0)
  InsertInteger( 12, pa, 0)
  InsertInteger( 1,  pa, 8)

  IF (DllCall("CreatePipe", "UInt*",hRead, "UInt*",hWrite, UInt,&pa, Int,0) <> 0) {
    InsertInteger(68,    sui, 0)
    DllCall("GetStartupInfo", "UInt", &sui)
    InsertInteger(0x101, sui, 44)
    InsertInteger(0,     sui, 48)
    InsertInteger(hWrite,sui, 60)
    InsertInteger(hWrite,sui, 64)

    IF (DllCall("CreateProcess",Int,0,Str,CMDin,Int,0,Int,0,Int,1,UInt,0,Int,0,Int,0,UInt,&sui,UInt,&pi)<>0) {
      cmdretPID := GetUInt(pi, 8)
      Loop {
        IF DllCall("PeekNamedPipe",uint,hRead, uint,0, uint,0, uint,0, "UInt*",bSize, uint,0) = 0
          break
        Process Exist, %cmdretPID%
        IfEqual ErrorLevel,0, break
        IfEqual bSize, 0, Continue
        VarSetCapacity(lpBuffer, bSize)
        IF (DllCall("ReadFile",UInt,hRead, Str,lpBuffer, Int,bSize, "UInt*",bRead, Int,0) > 0) {
          IFEqual bRead,0, Continue
          DllCall("lstrcpyn", UInt,&lpBuffer, UInt,&lpBuffer, Int,bRead)
          CMDout = %CMDout%%lpBuffer%
          }
        Sleep 0
      } ; Loop
    } ; IF CreateProcess

    DllCall("CloseHandle", UInt, hWrite)
    DllCall("CloseHandle", UInt, hRead)
  } ; IF CreatePipe

  Return CMDout
}

InsertInteger(pInteger, ByRef pDest, pOffset = 0, pSize = 4) {
   Loop %pSize%
      DllCall("RtlFillMemory", UInt,&pDest+pOffset+A_Index-1, UInt,1, UChar,pInteger >> 8*A_Index-8)
}

GetUInt(ByRef pSource, pOffset = 0, Len = 4) {
   Loop %Len%
      result += *(&pSource+pOffset+A_Index-1) << 8*A_Index-8
   Return result
}

but may be better as a function.

obviously some kind of hash would be performed on the second part.

or did i misunderstand your question?


thats all well and good, but what i mean is if you do all that stuff and you get a 15 day trial or whatever, and if you delete the ini the program wont work, but whats to prevent you from just requesting another ini?

another step would need to be added to store all the hashes in a database and only send a new key (ini) if a match is not found.

Icarus
  • Members
  • 851 posts
  • Last active: Jan 02 2012 11:17 AM
  • Joined: 24 Nov 2005
Will look at your code a little later, wanna do some coding myself :)

About the trial key, you know how it is - this is the developers responibility to know which user already asked for a key.
As a user, I would not bother to ask for a new key again and again - if i like the software, it is much easier to buy it no?

In addition to this, I intend to check against a web url to see if the user is authorized, and to be able to cancel it from remote.

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
The problem with including the disk serial number (Vol) in the PC fingerprint is that it is easy to change to whatever value you want, without affecting the normal operation of the PC, therefore, it is not very secure. You can even change it back to its previous value after a SW authenticity check. There is a globally unique HW disk ID, which you can get in XP with a few lines of code, but including that in a PC fingerprint causes problems: if you replace your disk, you have to re-register your protected SW. The processor ID, description info is better (and you can get it in AHK without any external tool), because a new processor requires reinstalling Windows, and so all the registered SW.

Also, when you redirect the output of Vol to a temp file and read that back to AHK, it is much simpler and faster than CMDret_RunReturn. If you delete the temp file afterwards, it gets never actually written to disk, lives and dies in the disk buffer.