zoukankan      html  css  js  c++  java
  • 物理网卡地址

    以下是获取网卡 MAC地址的方法.

    /// <summary>
      /// 以下是获取网卡 MAC地址的方法.
      /// 只能获取第一块
    
      /// </summary>
      /// <returns></returns>
      public static string GetMacAddress()
      {
      ManagementClass adapters = new ManagementClass("Win32_NetworkAdapterConfiguration");
      string MACAddress = "unknown";
      foreach (ManagementObject adapter in adapters.GetInstances())
      {
      if((bool)adapter["IPEnabled"] == true)
      {
      MACAddress = adapter.Properties["MACAddress"].Value.ToString();
      break;
      }
      }
      return MACAddress;
      }
    
    
    
    那就在客戶端的程序裡寫一個然發送回來保存在數據庫裡。
     public string GetNetCard()
      {
      string str = "";
      ManagementClass mcMAC = new ManagementClass("Win32_NetworkAdapterConfiguration");
      ManagementObjectCollection mocMAC = mcMAC.GetInstances();
      foreach (ManagementObject m in mocMAC)
      {
      if ((bool)m["IPEnabled"])
      {
      str = m["MacAddress"].ToString();
      break;
      }
      }
      return str;
      }
    
    
    
    
    
    
    
    
    
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Configuration;
    using System.Runtime.InteropServices;
    using System.Management;
    
    namespace POS
    {
      class GetVol
      {
      [DllImport("kernel32.dll")]
      private static extern int GetVolumeInformation(
      string lpRootPathName,
      string lpVolumeNameBuffer,
      int nVolumeNameSize,
      ref int lpVolumeSerialNumber,
      int lpMaximumComponentLength,
      int lpFileSystemFlags,
      string lpFileSystemNameBuffer,
      int nFileSystemNameSize
      );
    
      public string GetVolOf(string drvID)
      {
      const int MAX_FILENAME_LEN = 256;
      int retVal = 0;
      int a = 0;
      int b = 0;
      string str1 = null;
      string str2 = null;
      int i = GetVolumeInformation(
      drvID + @":",
      str1,
      MAX_FILENAME_LEN,
      ref retVal,
      a,
      b,
      str2,
      MAX_FILENAME_LEN
      );
    
      return retVal.ToString("x");
      }
    
      public string GetNetCard()
      {
      string str = "";
      ManagementClass mcMAC = new ManagementClass("Win32_NetworkAdapterConfiguration");
      ManagementObjectCollection mocMAC = mcMAC.GetInstances();
      foreach (ManagementObject m in mocMAC)
      {
      if ((bool)m["IPEnabled"])
      {
      str = m["MacAddress"].ToString();
      break;
      }
      }
      return str;
      }
      }
    }
    View Code

    c#如何给.NET软件添加注册码

    本文宗旨在于提出一种给软件添加注册码的方法。至于所提出的方法是否有效,是否能够经得起一些逆向高手的破解,还得经过验证。我只是提出我个人的看法。
    一、目标。
        目标很明确,就是根据需要注册软件的个人信息,产生注册码。并且软件本身必须可以校验该注册码是否有效。并且能够防止别人逆向算出校验算法,产生注册机;能够防止别人用暴力破解方法,直接修改软件执行代码,绕过注册。
       
    二、方法论述
        要做到以上的目标,有两个方面特别重要。一是,注册码产生算法的选择;二是,要使软件具有自身校验机制,防止可执行程序别篡改。下面我们分别论述这两点。
    1. 注册码产生算法的选择
       现在很多软件都存在注册机,很大原因是因为软件本身的注册码产生算法太过于简单。破解人员很容易从反汇编代码中抠出注册算法,并且能够很容易的还原成C代码。这些搞破解的算不上大师,但也可以算得上牛人了。我也曾经了解过相关的知识,看懂反汇编的代码不难,难的是在大量的汇编代码中找到彼此的调用关系,并且能够逆向的写出对应的代码;当然有些懒人直接抠出其中的汇编代码,不用理解详细的执行过程就能达到破解的目的。
       言归正传,不管别人多么NB,他至少要反汇编,至少看的是汇编代码。而如果我们的算法足够强大,他们也就玩完了。纵观如今标准的加密算法,无非就是对称加密和非对称加密。我们也不用去自创算法了,别做些吃力不讨好的事,自己设计的算法,安全性远远比不上现在常用的算法。我先简单列举出常用的算法,并说明为什么要选择我们所要的算法。
       a. 对称加密算法现在流行的有DES,AES两种,DES算法广泛的用在银行行业,AES出现的比较晚,但是安全性比DES好。所谓的对称就是只有一个密钥,加密和解密使用同一个密码,所以称为对称加密。如果我们用它在产生注册码,那么我们的软件中必须保存这个密钥。不管密钥在哪里,总是要存在在一个地方,而我们又没有办法去保证这个密钥的安全性。原因很简单,破解者只要跟下代码,就知道我们从哪里读出来这个密钥。
       b. 非对称加密有RSA,和椭圆曲线等,最流行的是RSA。虽然椭圆曲线效率和安全性比RSA好,但比较复杂,我至今没看明白原理,呵呵。所谓的非对称,是因为它有两个密钥,一个称为公钥,一个称为私钥。公钥是可以对外发布的,而私钥是自己保存的。用公钥加密,必须用私钥解密,反之,用私钥加密必须用公钥解密。所以,我们知道,我们可以在软件中保存公钥的内容,这个是可以公开的(当然,把它隐藏在软件内部是必要的,总之可以造成破解的难度的事情我们都可以去尝试)。然后,私钥我们可以自己留着。别人拿不到私钥,根本计算不出注册码来。
      
    2. 至此,我们知道我们可以使用RSA算法了,而且可以保证软件的安全。至少无法产生注册机,因为别人没有私钥。但是具体怎么做,我们可以按照下面的流程。
       a. 注册码产生过程:
          注册信息(包括用户名等信息)---> RSA私钥加密 ---> 注册码。
         
       b. 软件验证注册码过程:
          注册码 ---> RSA公钥解密 ---> 注册信息。
      
    3. 解决了第一个目标,我们还是很难防止别人直接篡改2进制的可执行文件,从而绕过注册码的校验。但是,方法总是有的。为了解决这个问题,我想到了一个方法:软件的自我校验。具体的做法是这样的:
       a. 我们为自身的软件产生校验值,这里要使用摘要算法。最常用的摘要算法是MD5,相信大家都听过,这里也就不再详述,我们仅仅需要在软件的执行时,读取可执行程序(在Windows下,自身的执行文件是可读的,但是如果自己要改写自己,那就没办法了)并计算校验值。
       b. 接着,我们可以判断校验值是否正确,如果不正确,我们软件可以直接自杀。
      
       但是这里有个问题,我们怎么在软件中保存正确的校验值呢?不可能保存在文件或者注册表中,这样早晚会被知道的。别人可以直接修改该校验值使之与错误的校验值相同,从而骗过软件的校验。这里有个方法:回归到(第1、2点)中描述的方法。如何回归?我们接着说。
    
    4. 保存软件的校验值:让校验值融入注册码。我们修改(第2点)的过程如下:
       a. 注册码产生过程:
          注册信息(包括用户名等信息)+ 软件校验值 ---> RSA私钥加密 ---> 注册码。
      
       b. 软件验证注册码过程:
          注册码 ---> RSA公钥解密 ---> 注册信息 + 软件校验值。
       这样子,我们就可以这样判断软件是否已经成功注册。首先根据上面步骤,算出注册信息和软件校验值,然后把这两者和当前的用户信息,和计算出的校验值做比较,如果都匹配,说明软件已经被成功的注册。
      
    5. 尝试破解。
       如果你知道了详细的过程,如何破解该软件?首先我们知道,已经无法写出注册机来了。唯一的办法是暴利破解,但是暴利破解,软件又加了自我校验。但是,百密总有一疏,暴利破解还是可以达到的。我们先回顾一下,如果我们按照上述的办法添加了注册码校验。那么我们的代码差不多是这么写的:
      
       int RSA_Check( char * sn ){
           该函数计算软件的校验值,根据注册码sn解密出校验值和用户信息,然后比较,返回是否校验通过。
       }
       ....
       在软件的启动时,我们调用上述的函数。
       if( RSA_Check( sn ) ){     <--------------------------①
           在这里,如果校验失败,那就直接exit(0)吧,呵呵~
       }
      
       但是致命弱点就在上述的①位置。因为①位置的汇编差不多是这样的:
       je xxxxx    
       ....
       ....
      
       仅仅是一条跳转语句,那么,破解人员直接将其改成jne或者别的jmp指令就完事了,我们的努力就全废了。既然如此,我们代码绝不能写成这样,或者我们的方法不该如此简单。至少,我们可以这么做:
       1. 不要把校验算法写成一个统一的接口。
       2. 不要仅仅在一个地方做判断。这点其实很简单也很有效,如果你愿意,你可以在软件中对效率要求不高的地方多加几个判断,这对破解人来说是相当痛苦的,至少他无法同时查找到所有的关键位置。只要有一个地方没改成功,那么我们的自我校验就起作用,那么我们就有权利执行后续的动作了。比如,直接删掉本身的程序(当然,这里必须关闭自己,然后调用另一个进程来删除软件)等等。
       3. 更“贱”的方法是,起一个附加的进程,和主进程互相监视,互相校验。如果校验到对方注册异常了,那就杀掉对方,干掉对方的可执行程序。听起来很贱,但是不是有用,俺也不知道。
       4. 如果要防止一个注册码到处使用的情况(中国人都是互帮互助的,呵呵),可以在注册信息中添加目标机器的信息,加入到注册信息中。
       4. 等等的这些方法,就很多了,大家可以自由发挥。
      
    三. 总结
       经过上述的论述,我觉得没有绝对的安全,有时如果你的软件不想被破解,那么您就只能诅咒那些不道德的人了。但是我们可以让他们更加痛苦,至少菜鸟是无法随随便便搞破坏的。在中国,写个软就开源,免费吧,别指望拿它来养家糊口了。
      
    四. 附件
        RSA加解密实现代码
     
    View Code

    C#获取本机和其它计算机物理网卡地址(MAC)

    验证计算机MAC地址进行软件授权是一种通用的方法,C#可以轻松获取计算机的MAC地址,本文采用实际的源代码讲述了两种获取网卡的方式,第一种 方法使用ManagementClass类,只能获取本机的计算机网卡物理地址,第二种方法使用Iphlpapi.dll的SendARP方法,可以获取 本机和其它计算机的MAC地址。
        方法1:使用ManagementClass类
              示例: 
    /// <summary>
    /// 获取网卡物理地址
    /// </summary>
    /// <returns></returns>
    publicstaticstringgetMacAddr_Local()
    {
        stringmadAddr =null;
        ManagementClass mc =newManagementClass("Win32_NetworkAdapterConfiguration");
        ManagementObjectCollection moc2 = mc.GetInstances();
        foreach(ManagementObject moinmoc2)
        {
            if(Convert.ToBoolean(mo["IPEnabled"]) ==true)
            {
                madAddr = mo["MacAddress"].ToString();
                madAddr = madAddr.Replace(':','-');
            }
            mo.Dispose();
        }
        returnmadAddr;
    }
    说明:   1.需要给项目增加引用:System.Management,如图:
        2.在程序开始添加包引入语句:using System.Management;
    
        3.本方案只能获取本机的MAC地址;
        方法2:使用SendARP类
              示例: 
    //下面一种方法可以获取远程的MAC地址
    [DllImport("Iphlpapi.dll")]
    staticexternintSendARP(Int32 DestIP, Int32 SrcIP,refInt64 MacAddr,refInt32 PhyAddrLen);
    [DllImport("Ws2_32.dll")]
    staticexternInt32 inet_addr(stringipaddr);       
    /// <summary>
    /// SendArp获取MAC地址
    /// </summary>
    /// <param name="RemoteIP">目标机器的IP地址如(192.168.1.1)</param>
    /// <returns>目标机器的mac 地址</returns>
    publicstaticstringgetMacAddr_Remote(stringRemoteIP)
    {
        StringBuilder macAddress =newStringBuilder();
        try
        {
            Int32 remote = inet_addr(RemoteIP);
            Int64 macInfo =newInt64();
            Int32 length = 6;
            SendARP(remote, 0,refmacInfo,reflength);
            stringtemp = Convert.ToString(macInfo, 16).PadLeft(12,'0').ToUpper();
            intx = 12;
            for(inti = 0; i < 6; i++)
            {
                if(i == 5)
                {
                    macAddress.Append(temp.Substring(x - 2, 2));
                }
                else
                {
                    macAddress.Append(temp.Substring(x - 2, 2) +"-");
                }
                x -= 2;
            }
            returnmacAddress.ToString();
        }
        catch
        {
            returnmacAddress.ToString();
        }
    }
    说明:    1.在程序开始添加包引入语句:using System.Runtime.InteropServices;
        2.该方法可以获取远程计算机的MAC地址;
     
    View Code
  • 相关阅读:
    485串口接线
    mvc3 升级mvc5
    VB连接ACCESS数据库,使用 LIKE 通配符问题
    VB6 读写西门子PLC
    可用的 .net core 支持 RSA 私钥加密工具类
    解决 Win7 远程桌面 已停止工作的问题
    解决 WinForm 重写 CreateParams 隐藏窗口以后的显示问题
    解决安装 .net framework 发生 extracting files error 问题
    CentOS7 安装配置笔记
    通过特殊处理 Resize 事件解决 WinForm 加载时闪烁问题的一个方法
  • 原文地址:https://www.cnblogs.com/blogpro/p/11462965.html
Copyright © 2011-2022 走看看