如何在Windows上编程检测随机硬件地址状态并过滤网卡?
检测Windows随机硬件地址设置并过滤网卡
一、全局启用状态检测
Windows全局随机硬件地址设置存储在以下注册表路径:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Randomization
- 键名:
RandomizeAdapterAddresses(DWORD类型) - 值说明:0 = 全局禁用;1 = 全局启用
C++ 全局状态读取示例
#include <windows.h> #include <iostream> bool GetGlobalRandomMacState() { HKEY hKey; DWORD dwValue = 0; DWORD dwType = REG_DWORD; DWORD dwSize = sizeof(dwValue); if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkList\\Randomization", 0, KEY_READ, &hKey) == ERROR_SUCCESS) { RegQueryValueEx(hKey, L"RandomizeAdapterAddresses", nullptr, &dwType, (LPBYTE)&dwValue, &dwSize); RegCloseKey(hKey); } return dwValue == 1; } int main() { bool isGlobalEnabled = GetGlobalRandomMacState(); std::cout << "全局随机硬件地址状态:" << (isGlobalEnabled ? "已启用" : "已禁用") << std::endl; return 0; }
C# 全局状态读取示例
using Microsoft.Win32; using System; class Program { static bool GetGlobalRandomMacState() { using (var key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Randomization")) { if (key == null) return false; var value = key.GetValue("RandomizeAdapterAddresses"); return value != null && (int)value == 1; } } static void Main() { bool isGlobalEnabled = GetGlobalRandomMacState(); Console.WriteLine($"全局随机硬件地址状态:{(isGlobalEnabled ? "已启用" : "已禁用")}"); } }
二、单网卡状态检测与过滤
每个网卡的随机硬件地址设置存储在网络适配器类的注册表项中,路径为:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}
该路径下的子项(如0001、0002)对应每个网卡,需匹配网卡硬件信息后读取RandomMacAddress键(DWORD类型,0=禁用,1=启用)。
C++ 实现步骤与代码
- 使用
GetAdaptersAddresses获取所有网卡的MAC地址、设备实例路径等信息 - 通过SetupDi系列函数将设备实例路径关联到注册表子项
- 读取对应注册表项的
RandomMacAddress值,过滤出未启用的网卡
#include <windows.h> #include <iphlpapi.h> #include <setupapi.h> #include <initguid.h> #include <devguid.h> #include <iostream> #include <vector> #pragma comment(lib, "iphlpapi.lib") #pragma comment(lib, "setupapi.lib") // 获取网卡的随机MAC启用状态 bool IsRandomMacEnabledForAdapter(const wchar_t* adapterDevicePath) { HDEVINFO hDevInfo = SetupDiGetClassDevs(&GUID_DEVCLASS_NET, nullptr, nullptr, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if (hDevInfo == INVALID_HANDLE_VALUE) return false; SP_DEVICE_INTERFACE_DATA deviceInterfaceData = {0}; deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); for (DWORD i = 0; SetupDiEnumDeviceInterfaces(hDevInfo, nullptr, &GUID_DEVCLASS_NET, i, &deviceInterfaceData); i++) { DWORD reqSize = 0; SetupDiGetDeviceInterfaceDetail(hDevInfo, &deviceInterfaceData, nullptr, 0, &reqSize, nullptr); std::vector<BYTE> detailBuf(reqSize); PSP_DEVICE_INTERFACE_DETAIL_DATA pDetailData = reinterpret_cast<PSP_DEVICE_INTERFACE_DETAIL_DATA>(detailBuf.data()); pDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); SP_DEVINFO_DATA devInfoData = {0}; devInfoData.cbSize = sizeof(SP_DEVINFO_DATA); if (SetupDiGetDeviceInterfaceDetail(hDevInfo, &deviceInterfaceData, pDetailData, reqSize, nullptr, &devInfoData)) { if (_wcsicmp(pDetailData->DevicePath, adapterDevicePath) == 0) { // 获取注册表路径 wchar_t regPath[MAX_PATH]; if (SetupDiGetDeviceRegistryProperty(hDevInfo, &devInfoData, SPDRP_DRIVER, nullptr, reinterpret_cast<PBYTE>(regPath), sizeof(regPath), nullptr)) { wchar_t fullRegPath[MAX_PATH]; swprintf_s(fullRegPath, L"%s\\RandomMacAddress", regPath); HKEY hKey; DWORD dwValue = 0; DWORD dwType = REG_DWORD; DWORD dwSize = sizeof(dwValue); if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, fullRegPath, 0, KEY_READ, &hKey) == ERROR_SUCCESS) { RegQueryValueEx(hKey, nullptr, nullptr, &dwType, (LPBYTE)&dwValue, &dwSize); RegCloseKey(hKey); SetupDiDestroyDeviceInfoList(hDevInfo); return dwValue == 1; } } break; } } } SetupDiDestroyDeviceInfoList(hDevInfo); return false; } // 获取未启用随机MAC的网卡MAC列表 void GetNonRandomMacAdapters() { ULONG outBufLen = 0; GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, nullptr, &outBufLen); std::vector<BYTE> buf(outBufLen); PIP_ADAPTER_ADDRESSES pAddresses = reinterpret_cast<PIP_ADAPTER_ADDRESSES>(buf.data()); if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, pAddresses, &outBufLen) == NO_ERROR) { for (PIP_ADAPTER_ADDRESSES pCurr = pAddresses; pCurr != nullptr; pCurr = pCurr->Next) { if (pCurr->PhysicalAddressLength == 0) continue; // 检查是否启用随机MAC bool isRandomEnabled = IsRandomMacEnabledForAdapter(pCurr->AdapterName); if (!isRandomEnabled) { // 输出MAC地址 std::cout << "网卡名称:" << pCurr->FriendlyName << ",MAC地址:"; for (DWORD i = 0; i < pCurr->PhysicalAddressLength; i++) { if (i > 0) std::cout << "-"; std::cout << std::hex << static_cast<int>(pCurr->PhysicalAddress[i]); } std::cout << std::dec << std::endl; } } } } int main() { GetNonRandomMacAdapters(); return 0; }
C# 实现步骤与代码
- 使用
NetworkInterface.GetAllNetworkInterfaces()获取所有物理网卡 - 通过WMI查询网卡的设备ID,关联到注册表子项
- 读取
RandomMacAddress值并过滤
using System; using System.Collections.Generic; using System.Net.NetworkInformation; using System.Management; using Microsoft.Win32; class Program { static bool IsRandomMacEnabled(string deviceId) { var netClassKey = Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}"); if (netClassKey == null) return false; foreach (var subKeyName in netClassKey.GetSubKeyNames()) { using (var subKey = netClassKey.OpenSubKey(subKeyName)) { if (subKey == null) continue; var hardwareIds = subKey.GetValue("HardwareID") as string[]; if (hardwareIds == null) continue; if (Array.Exists(hardwareIds, id => id.Equals(deviceId, StringComparison.OrdinalIgnoreCase))) { var randomMacValue = subKey.GetValue("RandomMacAddress"); return randomMacValue != null && (int)randomMacValue == 1; } } } return false; } static void GetNonRandomMacAdapters() { var nicList = NetworkInterface.GetAllNetworkInterfaces(); var wmiSearcher = new ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapter WHERE PhysicalAdapter = True"); foreach (var nic in nicList) { if (nic.NetworkInterfaceType == NetworkInterfaceType.Loopback) continue; var macAddress = nic.GetPhysicalAddress(); if (macAddress == null || macAddress.GetAddressBytes().Length == 0) continue; // 通过WMI获取设备ID foreach (ManagementObject obj in wmiSearcher.Get()) { if (obj["Name"]?.ToString() == nic.Name) { string deviceId = obj["DeviceID"].ToString(); bool isRandomEnabled = IsRandomMacEnabled(deviceId); if (!isRandomEnabled) { Console.WriteLine($"网卡名称:{nic.Name},MAC地址:{macAddress}"); } break; } } } } static void Main() { GetNonRandomMacAdapters(); } }
内容的提问来源于stack exchange,提问作者Rok Andrejc
相关产品推荐
相关产品推荐

