Подтвердить что ты не робот

Получить уникальный идентификатор машины

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

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

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

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

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

Ответ 3

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

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

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

Ответ 4

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

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

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

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

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

Ответ 5

Да, мы могли бы получить код, который представляет собой комбинацию физического адреса, уникального идентификатора диска, идентификатора жесткого диска (последовательный объем), идентификатора CPU и идентификатора 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");
    }

Ответ 6

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

ManagementClass oMClass = new ManagementClass ("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection colMObj = oMCLass.GetInstances();
foreach(ManagementObject objMO in colMObj)
    Console.WriteLine(objMO["MacAddress"].ToString());

Ответ 7

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

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

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

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

Github Project

Ответ 8

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

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

Ответ 9

Вы не должны использовать 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;
        }

    }

Ответ 10

Мне известны два возможных пути:

  1. Получить идентификатор процессора системы:

    public string getCPUId()
    {
        string cpuInfo = string.Empty;
        ManagementClass mc = new ManagementClass("win32_processor");
        ManagementObjectCollection moc = mc.GetInstances();
    
        foreach (ManagementObject mo in moc)
        {
            if (cpuInfo == "")
            {
                //Get only the first CPU ID
                cpuInfo = mo.Properties["processorID"].Value.ToString();
                break;
            }
        }
        return cpuInfo;
    }
    
  2. Получить UUID системы:

    public string getUUID()
    {
            Process process = new Process();
            ProcessStartInfo startInfo = new ProcessStartInfo();
            startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
            startInfo.FileName = "CMD.exe";
            startInfo.Arguments = "/C wmic csproduct get UUID";
            process.StartInfo = startInfo;
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.RedirectStandardOutput = true;
            process.Start();
            process.WaitForExit();
            string output = process.StandardOutput.ReadToEnd();
            return output;
    }
    

Ответ 11

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

Ответ 12

Вы можете попробовать получить некоторую информацию из биоса. Это все равно будет действовать после формата.