不用inf安裝ndis filter驅(qū)動

killvxk之前分享了一個代碼
https://bbs.pediy.com/thread-226472.htm

可惜發(fā)現(xiàn)晚了尿扯,那個連接無效了粱玲,只好自己擼了一個
調(diào)試上比較簡單拿著processmonitor 配合vm建一些快照,看看日志,就完事了空幻。
然后就是擼代碼蚕钦。

代碼中有個bug沧卢,其實也不算bug讥脐,沒準(zhǔn)還是個優(yōu)勢。
不過對于 xx 項目來說幔戏,NDIS Filter 太復(fù)雜了玛追,WFP 比較簡單,最后項目還是選擇WFP

/*
mengxp works 2020
QQ: 4003032
*/
#define _CRT_SECURE_NO_WARNINGS
#include <winsock2.h>
#include <netioapi.h>
#include <stdio.h>
#include <Shlwapi.h>
#include <setupapi.h>
 
#pragma comment(lib, "setupapi.lib")
#pragma comment(lib, "iphlpapi.lib")
 
DWORD OsVerMajor,OsVerMinor,OsVerWorkstation;
BOOL Is64BitWindows;
 
typedef BOOL (WINAPI *PISWOW64)(HANDLE hProcess,PBOOL pIsWow64);
typedef BOOL (WINAPI *PDISABLE_FS_REDIR)(PVOID *OldValue);
typedef BOOL (WINAPI *PREVERT_FS_REDIR)(PVOID OldValue);
typedef NTSTATUS (WINAPI *PFN_RTL_ADJUST_PRIVILEGE)(int, BOOL, BOOL, int *);
#define SE_DEBUG_PRIVILEGE  0x14
 
typedef enum tagCOMPONENT_CHARACTERISTICS {
    NCF_VIRTUAL                     = 0x1,
    NCF_SOFTWARE_ENUMERATED         = 0x2,
    NCF_PHYSICAL                    = 0x4,
    NCF_HIDDEN                      = 0x8,
    NCF_NO_SERVICE                  = 0x10,
    NCF_NOT_USER_REMOVABLE          = 0x20,
    NCF_MULTIPORT_INSTANCED_ADAPTER = 0x40,
    NCF_HAS_UI                      = 0x80,
    NCF_SINGLE_INSTANCE             = 0x100,
    NCF_FILTER                      = 0x400,
    NCF_DONTEXPOSELOWER             = 0x1000,
    NCF_HIDE_BINDING                = 0x2000,
    NCF_NDIS_PROTOCOL               = 0x4000,
    NCF_FIXED_BINDING               = 0x20000,
    NCF_LW_FILTER                   = 0x40000
} COMPONENT_CHARACTERISTICS;
 
VOID GetOsVer()
{
    HMODULE hKernel32 = LoadLibraryA("Kernel32.dll");
    PISWOW64 pfnIsWow64Process = (PISWOW64)GetProcAddress(hKernel32,"IsWow64Process");
    BOOL bIsWow64 = FALSE;
    OSVERSIONINFOEX OsVer;
 
    memset(&OsVer,0,sizeof(OsVer));
    OsVer.dwOSVersionInfoSize = sizeof(OsVer);
    GetVersionEx((OSVERSIONINFO *)&OsVer);
 
    OsVerMajor = OsVer.dwMajorVersion;
    OsVerMinor = OsVer.dwMinorVersion;
    OsVerWorkstation = OsVer.wProductType == VER_NT_WORKSTATION ? TRUE : FALSE;
 
    if(pfnIsWow64Process)
        pfnIsWow64Process(GetCurrentProcess(),&Is64BitWindows);
}
 
VOID AdjustDebugPrivilege()
{
    HMODULE hNtDll = LoadLibraryA("ntdll.dll");
    PFN_RTL_ADJUST_PRIVILEGE RtlAdjustPrivilege = (PFN_RTL_ADJUST_PRIVILEGE)GetProcAddress(hNtDll,"RtlAdjustPrivilege");
    int Enabled;
 
    RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, TRUE, FALSE, &Enabled);
}
 
BOOL ShutdownWow64Redir(PVOID *ppOldFsRedir)
{
    HMODULE hKernel32 = LoadLibraryA("Kernel32.dll");
    PISWOW64 pfnIsWow64Process = (PISWOW64)GetProcAddress(hKernel32,"IsWow64Process");
    PDISABLE_FS_REDIR pfnDisableFsRedir = (PDISABLE_FS_REDIR)GetProcAddress(hKernel32,"Wow64DisableWow64FsRedirection");
    PREVERT_FS_REDIR pfnRevertFsRedir = (PREVERT_FS_REDIR)GetProcAddress(hKernel32,"Wow64RevertWow64FsRedirection");
    BOOL bIsWow64 = FALSE;
    BOOL bRet = FALSE;
 
    if(pfnIsWow64Process)
        pfnIsWow64Process(GetCurrentProcess(),&bIsWow64);
 
    if(bIsWow64 && pfnDisableFsRedir)
    {
        bRet = pfnDisableFsRedir(ppOldFsRedir);
    }
    return bRet;
}
 
BOOL RevertWow64Redir(PVOID pOldFsRedir)
{
    HMODULE hKernel32 = LoadLibraryA("Kernel32.dll");
    PISWOW64 pfnIsWow64Process = (PISWOW64)GetProcAddress(hKernel32,"IsWow64Process");
    PDISABLE_FS_REDIR pfnDisableFsRedir = (PDISABLE_FS_REDIR)GetProcAddress(hKernel32,"Wow64DisableWow64FsRedirection");
    PREVERT_FS_REDIR pfnRevertFsRedir = (PREVERT_FS_REDIR)GetProcAddress(hKernel32,"Wow64RevertWow64FsRedirection");
    BOOL bIsWow64 = FALSE;
    BOOL bRet = FALSE;
 
    if(pfnIsWow64Process)
        pfnIsWow64Process(GetCurrentProcess(),&bIsWow64);
 
    if(bIsWow64 && pfnRevertFsRedir)
    {
        bRet = pfnRevertFsRedir(pOldFsRedir);
    }
    return bRet;
}
 
//////////////////////////////////////////////////////////////////////////
 
BOOL _IsServiceRunning(LPCSTR ServiceName)
{
    SC_HANDLE hSc = NULL, hService = NULL;
    BOOL bRunning = FALSE;
 
    do {
        SERVICE_STATUS Status;
 
        hSc = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
        if(!hSc)
            break;
 
        hService = OpenServiceA(hSc, ServiceName, SERVICE_ALL_ACCESS);
        if(!hService)
            break;
 
        if(!QueryServiceStatus(hService, &Status))
            break;
 
        if(Status.dwCurrentState != SERVICE_STOPPED)
            bRunning = TRUE;
 
    } while (FALSE);
 
    if(hSc)
        CloseServiceHandle(hSc);
 
    if(hService)
        CloseServiceHandle(hService);
 
    return bRunning;
}
 
BOOL _StartService(LPCSTR ServiceName)
{
    SC_HANDLE hSc = NULL, hService = NULL;
    BOOL bSuccess = FALSE;
 
    do {
        hSc = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
        if(!hSc)
            break;
 
        hService = OpenServiceA(hSc, ServiceName, SERVICE_ALL_ACCESS);
        if(!hService)
            break;
 
        bSuccess = StartService(hService, 0, NULL);
 
    } while (FALSE);
 
    if(hSc)
        CloseServiceHandle(hSc);
 
    if(hService)
        CloseServiceHandle(hService);
 
    return bSuccess;
}
 
BOOL _CreateService(LPCSTR ServiceName, LPCSTR DisplayName, LPCSTR SysPath, BOOL bKernelService, BOOL bAutoStart, LPCSTR LoadOrder)
{
    SC_HANDLE hSc = NULL, hService = NULL;
    BOOL bSuccess = FALSE;
 
    do {
        hSc = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
        if(!hSc)
            break;
 
        hService = CreateServiceA(hSc, ServiceName, DisplayName, SERVICE_ALL_ACCESS,
            bKernelService ? SERVICE_KERNEL_DRIVER : SERVICE_WIN32_OWN_PROCESS,
            bAutoStart ? (bKernelService ? SERVICE_SYSTEM_START : SERVICE_AUTO_START) : SERVICE_DEMAND_START,
            SERVICE_ERROR_IGNORE,
            SysPath, LoadOrder, NULL, NULL, NULL, NULL);
 
        if(!hService)
            break;
 
        bSuccess = TRUE;
 
    } while (FALSE);
 
    if(hSc)
        CloseServiceHandle(hSc);
 
    if(hService)
        CloseServiceHandle(hService);
 
    return bSuccess;
}
 
BOOL _DeleteService(LPCSTR ServiceName)
{
    SC_HANDLE hSc = NULL, hService = NULL;
    BOOL bSuccess = FALSE;
 
    do {
        hSc = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
        if(!hSc)
            break;
 
        hService = OpenServiceA(hSc, ServiceName, SERVICE_ALL_ACCESS);
        if(!hService)
            break;
 
        bSuccess = DeleteService(hService);
 
    } while (FALSE);
 
    if(hSc)
        CloseServiceHandle(hSc);
 
    if(hService)
        CloseServiceHandle(hService);
 
    return bSuccess;
}
 
BOOL _StopService(LPCSTR ServiceName)
{
    SC_HANDLE hSc = NULL, hService = NULL;
    BOOL bSuccess = FALSE;
 
    do {
        SERVICE_STATUS Status;
        int i = 5;
 
        hSc = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
        if(!hSc)
            break;
 
        hService = OpenServiceA(hSc, ServiceName, SERVICE_ALL_ACCESS);
        if(!hService)
            break;
 
        if(!ControlService(hService, SERVICE_CONTROL_STOP, &Status))
            break;
 
        if(Status.dwCurrentState == SERVICE_STOPPED)
        {
            bSuccess = TRUE;
            break;
        }
 
        while(i--)
        {
            if(!QueryServiceStatus(hService, &Status))
                break;
 
            if(Status.dwCurrentState == SERVICE_STOPPED)
            {
                bSuccess = TRUE;
                break;
            }
        }
 
    } while (FALSE);
 
    if(hSc)
        CloseServiceHandle(hSc);
 
    if(hService)
        CloseServiceHandle(hService);
 
    return bSuccess;
}
 
//////////////////////////////////////////////////////////////////////////
BOOL RegWow64;
 
LSTATUS QueryRegValue(HKEY key, LPCSTR subKey, LPCSTR name, LPBYTE value, ULONG *size, ULONG *type)
{
    HKEY hKey;
    LSTATUS Status;
    REGSAM sam = KEY_QUERY_VALUE;
 
    if(Is64BitWindows && RegWow64)
        sam |= KEY_WOW64_64KEY;
 
    Status = RegOpenKeyExA(key, subKey, 0, sam, &hKey);
    if(Status == ERROR_SUCCESS)
    {
        Status = RegQueryValueExA(hKey, name, NULL, type, value, size);
        RegCloseKey(hKey);
    }
    return Status;
}
 
LSTATUS QueryRegString(HKEY key, LPCSTR subKey, LPCSTR name, LPBYTE valueBuf, ULONG valueBufSize)
{
    DWORD type;
 
    return QueryRegValue(key, subKey, name, valueBuf, &valueBufSize, &type);
}
 
LSTATUS QueryRegDWORD(HKEY key, LPCSTR subKey, LPCSTR name, DWORD *value)
{
    DWORD size = sizeof(DWORD), type;
 
    return QueryRegValue(key, subKey, name, (LPBYTE)value, &size, &type);
}
 
LSTATUS SetRegValue(HKEY key, LPCSTR subKey, LPCSTR name, LPCBYTE value, ULONG size, ULONG type)
{
    HKEY hKey;
    LSTATUS Status;
    REGSAM sam = KEY_ALL_ACCESS;
 
    if(Is64BitWindows && RegWow64)
        sam |= KEY_WOW64_64KEY;
 
    Status = RegOpenKeyExA(key, subKey, 0, sam, &hKey);
    if(Status == ERROR_SUCCESS)
    {
        Status = RegSetValueExA(hKey, name, 0, type, value, size);
        RegCloseKey(hKey);
    }
    return Status;
}
 
LSTATUS SetRegString(HKEY key, LPCSTR subKey, LPCSTR name, LPCSTR value)
{
    return SetRegValue(key, subKey, name, (LPCBYTE)value, strlen(value) + 1, REG_SZ);
}
 
LSTATUS SetRegMultiString1(HKEY key, LPCSTR subKey, LPCSTR name, LPCSTR value)
{
    LSTATUS Status;
    int bufSize = strlen(value) + 2;
    char *buf;
 
    buf = malloc(bufSize);
    if(!buf)
        return S_FALSE;
    memset(buf, 0, bufSize);
 
    strcpy(buf, value);
    Status = SetRegValue(key, subKey, name, (LPCBYTE)buf, bufSize, REG_MULTI_SZ);
    free(buf);
 
    return Status;
}
 
LSTATUS SetRegDWORD(HKEY key, LPCSTR subKey, LPCSTR name, DWORD value)
{
    return SetRegValue(key, subKey, name, (LPCBYTE)&value, sizeof(DWORD), REG_DWORD);
}
 
LSTATUS AppendRegMultiString(HKEY key, LPCSTR subKey, LPCSTR name, LPCSTR append)
{
    HKEY hKey;
    LSTATUS Status;
    REGSAM sam = KEY_ALL_ACCESS;
 
    if(Is64BitWindows && RegWow64)
        sam |= KEY_WOW64_64KEY;
 
    Status = RegOpenKeyExA(key, subKey, 0, sam, &hKey);
    if(Status == ERROR_SUCCESS)
    {
        DWORD bufferIncrement = 4096, bufferSize, type, isExist = FALSE;
        LPBYTE buffer;
        PCHAR src, dst;
 
        bufferSize = bufferIncrement;
        buffer = malloc(bufferSize);
        if(!buffer)
            return S_FALSE;
 
        Status = RegQueryValueExA(hKey, name, NULL, &type, buffer, &bufferSize);
        while(Status == ERROR_MORE_DATA)
        {
            bufferSize += bufferIncrement;
            buffer = realloc(buffer, bufferSize);
            if(!buffer)
                return S_FALSE;
 
            Status = RegQueryValueExA(hKey, name, NULL, &type, buffer, &bufferSize);
        }
 
        src = buffer;
        while(*src)
        {
            if(!strcmp(src, append))
            {
                isExist = TRUE;
                break;
            }
            src += strlen(src) + 1;
        }
 
        if(!isExist)
        {
            int appendLen = strlen(append);
            LPBYTE newBuffer = malloc(bufferSize + appendLen + 1);
 
            Status = S_FALSE;
            if(newBuffer)
            {
                src = buffer;
                dst = (PCHAR)newBuffer;
 
                while(*src)
                {
                    int len = strlen(src) + 1;
 
                    strcpy(dst, src);
                    src += len;
                    dst += len;
                }
                strcpy(dst, append);
                dst += appendLen + 1;
                *dst = 0;
 
                Status = RegSetValueExA(hKey, name, 0, REG_MULTI_SZ, newBuffer, bufferSize + appendLen + 1);
                free(newBuffer);
            }
        }
 
        free(buffer);
        RegCloseKey(hKey);
    }
    return Status;
}
 
LSTATUS CreateRegKey(HKEY key, LPCSTR subKey)
{
    HKEY hKey;
    LSTATUS Status;
    REGSAM sam = KEY_ALL_ACCESS;
 
    if(Is64BitWindows && RegWow64)
        sam |= KEY_WOW64_64KEY;
 
    Status = RegCreateKeyExA(key, subKey, 0, NULL, 0, sam, NULL, &hKey, NULL);
    if(Status == ERROR_SUCCESS)
    {
        RegCloseKey(hKey);
    }
    return Status;
}
 
LSTATUS DeleteRegKey(HKEY key, LPCSTR subKey, LPCSTR name)
{
    HKEY hKey;
    LSTATUS Status;
    REGSAM sam = KEY_ALL_ACCESS;
 
    if(Is64BitWindows && RegWow64)
        sam |= KEY_WOW64_64KEY;
 
    Status = RegOpenKeyExA(key, subKey, 0, sam, &hKey);
    if(Status == ERROR_SUCCESS)
    {
        Status = RegDeleteKeyA(hKey, name);
        RegCloseKey(hKey);
    }
    return Status;
}
 
LSTATUS DeleteRegValue(HKEY key, LPCSTR subKey, LPCSTR name)
{
    HKEY hKey;
    LSTATUS Status;
    REGSAM sam = KEY_ALL_ACCESS;
 
    if(Is64BitWindows && RegWow64)
        sam |= KEY_WOW64_64KEY;
 
    Status = RegOpenKeyExA(key, subKey, 0, sam, &hKey);
    if(Status == ERROR_SUCCESS)
    {
        Status = RegDeleteValueA(hKey, name);
        RegCloseKey(hKey);
    }
    return Status;
}
 
//////////////////////////////////////////////////////////////////////////
 
BOOL InstallNdisFilter(LPCSTR serviceName, LPCSTR serviceDesc, LPCSTR sysPath, LPCSTR netCfgInstanceId)
{
    LPCSTR sysFile;
    PVOID OldRedir;
    CHAR Path[256];
    BOOL bRet;
 
    //復(fù)制驅(qū)動程序文件
    ShutdownWow64Redir(&OldRedir);
    sysFile = strrchr(sysPath, '\\');
    if(!sysFile)
        sysFile = sysPath;
    ExpandEnvironmentStrings("%systemroot%\\system32\\drivers\\", Path, sizeof(Path));
    strcat(Path, sysFile);
    bRet = CopyFile(sysPath, Path, FALSE);
    RevertWow64Redir(&OldRedir);
    if(!bRet)
    {
        printf("Copy driver file %s failed\n", sysFile);
        return FALSE;
    }
 
    //創(chuàng)建驅(qū)動服務(wù)
    sprintf(Path, "\\SystemRoot\\System32\\drivers\\%s", sysFile);
    bRet = _CreateService(serviceName, serviceDesc, Path, TRUE, TRUE, "NDIS");
    if(!bRet)
    {
        printf("Create service %s failed\n", serviceName);
        return FALSE;
    }
 
    //NDIS Version
    sprintf(Path, "SYSTEM\\CurrentControlSet\\services\\%s", serviceName);
    SetRegDWORD(HKEY_LOCAL_MACHINE, Path, "NdisMajorVersion", 6);
    SetRegDWORD(HKEY_LOCAL_MACHINE, Path, "NdisMinorVersion", 0);
 
    //INF Common.Params.reg
    sprintf(Path, "SYSTEM\\CurrentControlSet\\services\\%s\\FilterAdapterParams", serviceName);
    CreateRegKey(HKEY_LOCAL_MACHINE, Path);
    sprintf(Path, "SYSTEM\\CurrentControlSet\\services\\%s\\FilterAdapterParams\\AdapterParam", serviceName);
    CreateRegKey(HKEY_LOCAL_MACHINE, Path);
    SetRegString(HKEY_LOCAL_MACHINE, Path, "ParamDesc", "Adapterparam for lwf");
    SetRegString(HKEY_LOCAL_MACHINE, Path, "type", "int");
    SetRegString(HKEY_LOCAL_MACHINE, Path, "default", "10");
 
    sprintf(Path, "SYSTEM\\CurrentControlSet\\services\\%s\\FilterDriverParams", serviceName);
    CreateRegKey(HKEY_LOCAL_MACHINE, Path);
    sprintf(Path, "SYSTEM\\CurrentControlSet\\services\\%s\\FilterDriverParams\\DriverParam", serviceName);
    CreateRegKey(HKEY_LOCAL_MACHINE, Path);
    SetRegString(HKEY_LOCAL_MACHINE, Path, "ParamDesc", "Driverparam for lwf");
    SetRegString(HKEY_LOCAL_MACHINE, Path, "type", "int");
    SetRegString(HKEY_LOCAL_MACHINE, Path, "default", "5");
 
    sprintf(Path, "SYSTEM\\CurrentControlSet\\services\\%s\\Parameters", serviceName);
    CreateRegKey(HKEY_LOCAL_MACHINE, Path);
    SetRegString(HKEY_LOCAL_MACHINE, Path, "DriverParam", "5");
    SetRegDWORD(HKEY_LOCAL_MACHINE, Path, "DefaultFilterSettings", 1);
 
    //Binding
    sprintf(Path, "SYSTEM\\CurrentControlSet\\services\\%s\\Parameters\\Adapters", serviceName);
    CreateRegKey(HKEY_LOCAL_MACHINE, Path);
    sprintf(Path, "SYSTEM\\CurrentControlSet\\services\\%s\\Parameters\\NdisAdapters", serviceName);
    CreateRegKey(HKEY_LOCAL_MACHINE, Path);
 
    //INF Ndi part, ignore: InfPath InfSection InstallTimeStamp LocDescription
    sprintf(Path, "SYSTEM\\CurrentControlSet\\Control\\Network\\{4d36e974-e325-11ce-bfc1-08002be10318}\\%s", netCfgInstanceId);
    CreateRegKey(HKEY_LOCAL_MACHINE, Path);
    SetRegDWORD(HKEY_LOCAL_MACHINE, Path, "Characteristics", NCF_LW_FILTER);
    SetRegString(HKEY_LOCAL_MACHINE, Path, "ComponentId", serviceName);
    SetRegString(HKEY_LOCAL_MACHINE, Path, "Description", serviceDesc);
 
    //INF Ndi part, ignore: TimeStamp
    sprintf(Path, "SYSTEM\\CurrentControlSet\\Control\\Network\\{4d36e974-e325-11ce-bfc1-08002be10318}\\%s\\Ndi", netCfgInstanceId);
    CreateRegKey(HKEY_LOCAL_MACHINE, Path);
    SetRegMultiString1(HKEY_LOCAL_MACHINE, Path, "CoServices", serviceName);
    SetRegString(HKEY_LOCAL_MACHINE, Path, "FilterClass", "compression");
    SetRegDWORD(HKEY_LOCAL_MACHINE, Path, "FilterRunType", 1);
    SetRegDWORD(HKEY_LOCAL_MACHINE, Path, "FilterType", 2);
    SetRegString(HKEY_LOCAL_MACHINE, Path, "HelpText", serviceDesc);
    SetRegMultiString1(HKEY_LOCAL_MACHINE, Path, "Services", serviceName);
 
    //INF Ndi Part
    sprintf(Path, "SYSTEM\\CurrentControlSet\\Control\\Network\\{4d36e974-e325-11ce-bfc1-08002be10318}\\%s\\Ndi\\Interfaces", netCfgInstanceId);
    CreateRegKey(HKEY_LOCAL_MACHINE, Path);
    SetRegString(HKEY_LOCAL_MACHINE, Path, "FilterMediaTypes", "ethernet");
    SetRegString(HKEY_LOCAL_MACHINE, Path, "LowerRange", "nolower");
    SetRegString(HKEY_LOCAL_MACHINE, Path, "UpperRange", "noupper");
 
    return TRUE;
}
 
void RestartDevice(LPCSTR PnpInstanceId)
{
    HDEVINFO hDevInfo = NULL;
 
    do {
        DWORD Index;
 
        hDevInfo = SetupDiGetClassDevs(NULL,NULL,NULL, DIGCF_PRESENT | DIGCF_ALLCLASSES);
        if(!hDevInfo)
            break;
 
        Index = 0;
        while(1)
        {
            SP_DEVINFO_DATA sdd = {sizeof(sdd)};
            char instanceId[256];
 
            if(!SetupDiEnumDeviceInfo(hDevInfo, Index++, &sdd))
                break;
 
            if(SetupDiGetDeviceInstanceId(hDevInfo, &sdd, instanceId, sizeof(instanceId), NULL))
            {
                if(!strcmp(instanceId, PnpInstanceId))
                {
                    SP_PROPCHANGE_PARAMS params = {sizeof(SP_CLASSINSTALL_HEADER)};
 
                    params.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
                    params.Scope = DICS_FLAG_CONFIGSPECIFIC;
                    params.HwProfile = 0;
 
                    params.StateChange = DICS_DISABLE;
                    SetupDiSetClassInstallParams(hDevInfo, &sdd, &params.ClassInstallHeader, sizeof(params));
                    SetupDiChangeState(hDevInfo, &sdd);
 
                    params.StateChange = DICS_ENABLE;
                    SetupDiSetClassInstallParams(hDevInfo, &sdd, &params.ClassInstallHeader, sizeof(params));
                    SetupDiChangeState(hDevInfo, &sdd);
 
                    break;
                }
            }
        }
 
    } while (0);
 
    if(hDevInfo)
        SetupDiDestroyDeviceInfoList(hDevInfo);
}
 
BOOL InstallNdisFilterBind(LPCSTR filterServiceName, LPCSTR filterNetCfgInstanceId)
{
    LPCSTR enumPath;
    HKEY hKey;
    DWORD sam = KEY_READ, index = 0;
    LSTATUS Status;
 
    //枚舉所有 ethernet 網(wǎng)卡闲延,并添加綁定豹缀。用 GetIfTable2 也可,我這里使用注冊表遍歷慨代。
    enumPath = "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}";
    Status = RegOpenKeyExA(HKEY_LOCAL_MACHINE, enumPath, 0, sam, &hKey);
    if(Status != S_OK)
        return FALSE;
 
    while(1)
    {
        CHAR name[256], path[256], netCfgInstanceId[128];
        DWORD nameSize = sizeof(name);
        DWORD ifType, ifChar, ifLuid;
 
        if(RegEnumKeyExA(hKey, index++, name, &nameSize, NULL, NULL, NULL, NULL) != S_OK)
            break;
 
        sprintf(path, "%s\\%s", enumPath, name);
 
        if(QueryRegString(HKEY_LOCAL_MACHINE, path, "NetCfgInstanceId", netCfgInstanceId, sizeof(netCfgInstanceId)) != S_OK)
            continue;
 
        if(QueryRegDWORD(HKEY_LOCAL_MACHINE, path, "*IfType", &ifType) != S_OK)
            continue;
 
        if(QueryRegDWORD(HKEY_LOCAL_MACHINE, path, "NetLuidIndex", &ifLuid) != S_OK)
            continue;
 
        if(QueryRegDWORD(HKEY_LOCAL_MACHINE, path, "Characteristics", &ifChar) != S_OK)
            continue;
 
        if( (ifType == MIB_IF_TYPE_ETHERNET || ifType == IF_TYPE_IEEE80211) &&  //是以太網(wǎng)或WiFi適配器
            !(ifChar & NCF_VIRTUAL) )                                           //不是虛擬適配器
        {
            //綁定到 NdisFilter
            CHAR bindItem[256], pnpInstanceId[256];
            NET_LUID Luid;
            GUID Guid;
 
            sprintf(bindItem, "%s-%s-0000", netCfgInstanceId, filterNetCfgInstanceId);
            printf("Bind to %s\n", filterNetCfgInstanceId);
 
            sprintf(path, "%s\\%s\\Linkage", enumPath, name);
            printf("Append FilterList %s\n", bindItem);
            AppendRegMultiString(HKEY_LOCAL_MACHINE, path, "FilterList", bindItem);
 
            //Binding
            sprintf(path, "SYSTEM\\CurrentControlSet\\services\\%s\\Parameters\\Adapters\\%s", filterServiceName, netCfgInstanceId);
            CreateRegKey(HKEY_LOCAL_MACHINE, path);
            sprintf(path, "SYSTEM\\CurrentControlSet\\services\\%s\\Parameters\\Adapters\\%s\\%s-0000", filterServiceName, netCfgInstanceId, filterNetCfgInstanceId);
            CreateRegKey(HKEY_LOCAL_MACHINE, path);
            sprintf(path, "SYSTEM\\CurrentControlSet\\services\\%s\\Parameters\\NdisAdapters\\%s", filterServiceName, netCfgInstanceId);
            CreateRegKey(HKEY_LOCAL_MACHINE, path);
            SetRegString(HKEY_LOCAL_MACHINE, path, "AdapterParam", "10");
 
            memset(&Guid, 0, sizeof(Guid));
            Luid.Info.Reserved = 0;
            Luid.Info.IfType = ifType;
            Luid.Info.NetLuidIndex = ifLuid;
            ConvertInterfaceLuidToGuid(&Luid, &Guid);
            SetRegValue(HKEY_LOCAL_MACHINE, path, "InterfaceGuid", (LPCBYTE)&Guid, sizeof(Guid), REG_BINARY);
 
            //禁用啟用網(wǎng)卡
            sprintf(path, "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection", netCfgInstanceId);
            QueryRegString(HKEY_LOCAL_MACHINE, path, "PnPInstanceId", pnpInstanceId, sizeof(pnpInstanceId));
            printf("Restart %s pnpId %s\n", netCfgInstanceId, pnpInstanceId);
            RestartDevice(pnpInstanceId);
        }
    }
 
    RegCloseKey(hKey);
    return TRUE;
}
 
int main(int argc, char *argv[])
{
    char *SysPath;
    char *NetCfgInstanceId;
 
    //獲取操作系統(tǒng)版本
    GetOsVer();
 
    //設(shè)定過濾驅(qū)動程序路徑和實例GUID
    if(Is64BitWindows)
        SysPath = "tcpmasq64.sys";
    else
        SysPath = "tcpmasq32.sys";
    NetCfgInstanceId = "{91E009E2-A9A3-42B7-9E22-3A1D389D7D4D}";
 
    //安裝過濾驅(qū)動服務(wù)
    printf("Install NDIS Filter\n");
    InstallNdisFilter("tcpmasq", "TcpMasq NT6 LWF Driver", SysPath, NetCfgInstanceId);
 
    //添加綁定的網(wǎng)卡
    printf("NDIS Filter Bind\n");
    InstallNdisFilterBind("tcpmasq", NetCfgInstanceId);
 
    //BUG: 在控制面板重新禁用啟用網(wǎng)卡邢笙,會丟掉 Bind
    //可能是由于 HKLM\SYSTEM\CurrentControlSet\Control\Network\Config 數(shù)據(jù)里面沒有剛注冊的 NDIS Filter
    //Config 讀寫位于 netcfgx.dll
    //關(guān)鍵字 WRITING CONFIG BLOB 日志寫入 C:\Windows\inf\setupapi.dev.log
    //FIXME
 
    return 0;
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市侍匙,隨后出現(xiàn)的幾起案子氮惯,更是在濱河造成了極大的恐慌叮雳,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件妇汗,死亡現(xiàn)場離奇詭異帘不,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)杨箭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進(jìn)店門寞焙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人互婿,你說我怎么就攤上這事捣郊。” “怎么了慈参?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵呛牲,是天一觀的道長。 經(jīng)常有香客問我驮配,道長娘扩,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任壮锻,我火速辦了婚禮琐旁,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘猜绣。我一直安慰自己旋膳,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布途事。 她就那樣靜靜地躺著,像睡著了一般擅羞。 火紅的嫁衣襯著肌膚如雪尸变。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天减俏,我揣著相機(jī)與錄音召烂,去河邊找鬼。 笑死娃承,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播钻洒,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼傻昙,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了梳猪?” 一聲冷哼從身側(cè)響起麻削,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后呛哟,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體叠荠,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年扫责,在試婚紗的時候發(fā)現(xiàn)自己被綠了榛鼎。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡鳖孤,死狀恐怖者娱,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情淌铐,我是刑警寧澤肺然,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站腿准,受9級特大地震影響际起,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜吐葱,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一街望、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧弟跑,春花似錦灾前、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至饲嗽,卻和暖如春炭玫,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背貌虾。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工吞加, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人尽狠。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓衔憨,卻偏偏與公主長得像,于是被迫代替她去往敵國和親袄膏。 傳聞我的和親對象是個殘疾皇子践图,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,490評論 2 348

推薦閱讀更多精彩內(nèi)容