2012-03-03 10 views
21

Windows PCのアクティブなMACアドレスを取得するために、次のコードを使用しています。詐称された元の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アドレスを何らかの形で取得したいと考えています。そうする方法はありますか?

+11

MACをスプーフィングの全体のポイントがあるように、コンピュータ(およびソフトウェアそれは正しいMACであると信じています)。 – Joe

+0

@Joe、はい。私の最初の質問は「本当にすべてのコンピュータを一意に識別する方法はありますか」でした。 MACアドレスを一意の識別子として使用できるという提案があります。それはこの疑問につながります。 –

+1

いくつかの他のアイデアはここにあります:http://stackoverflow.com/questions/671876/whats-a-good-way-to-uniquely-identify-a-computer – Joe

答えて

21

私は別の方法を提供したいと思います。私はそれが本当に「どのコンピュータをも一意に識別する方法」に答えるかどうか分かりません。
ただし、このメソッドはSystem.ManagementのWin32_BIOSクラスを照会し、一意になる可能性の高い文字列を返します。 (ごめんなさい!)

/// <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(); 
} 
+0

私はすでに私の心の中にそれを持っていたが、代替のおかげで。とにかく、私は合理的な提案を感謝します。否定するものはありません。 :) –

+0

ありがとう非常に良い! –

8

2つの選択肢があります。

  1. あなたは、コードを使用してMACアドレスを取得することができますが、あなたが前に与え、そのMACアドレスは、任意のNIC(ネットワークインタフェースカード)に属しているかどうかを確認スニペット。それが1つに属していない場合、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. を使用してNICを見つけコードがあります。

    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/を発見した)

+0

MACアドレスがスプーフィングされている場合、この方法は機能しますか? – Guvante

+1

@Guvante、そうではありません。それは、詐称されたMACアドレスが対応するNICに属していることを示します。実際、私が今までに作業してきたすべてのコードは、工場で割り当てられた元のMACアドレスではなく、現在のMACアドレスを取得します。 –

+0

あなたの答えはうまくいかなかったが、あなたはこの質問の実際の答えを出そうとした唯一の人だ。だから私はあなたに恩恵を与えることにした.. :) –

7

私はソフトウェアの「活性化」のためのハードウェアパラメータの数を使用していたので、私は少し前と同様のものを書かなければなりませんでした。

DeviceIoControl & をご覧ください。 それは多くのinteropコード(それを扱うための私のクラスはapproximatley 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); 
    } 
} 
+0

これは有望そうです。ありがとう:) 私はテストしてお知らせします。 –

+1

@SajibMahmoodは、あなたが立ち往生するかどうか知らせてくれます。私のソフトウェアでは、250以上の異なるコンピュータハードウェア上で15万台以上のマシンを実行しています。それは常にmacアドレスを取得しました。あなたは残念なことにWMIでその成功率を得ることはありません。 –

+0

@SajibMahmood運がいいですか? –

1

まあ、私はのNetworkInterfaceクラスはNetworkInterfacesを一覧表示するためにすべての私のお金を賭けないでしょう。 メインボードに2つのアダプタがあり、再起動するたびに注文が切り替わるようです。

だからここは私のために働いた提案です(ところで:クレジットは、別の素晴らしいstackoverflowののcontributerにおそらく行く、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; 
    }