导航

用C#获取硬盘序列号,CPU序列号,网卡MAC地址

Posted on 2009-01-05 15:56  ccjvl  阅读(3331)  评论(3编辑  收藏  举报

 这个问题首先得考虑的就是你的硬盘是不是SCSI硬盘  
  如果是,那么根本不存在"物理序列号",只可能取得卷标的序列号  
   
  如果是卷标序列号,要注意的是每次格式化硬盘的时候这个序列号都会变  
  代码可以参考:  
  http://www.csdn.net/Develop/Read_Article.asp?Id=25196  
   
  如果是物理序列号:  
  String   HDid;  
  ManagementClass   cimobject   =   new   ManagementClass("Win32_DiskDrive");  
  ManagementObjectCollection   moc   =   cimobject.GetInstances();  
  foreach(ManagementObject   mo   in   moc)  
  {  
  HDid   =   (string)mo.Properties["Model"].Value;  
  MessageBox.Show(HDid   );    
  }

 

如果是取得逻辑序列号(Format产生的那个),用WMI就可以,在引用中,添加system.mangement以后。    
  using   System.Management;  
  .....  
  ManagementObject     m_objDisk     =     new     ManagementObject(     "win32_logicaldisk.deviceid=\"c\"");          
  string     strSN     =     (string)m_objDisk.GetPropertyValue(     "VolumeSerialNumber     ");          
   
  如果要取得物理分区号,看这个帖子:  
  关于硬盘序列号,高手请留步啊.   (之一)  
  http://expert.csdn.net/Expert/TopicView3.asp?id=1143107  

683E0480(第一种方案取得)

ST3160815AS (第二个方案取得的)

 5239355835565745202020202020202020202020(第三种方案取得)

private string[] GetMoc()
        
{
            
string[] str = new string[3];
            ManagementClass mcCpu 
= new ManagementClass("win32_Processor");
            ManagementObjectCollection mocCpu 
= mcCpu.GetInstances();
            
foreach(ManagementObject m in mocCpu)
            
{
                str[
0= m["ProcessorId"].ToString();
            }


            ManagementClass mcHD 
= new ManagementClass("win32_logicaldisk");
            ManagementObjectCollection mocHD 
= mcHD.GetInstances();
            
foreach(ManagementObject m in mocHD)
            
{
                
if(m["DeviceID"].ToString() == "C:")
                
{
                    str[
1= m["VolumeSerialNumber"].ToString();
                    
break;
                }

            }


            ManagementClass mcMAC 
= new ManagementClass("Win32_NetworkAdapterConfiguration");
            ManagementObjectCollection mocMAC 
= mcMAC.GetInstances();
            
foreach(ManagementObject m in mocMAC)
            
{
                
if((bool)m["IPEnabled"])
                
{
                    str[
2= m["MacAddress"].ToString();
                    
break;
                }

            }


            
return str;
        }

以上为取硬盘逻辑分区序列号,重新格式化会改变

 

以下为硬盘物理序列号,需管理员权限,wmi

 

Code

 

第三种方案:

 

Code

 

一般软件的注册机制可以通过获取硬件序列号,然后用非对称加密算法生成相应的公钥私钥。但是用Managed Code写获取硬盘序列号的代码不能解决所有的问题,比如不能在非管理员的权限下使用,前几天Sunmast在他的Blog上发布了《如何得到硬盘序列号?.NET版本[C#]》,就是没有解决这个问题,用WMI也有很多问题。

要想顺利获取硬盘的序列号,目前只能依靠非托管代码了。DiskId32是一个源码公开的C++程序,可以解决上述问题。由于代码比较底层,我对VC和DDK不熟悉,没有能力将其封装为DLL,希望各位帮忙!

还有,就算封装好了这个Native DLL并可以使用了,但还有问题没有解决。如果封装到了Native DLL,该DLL很容易被人替换成另外一个,毕竟在Managed Code里面可以看到调用Native DLL的函数声明,别人只要模仿这些函数界面重新写一个新的就很容易达到破解目的了。不过具体我没有测试过,不知道行不行。

于是我又想到了另外一个方法,就是把获取硬盘序列号的Native DLL作为资源文件封装到Managed Code中,然后在每次要调要该DLL时,先把该DLL写入磁盘,再动态绑定。由于Managed Code可以通过混淆器来保护,以致不能对其进行修改,这个我在《如何保护我们的 .NET 程序集?》中已经给出了答案。动态绑定Native DLL又是另外一个技术难题,我已经找到了一些资料,与大家分享。
Late binding on native DLLs with C#
Late-Binding DLLs in C#
Using legacy plug-ins with .NET - Part 1
Using legacy plug-ins with .NET - Part 2
C-Function pointer for .NET
Dynamic PInvoke method calls

不过最牛的就是下面这一招了!直接把Native Code用字节数组保存在Managed Code中,然后调用,真是牛B,不过我还没有完全弄懂,希望大家来实践实践。
Execute Native Code From .NET

另外还有一篇文章是关于加密字符串的,值得研究!
Poly-Engine Crypt String

希望各位多多交流.NET程序的保护问题,找出最好的解决方案!

 

 

http://www.winsim.com/diskid32/diskid32.html

 

 

Code