Comment détecter l’adresse MAC d’origine après son usurpation?

Nous utilisons le code suivant pour récupérer l’adresse MAC active d’un PC Windows.

private static ssortingng macId() { return identifier("Win32_NetworkAdapterConfiguration", "MACAddress", "IPEnabled"); } private static ssortingng identifier(ssortingng wmiClass, ssortingng wmiProperty, ssortingng wmiMustBeTrue) { ssortingng result = ""; System.Management.ManagementClass mc = new System.Management.ManagementClass(wmiClass); System.Management.ManagementObjectCollection moc = mc.GetInstances(); foreach (System.Management.ManagementObject mo in moc) { if (mo[wmiMustBeTrue].ToSsortingng() == "True") { //Only get the first one if (result == "") { try { result = mo[wmiProperty].ToSsortingng(); break; } catch { } } } } return result; } //Return a hardware identifier private static ssortingng identifier(ssortingng wmiClass, ssortingng wmiProperty) { ssortingng result = ""; System.Management.ManagementClass mc = new System.Management.ManagementClass(wmiClass); System.Management.ManagementObjectCollection moc = mc.GetInstances(); foreach (System.Management.ManagementObject mo in moc) { //Only get the first one if (result == "") { try { result = mo[wmiProperty].ToSsortingng(); break; } catch { } } } return result; } 

Cela fonctionne très bien pour récupérer l’adresse MAC. Le problème est que lorsque l’adresse MAC est usurpée, elle renvoie l’adresse MAC usurpée. Nous voulons en quelque sorte récupérer l’adresse MAC originale, unique et assignée en usine. Y a-t-il un moyen de le faire?

Je souhaite donner une alternative. Je ne sais pas si cela répond vraiment à «un moyen d’identifier de manière unique un ordinateur».
Cependant, cette méthode interroge la classe Win32_BIOS dans System.Management et retourne une chaîne avec de fortes chances d’être unique. (En attendant d’être désavoué !!)

 ///  /// BIOS IDentifier ///  ///  public static ssortingng BIOS_ID() { return GetFirstIdentifier("Win32_BIOS", "Manufacturer") + GetFirstIdentifier("Win32_BIOS", "SMBIOSBIOSVersion") + GetFirstIdentifier("Win32_BIOS", "IdentificationCode") + GetFirstIdentifier("Win32_BIOS", "SerialNumber") + GetFirstIdentifier("Win32_BIOS", "ReleaseDate") + GetFirstIdentifier("Win32_BIOS", "Version"); } ///  /// ManagementClass used to read the first specific properties ///  /// Object Class to query /// Property to get info ///  private static ssortingng GetFirstIdentifier(ssortingng wmiClass, ssortingng wmiProperty) { ssortingng result = ssortingng.Empty; ManagementClass mc = new System.Management.ManagementClass(wmiClass); ManagementObjectCollection moc = mc.GetInstances(); foreach (ManagementObject mo in moc) { //Only get the first one if (ssortingng.IsNullOrEmpty(result)) { try { if (mo[wmiProperty] != null) result = mo[wmiProperty].ToSsortingng(); break; } catch { } } } return result.Trim(); } 

Il peut y avoir deux alternatives.

  1. Vous pouvez obtenir l’adresse MAC à l’aide de l’extrait de code que vous avez fourni précédemment et vérifier si cette adresse MAC appartient à une carte d’interface réseau (Network Interface Card). Si elle n’appartient pas à une, l’adresse MAC est évidemment falsifiée. Voici le code qui localise la carte réseau en utilisant une adresse MAC

     using System.Net.Sockets; using System.Net; using System.Net.NetworkInformation; ssortingng localNicMac = "00:00:00:11:22:33".Replace(":", "-"); // Parse doesn't like colons var mac = PhysicalAddress.Parse(localNicMac); var localNic = NetworkInterface.GetAllNetworkInterfaces() .Where(nic => nic.GetPhysicalAddress().Equals(mac)) // Must use .Equals, not == .SingleOrDefault(); if (localNic == null) { throw new ArgumentException("Local NIC with the specified MAC could not be found."); } var ips = localNic.GetIPProperties().UnicastAddresses .Select(x => x.Address); 
  2. Obtenez l’adresse de la carte réseau directement.

     a. NWIF = dotnetClass "System.Net.NetworkInformation.NetworkInterface" b. the_Mac_array = NWIF.GetAllNetworkInterfaces() -- this is an array of all the Networks c. the_PhysicalAddress_Array = #() d. for net in the_Mac_array where (net.NetworkInterfaceType.toSsortingng()) == "Ethernet" do append the_PhysicalAddress_Array ((net.GetPhysicalAddress()).toSsortingng()) e. print the_PhysicalAddress_Array 

((Je l’ai trouvé ici http://snipplr.com/view/23006/ ))

Il y a quelques instants, j’ai dû écrire quelque chose de similaire car j’utilisais un certain nombre de parameters matériels pour “activer” mon logiciel.

Regardez, DeviceIoControl & OID_802_3_PERMANENT_ADDRESS . C’est beaucoup de code d’interopérabilité (ma classe pour le gérer est d’environ 200 lignes), mais cela me garantit le code matériel garanti.

Quelques extraits de code pour vous aider,

 private const uint IOCTL_NDIS_QUERY_GLOBAL_STATS = 0x170002; [DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern bool DeviceIoControl( SafeFileHandle hDevice, uint dwIoControlCode, ref int InBuffer, int nInBufferSize, byte[] OutBuffer, int nOutBufferSize, out int pBytesReturned, IntPtr lpOverlapped); [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] internal static extern SafeFileHandle CreateFile( ssortingng lpFileName, EFileAccess dwDesiredAccess, EFileShare dwShareMode, IntPtr lpSecurityAtsortingbutes, ECreationDisposition dwCreationDisposition, EFileAtsortingbutes dwFlagsAndAtsortingbutes, IntPtr hTemplateFile); [Flags] internal enum EFileAccess : uint { Delete = 0x10000, ReadControl = 0x20000, WriteDAC = 0x40000, WriteOwner = 0x80000, Synchronize = 0x100000, StandardRightsRequired = 0xF0000, StandardRightsRead = ReadControl, StandardRightsWrite = ReadControl, StandardRightsExecute = ReadControl, StandardRightsAll = 0x1F0000, SpecificRightsAll = 0xFFFF, AccessSystemSecurity = 0x1000000, // AccessSystemAcl access type MaximumAllowed = 0x2000000, // MaximumAllowed access type GenericRead = 0x80000000, GenericWrite = 0x40000000, GenericExecute = 0x20000000, GenericAll = 0x10000000 } // Open a file handle to the interface using (SafeFileHandle handle = FileInterop.CreateFile(deviceName, FileInterop.EFileAccess.GenericRead | FileInterop.EFileAccess.GenericWrite, 0, IntPtr.Zero, FileInterop.ECreationDisposition.OpenExisting, 0, IntPtr.Zero)) { int bytesReturned; // Set the OID to query the permanent address // http://msdn.microsoft.com/en-us/library/windows/hardware/ff569074(v=vs.85).aspx int OID_802_3_PERMANENT_ADDRESS = 0x01010101; // Array to capture the mac address var address = new byte[6]; if (DeviceIoControl(handle, IOCTL_NDIS_QUERY_GLOBAL_STATS, ref OID_802_3_PERMANENT_ADDRESS, sizeof(uint), address, 6, out bytesReturned, IntPtr.Zero)) { // Attempt to parse the MAC address into a ssortingng // any exceptions will be passed onto the caller return BitConverter.ToSsortingng(address, 0, 6); } } 

Eh bien, je ne parierais pas tout mon argent sur l’ordre dans lequel la classe NetworkInterface répertorie les NetworkInterfaces. Ma carte mère possède 2 adaptateurs et la commande semble changer chaque fois que je redémarre.

Voici donc une suggestion qui a fonctionné pour moi (BTW: les crédits vont probablement vers un autre consortingbuteur impressionnant de stackoverflow, ty):

  public static ssortingng GetMACAddress() { NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces(); //for each j you can get the MAC PhysicalAddress address = nics[0].GetPhysicalAddress(); byte[] bytes = address.GetAddressBytes(); ssortingng macAddress = ""; for (int i = 0; i < bytes.Length; i++) { // Format the physical address in hexadecimal. macAddress += bytes[i].ToString("X2"); // Insert a hyphen after each byte, unless we are at the end of the address. if (i != bytes.Length - 1) { macAddress += "-"; } } return macAddress; }