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

如何为便携可执行程序添加MAC地址验证并生成单可执行文件

Add MAC Address Validation to Your Portable EXE (Single Executable)

Alright, let's break down how to add MAC address validation to your portable executable so it only runs on devices with a specific MAC address. The goal is: on startup, check if any of the device's network adapters match your target MAC—if yes, run the program normally; if not, exit immediately. Here's a step-by-step approach that keeps everything in a single EXE file:

Core Concept

The program will:

  • Retrieve all network adapter MAC addresses on the local machine when it starts.
  • Compare each retrieved MAC against your pre-specified target MAC.
  • If a match is found, proceed with the original program logic.
  • If no matches are found, display a message (optional) and exit immediately.

Practical Implementation (C/C++ for Windows)

C/C++ is ideal here because it compiles to a standalone EXE with no external dependencies. If you're modifying an existing program, you can insert this validation logic at the very start of your main function (or WinMain for GUI apps).

Step 1: Code to Fetch MAC Addresses

Use Windows' GetAdaptersAddresses API (the modern replacement for GetAdaptersInfo) to get all adapter details, including MAC addresses. Here's a reusable function:

#include <windows.h>
#include <iphlpapi.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Link against iphlpapi.lib
#pragma comment(lib, "iphlpapi.lib")

// Convert MAC byte array to human-readable string (e.g., "00-1A-2B-3C-4D-5E")
void MacToString(BYTE* mac, char* output) {
    sprintf(output, "%02X-%02X-%02X-%02X-%02X-%02X",
            mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
}

// Check if any adapter's MAC matches the target
int IsTargetMacPresent(const char* targetMac) {
    PIP_ADAPTER_ADDRESSES pAddresses = NULL;
    ULONG outBufLen = 0;
    DWORD retVal;

    // First call to get the required buffer size
    retVal = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &outBufLen);
    if (retVal == ERROR_BUFFER_OVERFLOW) {
        pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen);
        if (!pAddresses) {
            printf("Memory allocation failed\n");
            return 0;
        }
        // Second call to get actual adapter data
        retVal = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, pAddresses, &outBufLen);
    }

    if (retVal == NO_ERROR) {
        PIP_ADAPTER_ADDRESSES pCurrAddresses = pAddresses;
        char currentMac[18]; // Holds formatted MAC string

        while (pCurrAddresses) {
            if (pCurrAddresses->PhysicalAddressLength == 6) { // Valid MAC length
                MacToString(pCurrAddresses->PhysicalAddress, currentMac);
                // Compare (case-insensitive)
                if (_stricmp(currentMac, targetMac) == 0) {
                    free(pAddresses);
                    return 1; // Match found
                }
            }
            pCurrAddresses = pCurrAddresses->Next;
        }
    } else {
        printf("GetAdaptersAddresses failed: %d\n", retVal);
    }

    if (pAddresses) free(pAddresses);
    return 0; // No match found
}

Step 2: Add Validation to Your Program

Insert this check at the very beginning of your entry point. For a console app:

int main() {
    const char* TARGET_MAC = "00-1A-2B-3C-4D-5E"; // Replace with your target MAC

    // Validate MAC first
    if (!IsTargetMacPresent(TARGET_MAC)) {
        printf("Invalid device. Exiting...\n");
        exit(EXIT_FAILURE);
    }

    // Your original program logic starts here
    printf("MAC validated. Running program...\n");
    // ... rest of your code ...

    return 0;
}

For a GUI app (using WinMain), replace the printf with a message box and exit:

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    const char* TARGET_MAC = "00-1A-2B-3C-4D-5E";

    if (!IsTargetMacPresent(TARGET_MAC)) {
        MessageBox(NULL, L"Invalid device. Program will exit.", L"Error", MB_OK | MB_ICONERROR);
        return 0;
    }

    // Your GUI app logic here
    MessageBox(NULL, L"MAC validated. Program running.", L"Success", MB_OK);
    return 0;
}

Compile to Single EXE

  • Using MSVC: Open Developer Command Prompt, run:
    cl your_program.cpp iphlpapi.lib /Fe:your_program.exe
    
  • Using MinGW: Run:
    g++ your_program.cpp -o your_program.exe -liphlpapi
    

Both commands will produce a standalone EXE with no external dependencies.

Key Notes

  • MAC Format: Ensure your target MAC uses hyphens (-) and uppercase letters (or modify the MacToString function to match your preferred format, e.g., colons :). The _stricmp makes the comparison case-insensitive.
  • Multiple Adapters: The code checks all network adapters (Ethernet, Wi-Fi, Bluetooth, etc.)—so if any adapter matches, the program runs.
  • MAC Spoofing: Keep in mind that MAC addresses can be spoofed, so this is a basic validation method, not a secure anti-piracy solution.
  • Existing EXEs: If you can't modify the source code of your existing EXE, you'd need to use reverse engineering tools to inject the validation logic—but this is more complex and may violate software licensing terms. It's always better to add the code at the source level if possible.

内容的提问来源于stack exchange,提问作者Mahmoud Dabash

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:39:06