This project has moved. For the latest updates, please go here.
3
Vote

Machine code repeats

description

Hello, first - thanks, wonderful project.

We're using SKGL in our project. -But already twice have encountered that Machine Code are the same for different hardware configurations.

Looks like distribution of Machine keys are quite a compact, and is too badly hashed - we've issued approx. 50 machine keys, and got already two repeats.

Maybe you can try to improve hashing of machine code generation? Or create machine key of larger size?

Uldis

comments

artemlos wrote May 29, 2014 at 9:44 PM

Let me see what I can do. The increase of machine code length would mean that something else would have to be reduced -- there is a trade off involved. I have to think about this.

Thanks for you message!

artemlos wrote May 29, 2014 at 9:44 PM

/../ your* message

wrote May 29, 2014 at 9:44 PM

artemlos wrote May 30, 2014 at 1:01 PM

Hi Uldis,,

I have tried to increase the length of the size of the machine code hash. Would you be able to test this code: http://blog.artemlos.net/posts/a-possible-change-for-machine-code/.

I could, if this is not possible, create a test version of SKGL instead.

Thank you in advance! :)

uldisv wrote Jun 3, 2014 at 7:00 AM

Hi - I'm a bit off/busy, will check in a few days and report you.

Uldis

uldisv wrote Jul 18, 2014 at 9:47 AM

Hi.
I tested on those machines, hash is changing, but it repeats on the same machines:
machine1 old 96535, new 889605
machine2 old 95526, new 947763
machine3 old 95526, new 947763
machine4 old 95495, new 990990
machine5 old 95495, new 990990
machine6 old 95736 new 915956
machine7 old 65017 new 965017
machine8 old 65017 new 965017
machine9 old 65017 new 965017
machine10 old 95495 new 990990
machine11 old 95495, new 990990
machine12 old 95495, new 990990

I'll try to get CPU/Disk/Mobo codes from these machines.

uldisv wrote Jul 18, 2014 at 10:07 AM

Hi - the problem is, that CPU returns the same ID for those processors, and BIOS e.t.c. just returns "To be Filled By OEM".

Here is full collectedInfo row (from new version machine ID generator):
BFEBFBFF000306A9To be filled by O.E.M.To be filled by O.E.M.

uldisv wrote Jul 18, 2014 at 10:17 AM

Olkd machine code - 95495, new - 990990.

collectedInfo row: BFEBFBFF000306C3To be filled by O.E.M.To be filled by O.E.M.

These rows are returned from Windows 7 Professional and Windows 7 Home premium - the same results.
There is no difference if run with "Run As Admin" or normally.

Uldis

uldisv wrote Jul 18, 2014 at 10:23 AM

Information about "To be Filled by OEM" problem: TEXT.

Uldis

uldisv wrote Jul 18, 2014 at 10:25 AM

B.t.w. this message has nothing to do with unlicensed software - all Windows in test are legal.

Uldis

artemlos wrote Aug 13, 2014 at 8:33 PM

Uldis,

Thank you for all this data! I am very sorry that I am replying so late, I have been quite busy the last few weeks. Let me look into this this week.

/Artem

artemlos wrote Aug 23, 2014 at 10:26 AM

Based on the information you provided, it appears that the machine code length is not the issue, but rather the data that is being collected before it is hashed.

Please try to use the hash method getMachineCode in https://skgl.codeplex.com/SourceControl/latest#SKGL - 2.0.5.2/SKGL Plus/SKGL.cs.

If it does not work, you can add more information to the hash and use a stronger hash method as machine code. This can be achieved with KeyActivation in http://support.serialkeymanager.com/howto/key-activation-through-a-client-application/

Sorry for a late response. I hope this helps!

/Artem

wrote Aug 24, 2014 at 7:59 AM

eriveraa wrote Sep 23, 2014 at 11:57 PM

Hi Artem, i would like to know if this issue is already fixed. I am planning on using your library in my application, and i want to be sure that there are no duplicates Machine Codes.
Thanks.

uldisv wrote Sep 24, 2014 at 6:43 AM

Hi. Haven't tested artemlos proposal from previous messages - but it looks promising. He switched from motherboard s/n to all network adapters MAC. Looks promising.
I'll check in a few days on test machines.

Uldis

artemlos wrote Sep 24, 2014 at 8:26 AM

In order to make sure there are no duplicates at all, please take a look at this article: https://skgl.codeplex.com/wikipage?title=Generate%20identical%20keys

ITDancer13 wrote Oct 2, 2014 at 11:51 AM

I´ve got the same problem. I´ve 4 pc from the same type and I got the same machine code on each of them.

I hope you can fix it :)


I tried it on my own to use the MAC addresses in that way:

private static string getMACAddress()
    {
        var nics = NetworkInterface.GetAllNetworkInterfaces();
        var mac = string.Empty;

        foreach (NetworkInterface adapter in nics)
            if (string.IsNullOrWhiteSpace(mac))
                mac = adapter.GetPhysicalAddress().ToString();

        return mac;
    }

    private static int getMachineCode()
    {
        var code = 0;

        SKGL.Generate g = new SKGL.Generate();
        code = g.MachineCode;

        MD5 md5 = new MD5CryptoServiceProvider();
        byte[] textToHash = Encoding.Default.GetBytes(getMACAddress());
        byte[] result = md5.ComputeHash(textToHash);

        foreach (var item in result)
            code = (code * item) % 100000;

        return code;
    }
It gave me four different machine codes...

artemlos wrote Oct 2, 2014 at 7:25 PM

It seems like the mac address is better at being specific for different machines.

uldisv wrote Oct 3, 2014 at 6:56 AM

Yes - it will give different results, but mac address can easily be "cheated" in Windows:
Image!

Here is simple step by step configuration to change it: http://www.wikihow.com/Change-a-Computer%27s-Mac-Address-in-Windows.

ITDancer13 wrote Oct 5, 2014 at 10:11 AM

That´s right, but
  1. you can use the MAC address in combination with the other aspects
  2. in each LAN each MAC address can be used only once.... so I think it´s not a big problem, because each customer usually has only one LAN....

uldisv wrote Oct 6, 2014 at 6:32 AM

Agree.

uldisv wrote Oct 20, 2014 at 8:28 AM

Hi - I currently modified your SKGL version 2.0.5.3 by combingin SKGL and ITDancer13 proposed getMachineCode().
Do you have plans to include this in some future versions?
I understand that will change exisiting keys, but otherwise your proposed machine code is not usable.

Uldis.

uldisv wrote Oct 20, 2014 at 9:09 AM

ITDancer13 - your code may run into problem, when user has USB Lan card attached and afterward remove it.

We should ignore removable Lan/Wifi cards.

ITDancer13 wrote Oct 20, 2014 at 9:13 AM

Hi, this is a good point!

Another issue is this line "code = (code * item) % 100000;"

Here we should check if "item" is not 0, otherwise the code would 0!

artemlos wrote Oct 23, 2014 at 9:05 PM

I will update the machine code generation as soon as possible. It would be great if you could post the entire code for the machine code module!

Thank you in advance!

uldisv wrote Oct 23, 2014 at 9:58 PM

Here is updated code for getMachineCode() function.
There is still one TODO - we have to filter out USB and software adapters. I'll work on it, as soon will get some free momemnt.
        [SecuritySafeCritical]
        private static int getMachineCode()
        {
            //      * Copyright (C) 2012 Artem Los, All rights reserved.
            //      * 
            //      * This code will generate a 5 digits long key, finger print, of the system
            //      * where this method is being executed. However, that might be changed in the
            //      * hash function "GetStableHash", by changing the amount of zeroes in
            //      * MUST_BE_LESS_OR_EQUAL_TO to the one you want to have. Ex 1000 will return 
            //      * 3 digits long hash.
            //      * 
            //      * Please note, that you might also adjust the order of these, but remember to
            //      * keep them there because as it is stated at 
            //      * (http://www.codeproject.com/Articles/17973/How-To-Get-Hardware-Information-CPU-ID-MainBoard-I)
            //      * the processorID might be the same at some machines, which will generate same
            //      * hashes for several machines.
            //      * 
            //      * The function will probably be implemented into SKGL Project at http://skgl.codeplex.com/
            //      * and Software Protector at http://softwareprotector.codeplex.com/, so I 
            //      * release this code under the same terms and conditions as stated here:
            //      * http://skgl.codeplex.com/license
            //      * 
            //      * Any questions, please contact me at
            //      *  * artem@artemlos.net
            //      
            methods m = new methods();

            ManagementObjectSearcher searcher = new ManagementObjectSearcher("select * from Win32_Processor");
            string collectedInfo = "";
            // here we will put the informa
            foreach (ManagementObject share in searcher.Get())
            {
                // first of all, the processorid
                collectedInfo += share.GetPropertyValue("ProcessorId");
            }

            searcher.Query = new ObjectQuery("select * from Win32_BIOS");
            foreach (ManagementObject share in searcher.Get())
            {
                //then, the serial number of BIOS
                collectedInfo += share.GetPropertyValue("SerialNumber");
            }

            searcher.Query = new ObjectQuery("select * from Win32_BaseBoard");
            foreach (ManagementObject share in searcher.Get())
            {
                //finally, the serial number of motherboard
                collectedInfo += share.GetPropertyValue("SerialNumber");
            }

            // patch luca bernardini
            if (string.IsNullOrEmpty(collectedInfo) | collectedInfo == "00" | collectedInfo.Length <= 3)
            {
                collectedInfo += getHddSerialNumber();
            }

            var nic = GetNicInfo();

            if (!string.IsNullOrWhiteSpace(nic))
              collectedInfo += nic;

            return m.getEightByteHash(collectedInfo, 100000);
        }

        /// <summary>
        /// Enumerate all Nic adapters, take first one, who has MAC address and return it.
        /// </summary>
        /// <remarks> Function MUST! be updated to select only real NIC cards (and filter out USB and PPTP etc interfaces).
        /// Otherwise user can run in this scenario: a) Insert USB NIC b) Generate machine code c) Remove USB NIC...
        /// </remarks>
        /// <returns>MAC address of NIC adapter</returns>
        [SecuritySafeCritical]
        private static string GetNicInfo()
        {
          var nics = NetworkInterface.GetAllNetworkInterfaces();
          var mac = string.Empty;

          foreach (var adapter in nics.Where(adapter => string.IsNullOrWhiteSpace(mac)))
            mac = adapter.GetPhysicalAddress().ToString();

          return mac;
        }

wrote Oct 24, 2014 at 9:44 AM

artemlos wrote Oct 27, 2014 at 9:20 PM

Thank you very much for all your help! :-)

uldisv wrote Nov 12, 2014 at 6:58 PM

Hi - I modified in my local version a bit machine code generation algorithm.
To be more compatible with previously generated machine codes - this version adds NIC information only if already generated string containts "To be filled by O.E.M." information:
        [SecuritySafeCritical]
        private static int getMachineCode()
        {
            //      * Copyright (C) 2012 Artem Los, All rights reserved.
            //      * 
            //      * This code will generate a 5 digits long key, finger print, of the system
            //      * where this method is being executed. However, that might be changed in the
            //      * hash function "GetStableHash", by changing the amount of zeroes in
            //      * MUST_BE_LESS_OR_EQUAL_TO to the one you want to have. Ex 1000 will return 
            //      * 3 digits long hash.
            //      * 
            //      * Please note, that you might also adjust the order of these, but remember to
            //      * keep them there because as it is stated at 
            //      * (http://www.codeproject.com/Articles/17973/How-To-Get-Hardware-Information-CPU-ID-MainBoard-I)
            //      * the processorID might be the same at some machines, which will generate same
            //      * hashes for several machines.
            //      * 
            //      * The function will probably be implemented into SKGL Project at http://skgl.codeplex.com/
            //      * and Software Protector at http://softwareprotector.codeplex.com/, so I 
            //      * release this code under the same terms and conditions as stated here:
            //      * http://skgl.codeplex.com/license
            //      * 
            //      * Any questions, please contact me at
            //      *  * artem@artemlos.net
            //      
            methods m = new methods();

            ManagementObjectSearcher searcher = new ManagementObjectSearcher("select * from Win32_Processor");
            string collectedInfo = "";
            // here we will put the informa
            foreach (ManagementObject share in searcher.Get())
            {
                // first of all, the processorid
                collectedInfo += share.GetPropertyValue("ProcessorId");
            }

            searcher.Query = new ObjectQuery("select * from Win32_BIOS");
            foreach (ManagementObject share in searcher.Get())
            {
                //then, the serial number of BIOS
                collectedInfo += share.GetPropertyValue("SerialNumber");
            }

            searcher.Query = new ObjectQuery("select * from Win32_BaseBoard");
            foreach (ManagementObject share in searcher.Get())
            {
                //finally, the serial number of motherboard
                collectedInfo += share.GetPropertyValue("SerialNumber");
            }

            // patch luca bernardini
            if (string.IsNullOrEmpty(collectedInfo) | collectedInfo == "00" | collectedInfo.Length <= 3)
            {
                collectedInfo += getHddSerialNumber();
            }

            // In case we have message "To be filled by O.E.M." - there is incorrect motherboard/BIOS serial number 
            // - we should relay to NIC
            if (collectedInfo.Contains("To be filled by O.E.M."))
            {
              var nic = GetNicInfo();

              if (!string.IsNullOrWhiteSpace(nic))
                collectedInfo += nic;
            }

          return m.getEightByteHash(collectedInfo, 100000);
        }
To be short - Nic method is not shown here but in previous post.

artemlos wrote Nov 14, 2014 at 1:25 PM

Thank you, uldisv!

I will try to implement it this weekend.

danchi wrote Jan 23, 2015 at 8:27 PM

Hi,

I have one suggestion.
As you can get back which features are checked and which are not from key, maybe you can also get back information, during the generation of key is included machine code or not.
Please share your thoughts.

Thanks.

artemlos wrote Feb 24, 2015 at 8:32 PM

Hi @danchi,

Let me see if I interpreted you correctly. You want to be able to tell if there is a machine code stored in the key?

/Artem

danchi wrote Mar 14, 2015 at 9:37 AM

Exactly.

wrote Mar 14, 2015 at 9:40 AM