Notifications
Clear all

[Closed] Get the right MacAddress

Hi,
I’m using the MacAddress of a machine to lock a script to that particular hardware. I’ve seen plenty of samples on how to get the MacAddress. But there are always multiple addresses. How do I pick the right one? To avoid issues, I’d need the address of an ethernet port. Since that doesn’t tend to change (often).
This is my function

function fn_getMacAddress &macAddress debug:false = 
(
	/*<FUNCTION>
	Description
		gets the most viable mac address. More likely to be unique than the cpuid
	Arguments
		<string> macAddress: the mac address
	Return
	<FUNCTION>*/
	
	local lowestIndex = 1000000
	local mgmtObject = undefined
	macAddress = undefined

	try
	(
		--this query gets all network adapters. this includes a bunch of crap but also vpn and virtual machines. these need to be filtered out.
		--we're looking for the actual network adapter.
		dotnet.loadAssembly @"System.Management.dll"
		local searcher = dotnetObject "System.Management.ManagementObjectSearcher" "SELECT * FROM Win32_NetworkAdapterConfiguration"
		local collection = searcher.get()
		local enumerator = collection.GetEnumerator()
		while enumerator.MoveNext() do
		(
			local currEnum = enumerator.current
			if debug do
			(
				format "Index: %
" currEnum.item["Index"]
				format "Description: %
" currEnum.item["Description"]
				format "DNSDomain: %
" currEnum.item["DNSDomain"]
				format "ipEnabled: %
" currEnum.item["ipEnabled"]
				format "MacAddress: %
" currEnum.item["MacAddress"]
				format "DefaultIPGateway: %

" currEnum.item["DefaultIPGateway"]
			)					
			--get the item which is ip enabled and has a mac address with the lowest index
			--the higher the index,, the later the adapter has been added. You normally have the physical adapter to connect to the internet
			--first and later you might install vpn of vm's
			if currEnum.item["Index"] < lowestIndex \
			AND currEnum.item["IPEnabled"] == true \
			AND currEnum.item["MacAddress"] != undefined do
			(
				lowestIndex = currEnum.item["Index"]
				mgmtObject = currEnum
			)
		)
		
		if mgmtObject != undefined do
		(
			macAddress = mgmtObject.item["MacAddress"]

		)
	)catch
	(
		MessageBox "Couldn't get hardware info from your computer" title:"Can't get hardware info"
	)
	
)

When I run this code I get 18 hits. I then filter out the ones which are IP enabled and which actually have a MacAddress. This leaves me with three candidates

Index: 7
Description: Broadcom NetLink (TM) Gigabit Ethernet
DNSDomain: home
ipEnabled: true
MacAddress: 18:03:73:E2:8E:AD
DefaultIPGateway: #("192.168.1.254")

Index: 15
Description: VirtualBox Host-Only Ethernet Adapter
DNSDomain: undefined
ipEnabled: true
MacAddress: 0A:00:27:00:00:00
DefaultIPGateway: undefined

Index: 18
Description: TAP-VyprVPN Adapter V9
DNSDomain: undefined
ipEnabled: true
MacAddress: 00:FF:84:8D:09:A2
DefaultIPGateway: undefined

The first one is the actual connection to the internet, the second one is a virtual machine and the third one is my VPN. Currently I pick based on the index. I pick the item with the lowest index. But I’m wondering if there’s a surefire way to pick the most stable macaddress.

48 Replies
1 Reply
(@polytools3d)
Joined: 10 months ago

Posts: 0

Is this for software protection or to be used in a controlled environment?

Thanks Denis,
that code does give me the same three macaddresses my code finds. However in a different order. And it seems the System.Net.NetworkInformation.SystemNetworkInterface doesn’t provide a way to discern between a physical network interface and a virtual machine or vpn.
So, from the list of mac addresses it generates I wouldn’t know which one to pick.

Why can’t you check the ‘allowed MacAddress’ against these three ones?
Your purpose was just “lock the script”, wasn’t it?

That’s definitely possible. But looking at one of these addresses (the one from my VM) it seems less than unique: 0A:00:27:00:00:00. I can’t say, but it’s possible these VM macaddresses don’t vary that much. If someone had a list of known VM and VPN macaddresses this might be a security issue.
On the other hand, I might be overthinking things and putting too much energy in securing something instead of actually developing the product.

What I get with a similar code to DenisT’s one is something like:

“00E0714B1597”, “00E0714B1596”, “7054D2E53C12”, “BDAEC51FE0EF”

that is 12 hexadecimal characters (the first and second ones correspond to the same PC).
So, your client should give to you something like that.

You can try my script in this web to see what you get in your computer:
http://www.proin3d.org/pathscripts/index.php/identifying-pc

I just have and it gives interesting results. When my VPN is on I get 00FF848D09A2. This is the actual macaddress of the vpn. When I switch my VPN off I get 180373E28EAD which is the address of my physical network connection.

This is the code I use. It’s a copy/paste from another in this forum, possibly the DenisT’s one.


			fn GetAllPhysicalMACs =
			(
				interfaces = (dotnetClass "System.Net.NetworkInformation.NetworkInterface").GetAllNetworkInterfaces()
				PhysicalMACs = for j in interfaces where (j.NetworkInterfaceType.toString()) == "Ethernet" collect (j.GetPhysicalAddress()).toString()
				return PhysicalMACs
			),

			Try (IMAC = (GetAllPhysicalMACs())[1]) catch (IMAC = "No IMAC in this PC")

This is to avoid having users run a single license on multiple machines. So it’s to “protect” a script I’ll be releasing publicly.

1 Reply
(@polytools3d)
Joined: 10 months ago

Posts: 0

If you are planning to use the MAC address to make sure that your software will run in just 1 machine, then I would consider a few things:

1. Any sort of DRM must ensure in first place that it causes 0 (cero) frustration to the customers. You really don’t want a customer calling you Sunday morning because they can’t activate their software or the activation stopped working.

Software can have bugs, and that is understandable and tolerable, but software activation that fails can really piss off a customer.

2. Since the devices indexes are dynamically allocated, you can’t rely just on the index.

3. Devices can be enabled/disabled for different reasons.

4. There are plug-play network adapters.

5. The safest way to know which is the correct MAC address would be to use all the MACs to ping an internet address, but you must be 100% sure that all customers will have access to internet, which is not always the case.

Even though, what would happen if the user has a plug-play device and move it to another machine?

What would happen if for any reason they lose the internet access or your server is down?

How would you deal with Antivirus and Firewalls?

6. MAC addresses can be easily spoofed or cloned.

7. What would happen the main network adapter stop working or they have to replace it for any unknown reason? They would ask for a new activation code with the new MAC.

How many times will you allow a customer to do this?

Are they asking for a legit activation or are they trying to activate a second machine for free?

8. Will you run the check every time the user launches your software or just once?

If you will run it just once, then someone could activate all their machines with just 1 License.
If you will run it in every launch you must ensure that the machine will met the conditions in order to avoid fails.

9. Where and how will you store the License information? This is a hard one.

So, what options do you have?

One would be so create a fingerprint based on different devices and then evaluate if the amount of changes in those devices can allow or not to run the software. This must be very carefully planned, it is not as simple as it looks.

Some little advice:

Expend 99% of the time making a great software and 1% protecting it, not the other way around.
If you expend too much time protecting your software, a lot of frustration and headache are guaranteed.

Then, what do you think would be a good choice?
1. Poor software with poor protection
2. Poor software with great protection
3. Great software with poor protection
4. Great software with great protection

Page 1 / 4