You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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++ 实现步骤与代码

  1. 使用GetAdaptersAddresses获取所有网卡的MAC地址、设备实例路径等信息
  2. 通过SetupDi系列函数将设备实例路径关联到注册表子项
  3. 读取对应注册表项的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# 实现步骤与代码

  1. 使用NetworkInterface.GetAllNetworkInterfaces()获取所有物理网卡
  2. 通过WMI查询网卡的设备ID,关联到注册表子项
  3. 读取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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 11:01:14