Consistent MAC Address Selection

Hello all,
I had something new happen today. The MAC address changed! Well, it really did not change. But what DID change was the index of the NICs in the list network interfaces.

I was using this code to obtain the MAC address. It always worked. Until today, when I added a TeamViewer VPN Software/Driver to my system.

Dim n as NetworkInterface
n = System.GetNetworkInterface(0)
Mac = n.MACAddress

The new driver became index 0. The problem for me, is that I used the MAC as part of a ID number, integrated into a license key.

Does anyone know how to always get the same MAC? Since this has happened, I wrote code to loop through the available network adapters, but it is far more cumbersome than it was before.

Ideas?
Thanks all!
Tim

I, like you, could never get a reliable MAC address source for this purpose; therefore, went another direction and just created a method that’s based on physical RAM installed and the total capacity of the primary drive partition (add a constant called ‘SALT’ and set a unique value for it):

function getHardwareIdentifier() as string

// - generates a 16-byte unique hardware hash based on total primary drive {c:\\} and memory capacity
  
  soft declare function getdrivetype lib "kernel32" alias "GetDriveTypeA" (byval drive as cstring) as integer
  soft declare function getdiskfreespaceex lib "kernel32" alias "GetDiskFreeSpaceExA" (byval directoryname as cstring, _
  bytesavailable as ptr, totalbytes as ptr, freebytes as ptr) as integer
  soft declare sub globalmemorystatus lib "kernel32" alias "GlobalMemoryStatus" (buffer as ptr)
  
  dim driveBytesAvailable as new memoryblock(8)
  dim driveBytesTotal     as new memoryblock(8)
  dim driveBytesFree      as new memoryblock(8)
  dim ramBytesTotal       as new memoryblock(32)
  dim returnStatus        as int64
  
  returnStatus = getdiskfreespaceex("c" + ":", driveBytesAvailable, driveBytesTotal, driveBytesFree)
  globalmemorystatus ramBytesTotal
  
  return lowercase(encodehex(crypto.pbkdf2(SALT, str(driveBytesTotal.uint64value(0)) + str(ramBytesTotal.uint32value(8)), 3, 16, crypto.algorithm.sha512), false))

end function

By the way, the best method I used for hardware fingerprinting was to create a primary key (only known on my end) and computed a hardware ID on their end. Once they registered with their hardware ID, I took a method of the ‘difference’ and implemented that as PART of their registration key. That difference was used to decrypt STRING values and top-left coordinates of controls within the application itself; therefore, if they tried to bypass my registration and crack my software without knowing this value… all they would get is a scrambled UI (labels & other controls on the window, all containing junk as data). Within the code itself, I would use something like: label1.text = decrypt(“f149c8c2994cf0dd”, regkey + hardwareid). Same with coordinates like label1.top, label1.left. Don’t simply do a boolean check to see if the hardware ID matches a specific key, as that check is easily able to be switched and cracked.