gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 10:08:20 31 4
gpt4 key购买 nike

我正在使用 Nate True @ 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, macshift@natetrue.com\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 千兆以太网 Controller

不幸的是,作为一名 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”的链接。

关于c++ - 通过适配器描述更改 Mac 地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8627728/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com