网络编程-如何修改从本机发送出去的数据包的MAC地址

问题描述

如何修改从本机发送出去的数据包的MAC地址

例如,本机的MAC地址为: ?00-1C-47-CE-FE-02,在发送数据包的时候,如何将其修改为?00-11-42-DF-EE-01
1.不能采用修改网卡的MAC地址的方式,因为修改后的地址是随机动态的,要像方法中的一个参数一样,随时修改,不会影响网络状态,不会闪断
2.修改发送数据包的MAC地址后,要能够接收到返回的数据包
小弟不大懂网络方面的知识,但无奈领导布置了任务,
不知能否实现,能实现,麻烦说明具体实现方法,如不能实现,也麻烦具体说明一下不能实现的理由。
如有兴趣的大神可以加我QQ392124082研究研究
小弟感激不尽

解决方案

物理MAC 地址是不能在系统或者程序中修改的,但对方通信端是 web服务器或者电信服务器,修改系统注册表就可以了,能达到模拟真实MAC达到欺骗的目的,本人实测是完全可行的,但同一网域相同的MAC 会冲突,会导致一方不能联网,如果路由端经过ARP双向绑定你是没有任何办法的,这种概率非常低,下面是一个C#实例(非本人所写,但实测可行),可以随机修改也可以改成 指定MAC,主要还是看你要实现什么目的,请详细说明。

public class MACHelper
{
    [DllImport("wininet.dll")]
    private extern static bool InternetGetConnectedState(int Description, int ReservedValue);
    /// <summary>
    /// 是否能连接上Internet
    /// </summary>
    /// <returns></returns>
    public bool IsConnectedToInternet()
    {
        int Desc = 0;
        return InternetGetConnectedState(Desc, 0);
    }
    /// <summary>
    /// 获取MAC地址
    /// </summary>
    public string GetMACAddress()
    {
        //得到 MAC的注册表键
        RegistryKey macRegistry = Registry.LocalMachine.OpenSubKey("SYSTEM").OpenSubKey("CurrentControlSet").OpenSubKey("Control")
            .OpenSubKey("Class").OpenSubKey("{4D36E972-E325-11CE-BFC1-08002bE10318}");
        IList<string> list = macRegistry.GetSubKeyNames().ToList();
        IPGlobalProperties computerProperties = IPGlobalProperties.GetIPGlobalProperties();
        NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
        var adapter = nics.First(o => o.Name == "本地连接");
        if (adapter == null)
            return null;
        return string.Empty;
    }
    /// <summary>
    /// 设置MAC地址
    /// </summary>
    /// <param name="newMac"></param>
    public void SetMACAddress(string newMac)
    {
        string macAddress;
        string index = GetAdapterIndex(out macAddress);
        if (index == null)
            return;
        //得到 MAC的注册表键
        RegistryKey macRegistry = Registry.LocalMachine.OpenSubKey("SYSTEM").OpenSubKey("CurrentControlSet").OpenSubKey("Control")
            .OpenSubKey("Class").OpenSubKey("{4D36E972-E325-11CE-BFC1-08002bE10318}").OpenSubKey(index, true);
        if (string.IsNullOrEmpty(newMac))
        {
            macRegistry.DeleteValue("NetworkAddress");
        }
        else
        {
            macRegistry.SetValue("NetworkAddress", newMac);
            macRegistry.OpenSubKey("Ndi", true).OpenSubKey("params", true).OpenSubKey("NetworkAddress", true).SetValue("Default", newMac);
            macRegistry.OpenSubKey("Ndi", true).OpenSubKey("params", true).OpenSubKey("NetworkAddress", true).SetValue("ParamDesc", "Network Address");
        }
        Thread oThread = new Thread(new ThreadStart(ReConnect));//new Thread to ReConnect
        oThread.Start();
    }
    /// <summary>
    /// 重设MAC地址
    /// </summary>
    public void ResetMACAddress()
    {
        SetMACAddress(string.Empty);
    }
    /// <summary>
    /// 重新连接
    /// </summary>
    private void ReConnect()
    {
        NetSharingManagerClass netSharingMgr = new NetSharingManagerClass();
        INetSharingEveryConnectionCollection connections = netSharingMgr.EnumEveryConnection;
        foreach (INetConnection connection in connections)
        {
            INetConnectionProps connProps = netSharingMgr.get_NetConnectionProps(connection);
            if (connProps.MediaType == tagNETCON_MEDIATYPE.NCM_LAN)
            {
                connection.Disconnect(); //禁用网络
                connection.Connect();    //启用网络
            }
        }
    }
    /// <summary>
    /// 生成随机MAC地址
    /// </summary>
    /// <returns></returns>
    public string CreateNewMacAddress()
    {
        //return "0016D3B5C493";
        int min = 0;
        int max = 16;
        Random ro = new Random();
        var sn = string.Format("{0}{1}{2}{3}{4}{5}{6}{7}{8}{9}{10}{11}",
           ro.Next(min, max).ToString("x"),//0
           ro.Next(min, max).ToString("x"),//
           ro.Next(min, max).ToString("x"),
           ro.Next(min, max).ToString("x"),
           ro.Next(min, max).ToString("x"),
           ro.Next(min, max).ToString("x"),//5
           ro.Next(min, max).ToString("x"),
           ro.Next(min, max).ToString("x"),
           ro.Next(min, max).ToString("x"),
           ro.Next(min, max).ToString("x"),
           ro.Next(min, max).ToString("x"),//10
           ro.Next(min, max).ToString("x")
            ).ToUpper();
        return sn;
    }
    /// <summary>
    /// 得到Mac地址及注册表对应Index
    /// </summary>
    /// <param name="macAddress"></param>
    /// <returns></returns>
    public string GetAdapterIndex(out string macAddress)
    {
        ManagementClass oMClass = new ManagementClass("Win32_NetworkAdapterConfiguration");
        ManagementObjectCollection colMObj = oMClass.GetInstances();
        macAddress = string.Empty;
        int indexString = 1;
        foreach (ManagementObject objMO in colMObj)
        {
            indexString++;
            if (objMO["MacAddress"] != null && (bool)objMO["IPEnabled"] == true)
            {
                macAddress = objMO["MacAddress"].ToString().Replace(":", "");
                break;
            }
        }
        if (macAddress == string.Empty)
            return null;
        else
            return indexString.ToString().PadLeft(4, '0');
    }
    #region Temp
    public void noting()
    {
        //ManagementClass oMClass = new ManagementClass("Win32_NetworkAdapterConfiguration");
        ManagementClass oMClass = new ManagementClass("Win32_NetworkAdapter");
        ManagementObjectCollection colMObj = oMClass.GetInstances();
        foreach (ManagementObject objMO in colMObj)
        {
            if (objMO["MacAddress"] != null)
            {
                if (objMO["Name"] != null)
                {
                    //objMO.InvokeMethod("Reset", null);
                    objMO.InvokeMethod("Disable", null);//Vista only
                    objMO.InvokeMethod("Enable", null);//Vista only
                }
                //if ((bool)objMO["IPEnabled"] == true)
                //{
                //    //Console.WriteLine(objMO["MacAddress"].ToString());
                //    //objMO.SetPropertyValue("MacAddress", CreateNewMacAddress());
                //    //objMO["MacAddress"] = CreateNewMacAddress();
                //    //objMO.InvokeMethod("Disable", null);
                //    //objMO.InvokeMethod("Enable", null);
                //    //objMO.Path.ReleaseDHCPLease();
                //    var iObj = objMO.GetMethodParameters("EnableDHCP");
                //    var oObj = objMO.InvokeMethod("ReleaseDHCPLease", null, null);
                //    Thread.Sleep(100);
                //    objMO.InvokeMethod("RenewDHCPLease", null, null);
                //}
            }
        }
    }
    public void no()
    {
        Shell32.Folder networkConnectionsFolder = GetNetworkConnectionsFolder();
        if (networkConnectionsFolder == null)
        {
            Console.WriteLine("Network connections folder not found.");
            return;
        }
        Shell32.FolderItem2 networkConnection = GetNetworkConnection(networkConnectionsFolder, string.Empty);
        if (networkConnection == null)
        {
            Console.WriteLine("Network connection not found.");
            return;
        }
        Shell32.FolderItemVerb verb;
        try
        {
            IsNetworkConnectionEnabled(networkConnection, out verb);
            verb.DoIt();
            Thread.Sleep(1000);
            IsNetworkConnectionEnabled(networkConnection, out verb);
            verb.DoIt();
        }
        catch (ArgumentException ex)
        {
            Console.WriteLine(ex.Message);
        }
    }
    /// <summary>
    /// Gets the Network Connections folder in the control panel.
    /// </summary>
    /// <returns>The Folder for the Network Connections folder, or null if it was not found.</returns>
    static Shell32.Folder GetNetworkConnectionsFolder()
    {
        Shell32.Shell sh = new Shell32.Shell();
        Shell32.Folder controlPanel = sh.NameSpace(3); // Control panel
        Shell32.FolderItems items = controlPanel.Items();
        foreach (Shell32.FolderItem item in items)
        {
            if (item.Name == "网络连接")
                return (Shell32.Folder)item.GetFolder;
        }
        return null;
    }
    /// <summary>
    /// Gets the network connection with the specified name from the specified shell folder.
    /// </summary>
    /// <param name="networkConnectionsFolder">The Network Connections folder.</param>
    /// <param name="connectionName">The name of the network connection.</param>
    /// <returns>The FolderItem for the network connection, or null if it was not found.</returns>
    static Shell32.FolderItem2 GetNetworkConnection(Shell32.Folder networkConnectionsFolder, string connectionName)
    {
        Shell32.FolderItems items = networkConnectionsFolder.Items();
        foreach (Shell32.FolderItem2 item in items)
        {
            if (item.Name == "本地连接")
            {
                return item;
            }
        }
        return null;
    }
    /// <summary>
    /// Gets whether or not the network connection is enabled and the command to enable/disable it.
    /// </summary>
    /// <param name="networkConnection">The network connection to check.</param>
    /// <param name="enableDisableVerb">On return, receives the verb used to enable or disable the connection.</param>
    /// <returns>True if the connection is enabled, false if it is disabled.</returns>
    static bool IsNetworkConnectionEnabled(Shell32.FolderItem2 networkConnection, out Shell32.FolderItemVerb enableDisableVerb)
    {
        Shell32.FolderItemVerbs verbs = networkConnection.Verbs();
        foreach (Shell32.FolderItemVerb verb in verbs)
        {
            if (verb.Name == "启用(&A)")
            {
                enableDisableVerb = verb;
                return false;
            }
            else if (verb.Name == "停用(&B)")
            {
                enableDisableVerb = verb;
                return true;
            }
        }
        throw new ArgumentException("No enable or disable verb found.");
    }
    #endregion
}

解决方案二:

自己构建raw socket的包,不过这个windows vista以后不允许发送了
你这个更像SendARP() 做的事情,进行ARP欺骗,获取对应的数据

解决方案三:

1.MAC修改后很可能和其它MAC相同,这一点如何避免。
2.接收是会检查以太网封包包头中的MAC是不是自己的MAC,相同才会接收处理。

解决方案四:

如何修改本机MAC地址

解决方案五:

Linux可以使用超级用户建立的raw socket(原始套接字)
Windows从xp的sp2版本就不允许应用程序使用链路层原始套接字了
再接收回来不太可能。hub环境下打开混杂模式就行,交换机环境么,你得先MAC欺骗,当然如果交换机静态绑定了MAC-PORT就不行了

时间: 2024-12-22 21:31:08

网络编程-如何修改从本机发送出去的数据包的MAC地址的相关文章

c++-如何在windows下C++编程实现循环发送定长数据包?

问题描述 如何在windows下C++编程实现循环发送定长数据包? 为了对内部网络进行相关测试,所以要用C++编程实现一个循环发包程序,用QT平台进行开发,要发送的数据包都是同样大小,且大小由用户自行设置,用户设置的大小是整个数据包的大小,包括Ip头等等.所以想请问一下这个要用什么实现?rawsocket可以吗? 解决方案 http://www.cnblogs.com/shenck/p/4075141.html

sock-怎么用python和原始套接字发送一tcp数据包?

问题描述 怎么用python和原始套接字发送一tcp数据包? 这段代码直接把数据packet_base作为ip的载荷了,怎么才能是packet_base作为tcp的载荷呢?谢谢 sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_TCP) sock.sendto(packet_base, 0, (IP_PACKET_IN, 12321)) sock.close() 解决方案 把你的代码修改成如下就是TCP啦:

c#-用C#语言怎么模拟发送post请求数据包并最终下载文件

问题描述 用C#语言怎么模拟发送post请求数据包并最终下载文件 通过一个在线工具模拟发送post请求数据包发送的内容和返回的数据见下面两张截图,问题来了,怎么根据返回的数据下载这个文件.用C#语言怎么写啊 解决方案 在浏览器中下载,同时用fiddler抓包,然后根据fiddler的结果照着模仿 解决方案二: 用FIDDLER确实可行,谢谢

Java网络编程从入门到精通 (9):使用isXxx方法判断地址类型

本文为原创,如需转载,请注明作者和出处,谢谢! 上一篇:Java网络编程从入门到精通(8):用getAddress方法获得IP地址     IP地址分为普通地址和特殊地址.在前面的文章中所使用的大多数都是普通的IP地址,在本文中将介绍如何利用InetAddress类提供的十个方法来确定一个IP地址是否是一个特殊的IP地址. 一.isAnyLocalAddress方法     当IP地址是通配符地址时返回true,否则返回false.这个通配符地址对于拥有多个网络接口(如两块网卡)的计算机非常拥有

网络编程-求一段从网站读取实时日线数据的vb代码,本人要把实时日线数据不断写进txt文件最后一行

问题描述 求一段从网站读取实时日线数据的vb代码,本人要把实时日线数据不断写进txt文件最后一行 谢谢各位大神!本人业余爱好,但是现在对网络编程不熟,求帮助! 日线数据直接读到一个字符串里面就好了,用空格或tab隔开都行 解决方案 这不是S吗?直接写到数据库的表里就好了

网络编程高手请进来,Socket发送图片错误~~~

问题描述 发送端主要代码:#region用Socket发送图片privatevoidtime(objecto){IPAddresssIP=IPAddress.Parse("127.0.0.1");IPEndPointssIP=newIPEndPoint(sIP,8001);Sockets=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);try{s.Connect(sIP,8001);}ca

Java网络编程从入门到精通(9):使用isXxx方法判断地址类型

IP地址分为普通地址和特殊地址.在前面的文章中所使用的大多数都是普通的IP地址,在本文中将介绍如何利用InetAddress类提供的十个方法来确定一个IP地址是否是一个特殊的IP地址. 一.isAnyLocalAddress方法 当IP地址是通配符地址时返回true,否则返回false.这个通配符地址对于拥有多个网络接口(如两块网卡)的计算机非常拥有.使用通配符地址可以允许在服务器主机接受来自任何网络接口的客户端连接.IPv4的通配符地址是0.0.0.0.IPv6的通配符地址是0:0:0:0:0

Linux网络 - 数据包的接收过程

本文将介绍在Linux系统中,数据包是如何一步一步从网卡传到进程手中的. 如果英文没有问题,强烈建议阅读后面参考里的两篇文章,里面介绍的更详细. 本文只讨论以太网的物理网卡,不涉及虚拟设备,并且以一个UDP包的接收过程作为示例. 本示例里列出的函数调用关系来自于kernel 3.13.0,如果你的内核不是这个版本,函数名称和相关路径可能不一样,但背后的原理应该是一样的(或者有细微差别) 网卡到内存 网卡需要有驱动才能工作,驱动是加载到内核中的模块,负责衔接网卡和内核的网络模块,驱动在加载的时候将

Linux网络编程入门

(一)Linux网络编程--网络知识介绍 Linux网络编程--网络知识介绍 客户端和服务端          网络程序和普通的程序有一个最大的区别是网络程序是由两个部分组成的--客户端和服务器端. 客户端         在网络程序中,如果一个程序主动和外面的程序通信,那么我们把这个程序称为客户端程序. 比如我们使用ftp程序从另外一         个地方获取文件的时候,是我们的ftp程序主动同外面进行通信(获取文件), 所以这个地方我们的ftp程序就是客户端程序.  服务端