получить уникальный идентификатор машины - PullRequest
32 голосов
/ 05 января 2010

Я хочу получить уникальный неизменяемый идентификатор компьютера, например серийный номер процессора компьютера для распространения программного обеспечения без копирования.

Я пытался использовать серийный номер процессора и серийный номер жесткого диска, которые все меняются после форматирования и переустановки Windows.

Есть идеи, как получить неизменяемый серийный номер компьютера?

Ответы [ 12 ]

14 голосов
/ 20 января 2010

Вы можете использовать WMI Code creator .Я думаю, вы можете иметь комбинацию «ключей» (процессор, Mac и ключ, сгенерированный программным обеспечением).

using System.Management;
using System.Windows.Forms;

try
{
     ManagementObjectSearcher searcher = 
         new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_Processor"); 

     foreach (ManagementObject queryObj in searcher.Get())
     {
         Console.WriteLine("-----------------------------------");
         Console.WriteLine("Win32_Processor instance");
         Console.WriteLine("-----------------------------------");
         Console.WriteLine("Architecture: {0}", queryObj["Architecture"]);
         Console.WriteLine("Caption: {0}", queryObj["Caption"]);
         Console.WriteLine("Family: {0}", queryObj["Family"]);
         Console.WriteLine("ProcessorId: {0}", queryObj["ProcessorId"]);
     }
}
catch (ManagementException e)
{
    MessageBox.Show("An error occurred while querying for WMI data: " + e.Message);
}

Win32_Processor

Получение идентификаторов оборудования в C # с WMI от Peter Bromberg

14 голосов
/ 05 января 2010

Если вам нужен уникальный идентификатор , вы должны сначала определить свое определение уникальный .Если вы хотите / намереваетесь использовать его для механизма защиты от копирования, используйте что-то простое.Это потому, что если кто-то действительно хочет использовать ваше программное обеспечение, он (-ы) найдет способ сломать вашу защиту, если у вас будет достаточно времени и навыков.В случае уникального идентификатора оборудования, просто подумайте о виртуальных машинах, и вы увидите, что можно подделать все, что угодно, чтобы кто-то мог вмешаться в ваше программное обеспечение.

Вы не можете ничего взять с ПКи рассматривайте это как уникальность в течение всей своей жизни.(Аппаратные изменения, скорее всего, в какой-то момент потребуют регенерации идентификатора.) Если вам нужно что-то подобное, вам следует проверить использование аутентификационного ключа USB Dongle , который вы можете отправить своим клиентам.

Если вам нужен какой-то уникальный идентификатор, который не так сложно получить, вы можете взять MAC-адрес (ненадежный), серийный номер ОС или домен и имя пользователя, но все они подвержены подделке.Однако, если ваша главная цель - заблокировать посторонних людей, вы ничего не будете продавать, потому что никто не захочет использовать ваше программное обеспечение, если его сложно установить, зарегистрировать или перейти с одного компьютера на другой, хотя последнее соображениенеотъемлемая часть лицензирования для каждой машины.(Это, вероятно, случается довольно часто.)

В качестве первого шага сделайте это легко: используйте что-то простое, что нелегко подделать в вашей целевой группе.(Например, доменные имена и имена пользователей не могут быть легко подделаны корпоративными клиентами, потому что их ПК работают в более широкой среде, реализующей политики и т. Д.) Просто забудьте о других, пока не получите это.

Может бытьвы можете заблокировать их, но это не значит, что они собираются покупать ваше программное обеспечение;они просто больше не будут его использовать.Вам нужно учитывать, сколько потенциальных клиентов не будет или не готовы платить, потому что вы сделали использование программы настолько сложным.

11 голосов
/ 20 января 2010

Я бы держался подальше от использования MAC-адресов. На некоторых устройствах MAC-адрес может измениться после перезагрузки. Мы научились довольно рано во время нашего исследования не полагаться на него.

Взгляните на статью Разработка для защиты и лицензирования программного обеспечения , в которой есть несколько советов о том, как разрабатывать и реализовывать приложения для уменьшения пиратства.

Обязательный отказ от ответственности и штекер: соучредитель, которого я основал, производит лицензирование OffByZero Cobalt . Так что, вероятно, вас не удивит тот факт, что я рекомендую передать вам лицензию на аутсорсинг и сфокусироваться на ваших основных компетенциях.

4 голосов
/ 05 января 2010

Оформить эту статью . Он очень исчерпывающий, и вы найдете, как извлечь различную информацию об оборудовании.

Цитата из статьи :

Чтобы получить информацию об оборудовании, вам нужно создать объект класса ManagementObjectSearcher.

using System.Management;
ManagementObjectSearcher searcher = new ManagementObjectSearcher("select * from " + Key);
foreach (ManagementObject share in searcher.Get()) {
    // Some Codes ...
}

Ключ в приведенном выше коде - это переменная, которая заменяется соответствующими данными. Например, чтобы получить информацию о процессоре, вы должны заменить ключ на Win32_Processor.

3 голосов
/ 04 ноября 2015

Да, мы могли бы получить код, который представляет собой комбинацию физического адреса, уникального идентификатора диска, идентификатора жесткого диска (том последовательного тома), идентификатора процессора и идентификатора BIOS. Пример ( Полный пример ):

//Main physical hard drive ID
    private static string diskId()
    {
        return identifier("Win32_DiskDrive", "Model")
        + identifier("Win32_DiskDrive", "Manufacturer")
        + identifier("Win32_DiskDrive", "Signature")
        + identifier("Win32_DiskDrive", "TotalHeads");
    }
    //Motherboard ID
    private static string baseId()
    {
        return identifier("Win32_BaseBoard", "Model")
        + identifier("Win32_BaseBoard", "Manufacturer")
        + identifier("Win32_BaseBoard", "Name")
        + identifier("Win32_BaseBoard", "SerialNumber");
    }
3 голосов
/ 05 января 2010

редактировать: я только что видел, что вы имели в виду в C #. Вот лучший способ с неуправляемым кодом:

ManagementClass oMClass = new ManagementClass ("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection colMObj = oMCLass.GetInstances();
foreach(ManagementObject objMO in colMObj)
    Console.WriteLine(objMO["MacAddress"].ToString());
2 голосов
/ 20 марта 2019

Может быть, самый простой способ.Получите DeviceId Nuget пакет

И используйте его как

string deviceId = new DeviceIdBuilder()
.AddMachineName()
.AddMacAddress()
.AddProcessorId()
.AddMotherboardSerialNumber()
.ToString();

Вы можете персонализировать информацию, используемую для генерации идентификатора

GithubПроект

2 голосов
/ 16 января 2016

Вы не должны использовать MAC, это плохой способ. Потому что некоторые ОС просто меняют его каждый день. Мой опыт: Tools.CpuID.ProcessorId () + volumeSerial;

string volumeSerial = "";
    try {
        ManagementObject dsk = new ManagementObject(@"win32_logicaldisk.deviceid=""C:""");
        dsk.Get();
        volumeSerial = dsk["VolumeSerialNumber"].ToString();
    } catch {
        try {
            ManagementObject dsk = new ManagementObject(@"win32_logicaldisk.deviceid=""D:""");
            dsk.Get();
            volumeSerial = dsk["VolumeSerialNumber"].ToString();
        } catch { File.WriteAllText("disk.mising","need C or D"); Environment.Exit(0); }
    }

public class CpuID
    {
        [DllImport("user32", EntryPoint = "CallWindowProcW", CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
        private static extern IntPtr CallWindowProcW([In] byte[] bytes, IntPtr hWnd, int msg, [In, Out] byte[] wParam, IntPtr lParam);

        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
        public static extern bool VirtualProtect([In] byte[] bytes, IntPtr size, int newProtect, out int oldProtect);

        const int PAGE_EXECUTE_READWRITE = 0x40;



        public static string ProcessorId()
        {
            byte[] sn = new byte[8];

            if (!ExecuteCode(ref sn))
                return "ND";

            return string.Format("{0}{1}", BitConverter.ToUInt32(sn, 4).ToString("X8"), BitConverter.ToUInt32(sn, 0).ToString("X8"));
        }

        private static bool ExecuteCode(ref byte[] result)
    {
        int num;

        /* The opcodes below implement a C function with the signature:
         * __stdcall CpuIdWindowProc(hWnd, Msg, wParam, lParam);
         * with wParam interpreted as an 8 byte unsigned character buffer.
         * */

        byte[] code_x86 = new byte[] {
            0x55,                      /* push ebp */
            0x89, 0xe5,                /* mov  ebp, esp */
            0x57,                      /* push edi */
            0x8b, 0x7d, 0x10,          /* mov  edi, [ebp+0x10] */
            0x6a, 0x01,                /* push 0x1 */
            0x58,                      /* pop  eax */
            0x53,                      /* push ebx */
            0x0f, 0xa2,                /* cpuid    */
            0x89, 0x07,                /* mov  [edi], eax */
            0x89, 0x57, 0x04,          /* mov  [edi+0x4], edx */
            0x5b,                      /* pop  ebx */
            0x5f,                      /* pop  edi */
            0x89, 0xec,                /* mov  esp, ebp */
            0x5d,                      /* pop  ebp */
            0xc2, 0x10, 0x00,          /* ret  0x10 */
        };
        byte[] code_x64 = new byte[] {
            0x53,                                     /* push rbx */
            0x48, 0xc7, 0xc0, 0x01, 0x00, 0x00, 0x00, /* mov rax, 0x1 */
            0x0f, 0xa2,                               /* cpuid */
            0x41, 0x89, 0x00,                         /* mov [r8], eax */
            0x41, 0x89, 0x50, 0x04,                   /* mov [r8+0x4], edx */
            0x5b,                                     /* pop rbx */
            0xc3,                                     /* ret */
        };

        byte[] code;

        if (IsX64Process())
            code = code_x64;
        else 
            code = code_x86;

        IntPtr ptr = new IntPtr(code.Length);

        if (!VirtualProtect(code, ptr, PAGE_EXECUTE_READWRITE, out num))
            Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());

        ptr = new IntPtr(result.Length);

        try {
            return (CallWindowProcW(code, IntPtr.Zero, 0, result, ptr) != IntPtr.Zero);
        } catch { System.Windows.Forms.MessageBox.Show("Память повреждена"); return false; }
    }

        private static bool IsX64Process()
        {
            return IntPtr.Size == 8;
        }

    }
2 голосов
/ 05 января 2010

Второе предложение Блинди использовать MAC-адрес (первого?) Сетевого адаптера. Да, MAC-адрес может быть подделан, но это имеет побочные эффекты (вам не нужны два компьютера с одинаковым MAC-адресом в одной сети), и это то, что «ваш средний пират» не сделает просто для того, чтобы иметь возможность использовать ваше программное обеспечение. Учитывая, что не существует 100% -ного решения проблемы компьютерного пиратства, MAC-адрес является хорошим компромиссом, IMO.

Обратите внимание, что адрес будет меняться, когда пользователь добавляет, заменяет или удаляет сетевую карту (или заменяет свой старый компьютер в целом), поэтому будьте готовы помочь своим клиентам и дать им новый ключ при смене оборудования конфигурации.

0 голосов
/ 02 мая 2019

Следующий сайт использует System.Management, чтобы выполнить то же самое - очень изящный способ в консольном приложении

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...