wake-up-neo.com

eindeutige Maschinen-ID erhalten

Ich möchte eine eindeutige unveränderliche Maschinen-ID erhalten. Wie die Seriennummer des Computers für die Verteilung einer Software ohne Kopieren.

Ich habe mit der Prozessor-Seriennummer und der Festplatten-Seriennummer versucht, dass sich alle nach dem Formatieren und Neuinstallieren der Fenster ändern. 

Irgendeine Idee, wie ich eine unveränderliche Seriennummer eines Computers erhalten kann?

31
ush

Sie können WMI Code Creator verwenden. Ich denke, Sie können eine Kombination von "Schlüsseln" haben (Prozessor-ID, Mac und durch Software erzeugter Schlüssel). 

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_Prozessor

Hardware-IDs in C # mit WMI abrufen von Peter Bromberg

15
PRR

Wenn Sie eine eindeutige ID benötigen, müssen Sie zunächst Ihre Definition von unique festlegen. Wenn Sie es für einen Kopierschutzmechanismus verwenden möchten/wollen, verwenden Sie etwas einfaches. Dies liegt daran, dass jemand, der Ihre Software wirklich verwenden möchte (n), einen Weg finden wird, Ihren Schutz zu brechen, wenn Sie genügend Zeit und Geschicklichkeit haben. Bei einer eindeutigen Hardware-ID müssen Sie nur über virtuelle Maschinen nachdenken. Sie werden sehen, dass es möglich ist, alles zu manipulieren, damit jemand Ihre Software manipulieren kann.

Es gibt nicht viel, was Sie von einem PC mitnehmen können, und er kann es während seiner gesamten Lebensdauer als einzigartig betrachten. (Hardwareänderungen erfordern höchstwahrscheinlich die erneute Generierung der ID zu einem bestimmten Zeitpunkt.) Wenn Sie so etwas benötigen, sollten Sie dies anhand eines Authentifizierungsprotokolls USB Dongle prüfen, das Sie an Ihre Kunden senden können.

Wenn Sie nur eine eindeutige Kennung benötigen, die nicht so schwer zu erhalten ist, können Sie die MAC-Adresse (unzuverlässig), die Seriennummer des Betriebssystems oder die Domäne und den Namen des Benutzers verwenden. Alle können jedoch gefälscht werden. Wenn Ihr Hauptziel jedoch darin besteht, nicht autorisierte Personen auszusperren, verkaufen Sie nichts, da niemand Ihre Software verwenden möchte, wenn die Installation, Registrierung oder der Umzug von einem PC auf einen anderen schwierig ist, obwohl dies die letzte Überlegung ist Teil und Paket der Lizenzierung pro Maschine. (Dies wird wahrscheinlich ziemlich oft vorkommen.)

Machen Sie es sich als ersten Schritt einfach: Verwenden Sie etwas Einfaches, das in Ihrer Zielgruppe nicht leicht zu fälschen ist. (Beispielsweise können Domänen- und Benutzernamen von Unternehmenskunden nicht leicht gefälscht werden, da ihre PCs in einer größeren Umgebung ausgeführt werden und Richtlinien implementieren usw.). Vergessen Sie die anderen nur, bis Sie über diese verfügen.

Vielleicht können Sie sie aussperren, aber das bedeutet nicht, dass sie Ihre Software kaufen werden. Sie werden es einfach nicht mehr benutzen. Sie müssen berücksichtigen, wie viele potenzielle Kunden nicht sein werden oder nicht bereit sind zu zahlen, weil Sie die Verwendung Ihres Programms so kompliziert gemacht haben.

14
Oliver

Ich würde weit weg von MAC-Adressen bleiben. Bei einigen Geräten kann sich die MAC-Adresse beim Neustart ändern. Wir haben schon früh gelernt, uns nicht darauf zu verlassen.

Werfen Sie einen Blick auf den Artikel Entwickeln für Softwareschutz und Lizenzierung , der einige Hinweise zum Entwickeln und Implementieren von Apps enthält, um die Piraterie zu reduzieren.

Obligatorischer Haftungsausschluss & Plug: Die von mir mitbegründete Firma stellt die OffByZero Cobalt-Lizenzierungslösung her. Daher überrascht es Sie wahrscheinlich nicht, zu hören, dass ich empfehle, Ihre Lizenzierung auszulagern und sich auf Ihre Kernkompetenzen zu konzentrieren.

11
Duncan Bayne

Check out dieser Artikel . Es ist sehr umfassend und Sie werden feststellen, wie Sie verschiedene Hardwareinformationen extrahieren.

Zitat aus dem Artikel :

Um Hardwareinformationen abzurufen, müssen Sie ein Objekt der ManagementObjectSearcher-Klasse erstellen.

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

Der Schlüssel im obigen Code ist eine Variable, die durch entsprechende Daten ersetzt wird. Um beispielsweise die Informationen der CPU zu erhalten, müssen Sie den Schlüssel durch Win32_Processor ersetzen.

5

edit: Ich habe gerade gesehen, dass du in c # gemeint hast. Hier ist ein besserer Weg mit nicht verwaltetem Code:

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

Vielleicht ist der einfachste Weg. Holen Sie sich das DeviceId Nuget-Paket

Und benutze es gerne

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

Sie können die zum Generieren der ID verwendeten Informationen personalisieren

Github-Projekt

3
Daniel

Ich stimme Blindys Vorschlag zu, die MAC-Adresse des (ersten?) Netzwerkadapters zu verwenden. Ja, die MAC-Adresse kann gefälscht werden, aber dies hat Nebenwirkungen (Sie möchten nicht, dass zwei PCs mit derselben MAC-Adresse im selben Netzwerk sind). Dies ist etwas, was "Ihr durchschnittlicher Pirat" nicht tun kann, nur um es zu können um Ihre Software zu verwenden. In Anbetracht dessen, dass es keine 100% ige Lösung gegen Softwarepiraterie gibt, ist die MAC-Adresse ein guter Kompromiss, IMO.

Beachten Sie jedoch, dass sich die Adresse ändert, wenn der Benutzer eine Netzwerkkarte hinzufügt, ersetzt oder entfernt (oder seinen alten PC insgesamt ersetzt). Seien Sie also darauf vorbereitet, Ihren Kunden zu helfen, und geben Sie ihnen einen neuen Schlüssel, wenn Sie ihre Hardwarekonfiguration ändern.

2
Heinzi

Ja, wir könnten einen Code erhalten, der eine Kombination aus physischer Adresse, eindeutiger Laufwerks-ID, Festplatten-ID (Volume Serial), CPU-ID und BIOS-ID ist. Beispiel ( Vollständiges Beispiel ):

//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");
    }
2
Raj kumar

Sie sollten kein MAC verwenden, es ist ein schlechter Weg. Weil einige Betriebssysteme es jeden Tag ändern. Meine Erfahrung: Tools.CpuID.Processor Id () + 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
Nik Shev

Die folgende Site verwendet System.Management Dasselbe zu erreichen, ist in einer Konsolenanwendung eine sehr elegante Methode

0
Sujoy

Dazu gibt es zwei Möglichkeiten, die ich kenne:

  1. Rufen Sie die Prozessor-ID des Systems ab:

    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's ID
                cpuInfo = mo.Properties["processorID"].Value.ToString();
                break;
            }
        }
        return cpuInfo;
    }
    
  2. Rufen Sie die UUID des Systems ab:

    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;
    }
    
0