欺骗后如何检测原始MAC地址?

我们使用下面的代码来检索Windows PC的活动MAC地址。

private static string macId() { return identifier("Win32_NetworkAdapterConfiguration", "MACAddress", "IPEnabled"); } private static string identifier(string wmiClass, string wmiProperty, string wmiMustBeTrue) { string 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].ToString() == "True") { //Only get the first one if (result == "") { try { result = mo[wmiProperty].ToString(); break; } catch { } } } } return result; } //Return a hardware identifier private static string identifier(string wmiClass, string wmiProperty) { string 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].ToString(); break; } catch { } } } return result; } 

它工作正常,以检索MAC地址。 问题是什么时候MAC地址被欺骗,然后返回伪造的MAC地址。 我们想要以某种方式检索出厂时唯一和分配的原始MAC地址。 有没有办法做到这一点?

我想提供一个替代scheme。 我不知道它是否真正回答“唯一识别任何计算机的方法”。
但是,此方法查询System.Management中的Win32_BIOS类并返回一个很有可能是唯一的string。 (等待被否决!!)

 /// <summary> /// BIOS IDentifier /// </summary> /// <returns></returns> public static string 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"); } /// <summary> /// ManagementClass used to read the first specific properties /// </summary> /// <param name="wmiClass">Object Class to query</param> /// <param name="wmiProperty">Property to get info</param> /// <returns></returns> private static string GetFirstIdentifier(string wmiClass, string wmiProperty) { string result = string.Empty; ManagementClass mc = new System.Management.ManagementClass(wmiClass); ManagementObjectCollection moc = mc.GetInstances(); foreach (ManagementObject mo in moc) { //Only get the first one if (string.IsNullOrEmpty(result)) { try { if (mo[wmiProperty] != null) result = mo[wmiProperty].ToString(); break; } catch { } } } return result.Trim(); } 

可以有两种select。

  1. 您可以使用您之前提供的代码片段获取MAC地址,并检查该MAC地址是否属于任何NIC(networking接口卡)。 如果它不属于一个,那么MAC地址显然是欺骗性的。 这是使用MAC地址定位网卡的代码

     using System.Net.Sockets; using System.Net; using System.Net.NetworkInformation; string 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. 直接获取网卡地址。

     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.toString()) == "Ethernet" do append the_PhysicalAddress_Array ((net.GetPhysicalAddress()).toString()) e. print the_PhysicalAddress_Array 

((我在http://snipplr.com/view/23006/find);

我不得不在前一段时间写类似的东西,因为我使用了许多硬件参数来激活我的软件。

看看DeviceIoControl & OID_802_3_PERMANENT_ADDRESS 。 它的很多interop代码(我的类处理它大约是200行),但它使我的硬件代码保证。

一些代码片段让你去,

 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( string lpFileName, EFileAccess dwDesiredAccess, EFileShare dwShareMode, IntPtr lpSecurityAttributes, ECreationDisposition dwCreationDisposition, EFileAttributes dwFlagsAndAttributes, 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 string // any exceptions will be passed onto the caller return BitConverter.ToString(address, 0, 6); } } 

那么,我不会赌我所有的钱在NetworkInterface类列出NetworkInterfaces的顺序。 我的主板有2个适配器,每次重新启动时,顺序似乎都会切换。

所以这里是一个build议,这对我来说(顺便说一句:信用可能是另一个很棒的stackoverflow贡献者,ty):

  public static string GetMACAddress() { NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces(); //for each j you can get the MAC PhysicalAddress address = nics[0].GetPhysicalAddress(); byte[] bytes = address.GetAddressBytes(); string 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; }