通过适配器描述更改Mac地址

2024-01-08

我正在使用 Nate True @ 提供的优秀工具http://devices.natetrue.com/macshift/ http://devices.natetrue.com/macshift/它通过适配器名称更改 Mac 地址。这是源代码:

const int versionMajor = 1;
const int versionMinor = 1;

#include <windows.h>
#include <objbase.h>
#include <netcon.h>
#include <stdio.h>
#include "validmacs.h"

void SetMAC(char * AdapterName, char * NewMAC) {
  HKEY hListKey = NULL;
  HKEY hKey = NULL;
  RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}",
    0, KEY_READ, &hListKey);
  if (!hListKey) {
    printf("Failed to open adapter list key\n");
    return;
    }
  FILETIME writtenTime;
  char keyNameBuf[512], keyNameBuf2[512];
  DWORD keyNameBufSiz = 512;
  DWORD crap;
  int i = 0;
  bool found = false;
  while (RegEnumKeyEx(hListKey, i++, keyNameBuf, &keyNameBufSiz, 0, NULL, NULL, &writtenTime)
        == ERROR_SUCCESS) {
    _snprintf(keyNameBuf2, 512, "%s\\Connection", keyNameBuf);
    hKey = NULL;
    RegOpenKeyEx(hListKey, keyNameBuf2, 0, KEY_READ, &hKey);
    if (hKey) {
      keyNameBufSiz = 512;
      if (RegQueryValueEx(hKey, "Name", 0, &crap, (LPBYTE)keyNameBuf2, &keyNameBufSiz)
        == ERROR_SUCCESS && strcmp(keyNameBuf2, AdapterName) == 0) {
        printf("Adapter ID is %s\n", keyNameBuf);
        found = true;
        break;
        }
      RegCloseKey(hKey);
      }
    keyNameBufSiz = 512;
    }
  RegCloseKey(hListKey);
  if (!found) {
    printf("Could not find adapter name '%s'.\nPlease make sure this is the name you gave it in Network Connections.\n", AdapterName);
    return;
    }
  RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}",
    0, KEY_READ, &hListKey);
  if (!hListKey) {
    printf("Failed to open adapter list key in Phase 2\n");
    return;
    }
  i = 0;
  char buf[512];
  while (RegEnumKeyEx(hListKey, i++, keyNameBuf2, &keyNameBufSiz, 0, NULL, NULL, &writtenTime)
        == ERROR_SUCCESS) {
    hKey = NULL;
    RegOpenKeyEx(hListKey, keyNameBuf2, 0, KEY_READ | KEY_SET_VALUE, &hKey);
    if (hKey) {
      keyNameBufSiz = 512;
      if ((RegQueryValueEx(hKey, "NetCfgInstanceId", 0, &crap, (LPBYTE)buf, &keyNameBufSiz)
        == ERROR_SUCCESS) && (strcmp(buf, keyNameBuf) == 0)) {
        RegSetValueEx(hKey, "NetworkAddress", 0, REG_SZ, (LPBYTE)NewMAC, strlen(NewMAC) + 1);
        //printf("Updating adapter index %s (%s=%s)\n", keyNameBuf2, buf, keyNameBuf);
        //break;
        }
      RegCloseKey(hKey);
      }
    keyNameBufSiz = 512;
    }
  RegCloseKey(hListKey);

  }

void ResetAdapter(char * AdapterName) {
  struct _GUID guid = {0xBA126AD1,0x2166,0x11D1,0};
  memcpy(guid.Data4, "\xB1\xD0\x00\x80\x5F\xC1\x27\x0E", 8);
  unsigned short * buf = new unsigned short[strlen(AdapterName)+1];

  void (__stdcall *NcFreeNetConProperties) (NETCON_PROPERTIES *);
  HMODULE NetShell_Dll = LoadLibrary("Netshell.dll");
  if (!NetShell_Dll) {
    printf("Couldn't load Netshell.dll\n");
    return;
    }
  NcFreeNetConProperties = (void (__stdcall *)(struct tagNETCON_PROPERTIES *))GetProcAddress(NetShell_Dll, "NcFreeNetconProperties");
  if (!NcFreeNetConProperties) {
    printf("Couldn't load required DLL function\n");
    return;
    }

  for (unsigned int i = 0; i <= strlen(AdapterName); i++) {
    buf[i] = AdapterName[i];
    }
  CoInitialize(0);
    INetConnectionManager * pNCM = NULL;    
    HRESULT hr = ::CoCreateInstance(guid,
                                     NULL,
                                     CLSCTX_ALL,
                                     __uuidof(INetConnectionManager),
                                     (void**)&pNCM);
    if (!pNCM)
        printf("Failed to instantiate required object\n");
    else {
        IEnumNetConnection * pENC;
        pNCM->EnumConnections(NCME_DEFAULT, &pENC);
        if (!pENC) {
          printf("Could not enumerate Network Connections\n");
          }
        else {
          INetConnection * pNC;
          ULONG fetched;
          NETCON_PROPERTIES * pNCP;
          do {
            pENC->Next(1, &pNC, &fetched);
            if (fetched && pNC) {
              pNC->GetProperties(&pNCP);
              if (pNCP) {
                if (wcscmp(pNCP->pszwName, buf) == 0) {
                  pNC->Disconnect();
                  pNC->Connect();
                  }
                NcFreeNetConProperties(pNCP);
                }
              }
            } while (fetched);
            pENC->Release();
          }
        pNCM->Release();
    }

    FreeLibrary(NetShell_Dll);
    CoUninitialize ();
  }

bool IsValidMAC(char * str) {
  if (strlen(str) != 12) return false;
  for (int i = 0; i < 12; i++) {
    if ((str[i] < '0' || str[i] > '9') 
          && (str[i] < 'a' || str[i] > 'f')
          && (str[i] < 'A' || str[i] > 'F')) {
      return false;
      }
    }
  return true;
  }

void ShowHelp() {
  printf("Usage: macshift [options] [mac-address]\n\n");
  printf("Options:\n");
  printf("\t-i [adapter-name]     The adapter name from Network Connections.\n");
  printf("\t-r                    Uses a random MAC address. This is the default.\n");
  printf("\t-d                    Restores the original MAC address.\n");
  printf("\t--help                Shows this screen.\n\n");
  printf("Macshift uses special undocumented functions in the Windows COM Interface that\n");
  printf(" allow you to change an adapter's MAC address without needing to restart.\n");
  printf("When you change a MAC address, all your connections are closed automatically\n");
  printf(" and your adapter is reset.\n");
  }

//Generates a random MAC that is actually plausible
void RandomizeMAC(char * newmac) {
  _snprintf(newmac, 6, "%06X", rand() % numMacs);
  for (int i = 3; i < 6; i++) {
    _snprintf(&newmac[i*2], 2, "%02X", rand() & 0xFF);
    }
  newmac[12] = 0;
  }

int main(int argc, char * * argv) {
  printf("Macshift v%i.%i, MAC Changing Utility by Nathan True, [email protected] /cdn-cgi/l/email-protection\n\n", versionMajor, versionMinor);

  //Parse commandline arguments
  char * adapter = "Wireless";
  char newmac[13];
  int i;
  if (argc == 1) {
    ShowHelp();
    return 0;
    }
  //Start out with a random MAC
  srand(GetTickCount());
  RandomizeMAC(newmac);
  for (i = 1; i < argc; i++) {
    if (argv[i][0] == '-') {
      switch (argv[i][1]) {
        case '-': //Extended argument
          if (strcmp(argv[i]+2, "help") == 0) {
            ShowHelp();
            return 0;
            }
          break;
        case 'r': //Random setting, this is the default
          break;
        case 'i': //Adapter name follows
          if (argc > i + 1) adapter = argv[++i];
          break;     
        case 'd': //Reset the MAC address
          newmac[0] = 0;
        }
      }
    else {
      if (IsValidMAC(argv[i])) strncpy(newmac, argv[i], 13);
      else printf("MAC String %s is not valid. MAC addresses must m/^[0-9a-fA-F]{12}$/.\n", argv[i]);
      }
    }

  printf("Setting MAC on adapter '%s' to %s...\n", adapter, newmac[0] ? newmac : "original MAC");
  SetMAC(adapter, newmac);
  printf("Resetting adapter...\n");
  fflush(stdout);
  ResetAdapter(adapter);
  printf("Done\n");
  return 0;
  }

除了名称之外,我还想通过适配器的描述来更改 Mac 地址。所以我需要修改这段代码,以便如果找不到匹配的名称,它会根据描述回退到更改 mac。

这是一个适配器示例:

名称: 本地连接

描述:Marvell Yukon 88E8055 PCI-E 千兆以太网控制器

不幸的是,作为一名 Java 开发人员,我对 C++ 的经验有限,因此我们将不胜感激。


下面是 GetAdaptersInfo 的 C 示例,它打印出每个适配器的名称和描述(您可以通过在匹配时调用 SetMAC 轻松地使其适合您的代码):



    VOID EnumerateNetworkAdapters(VOID)
    {
        ULONG len = 0;
        if (ERROR_BUFFER_OVERFLOW == GetAdaptersInfo(NULL, &len;))
        {
            IP_ADAPTER_INFO *ipai;
            ipai = malloc(len);
            if (NO_ERROR == GetAdaptersInfo(ipai, &len;))
            {
                IP_ADAPTER_INFO *p = ipai;
                do
                {
                    printf("name=%s description=%s\n", p->AdapterName, p->Description);
                }
                while (p = p->Next);
            }
            free(ipai);
        }
    }
  

链接到“Iphlpapi.lib”。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

通过适配器描述更改Mac地址 的相关文章

  • 类型中的属性名称必须是唯一的

    我正在使用 Entity Framework 5 并且有以下实体 public class User public Int32 Id get set public String Username get set public virtual
  • 如何在 Cassandra 中存储无符号整数?

    我通过 Datastax 驱动程序在 Cassandra 中存储一些数据 并且需要存储无符号 16 位和 32 位整数 对于无符号 16 位整数 我可以轻松地将它们存储为有符号 32 位整数 并根据需要进行转换 然而 对于无符号 64 位整
  • std::vector 与 std::stack

    有什么区别std vector and std stack 显然 向量可以删除集合中的项目 尽管比列表慢得多 而堆栈被构建为仅后进先出的集合 然而 堆栈对于最终物品操作是否更快 它是链表还是动态重新分配的数组 我找不到关于堆栈的太多信息 但
  • 随着时间的推移,添加到 List 变得非常慢

    我正在解析一个大约有 1000 行的 html 表 我从一个字符串中添加 10 个字符串 td 每行到一个list td
  • 无限循环与无限递归。两者都是未定义的吗?

    无副作用的无限循环是未定义的行为 看here https coliru stacked crooked com view id 24e0a58778f67cd4举个例子参考参数 https en cppreference com w cpp
  • 需要帮助优化算法 - 两百万以下所有素数的总和

    我正在尝试做一个欧拉计划 http projecteuler net问题 我正在寻找 2 000 000 以下所有素数的总和 这就是我所拥有的 int main int argc char argv unsigned long int su
  • 访问外部窗口句柄

    我当前正在处理的程序有问题 这是由于 vista Windows 7 中增强的安全性引起的 特别是 UIPI 它阻止完整性级别较低的窗口与较高完整性级别的窗口 对话 就我而言 我想告诉具有高完整性级别的窗口进入我们的应用程序 它在 XP 或
  • 在 Unity 中实现 Fur with Shells 技术

    我正在尝试在 Unity 中实现皮毛贝壳技术 http developer download nvidia com SDK 10 5 direct3d Source Fur doc FurShellsAndFins pdf Fins 技术被
  • C# xml序列化必填字段

    我需要将一些字段标记为需要写入 XML 文件 但没有成功 我有一个包含约 30 个属性的配置类 这就是为什么我不能像这样封装所有属性 public string SomeProp get return someProp set if som
  • 游戏内的java.awt.Robot?

    我正在尝试使用下面的代码来模拟击键 当我打开记事本时 它工作正常 但当我打开我想使用它的游戏时 它没有执行任何操作 所以按键似乎不起作用 我尝试模拟鼠标移动和点击 这些动作确实有效 有谁知道如何解决这个问题 我发现这个问题 如何在游戏中使用
  • 为什么使用小于 32 位的整数?

    我总是喜欢使用最小尺寸的变量 这样效果就很好 但是如果我使用短字节整数而不是整数 并且内存是 32 位字可寻址 这真的会给我带来好处吗 编译器是否会做一些事情来增强内存使用 对于局部变量 它可能没有多大意义 但是在具有数千甚至数百万项的结构
  • 复制目录下所有文件

    如何将一个目录中的所有内容复制到另一个目录而不循环遍历每个文件 你不能 两者都不Directory http msdn microsoft com en us library system io directory aspx nor Dir
  • 编译时展开 for 循环内的模板参数?

    维基百科 here http en wikipedia org wiki Template metaprogramming Compile time code optimization 给出了 for 循环的编译时展开 我想知道我们是否可以
  • 在 WPF 中使用 ReactiveUI 提供长时间运行命令反馈的正确方法

    我有一个 C WPF NET 4 5 应用程序 用户将用它来打开某些文件 然后 应用程序将经历很多动作 读取文件 通过许多插件和解析器传递它 这些文件可能相当大 gt 100MB 因此这可能需要一段时间 我想让用户了解 UI 中发生的情况
  • 对于某些 PDF 文件,LoadIFilter() 返回 -2147467259

    我正在尝试使用 Adob e IFilter 搜索 PDF 文件 我的代码是用 C 编写的 我使用 p invoke 来获取 IFilter 的实例 DllImport query dll SetLastError true CharSet
  • 如何将 GIT 调用的输出获取到批处理脚本中的变量中?

    我有一个 git 命令来获取当前存储库的最新 SHA 如下所示 git log pretty format H n 1 我有一个 Windows 批处理脚本 我想按如下方式使用它 SET CURRENT SHA 但我不知道如何将从 git
  • 在OpenGL中,我可以在坐标(5, 5)处精确地绘制一个像素吗?

    我所说的 5 5 正是指第五行第五列 我发现使用屏幕坐标来绘制东西非常困难 OpenGL 中的所有坐标都是相对的 通常范围从 1 0 到 1 0 为什么阻止程序员使用屏幕坐标 窗口坐标如此严重 最简单的方法可能是通过以下方式设置投影以匹配渲
  • Mono 应用程序在非阻塞套接字发送时冻结

    我在 debian 9 上的 mono 下运行一个服务器应用程序 大约有 1000 2000 个客户端连接 并且应用程序经常冻结 CPU 使用率达到 100 我执行 kill QUIT pid 来获取线程堆栈转储 但它总是卡在这个位置
  • 现代编译器是否优化乘以 1 和 -1

    如果我写 template
  • 如何确定 CultureInfo 实例是否支持拉丁字符

    是否可以确定是否CultureInfo http msdn microsoft com en us library system globalization cultureinfo aspx我正在使用的实例是否基于拉丁字符集 我相信你可以使

随机推荐