不用inf安装ndis filter驱动
2020-08-13 18:40:42 Author: bbs.pediy.com(查看原文) 阅读量:346 收藏

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

可惜发现晚了,那个连接无效了,去老v的gitee仓库转悠好几圈,没发现那个安装ndis filter的代码在哪个仓库,可能是未公开的仓库。我还去问了gitee那边回复说是gitee之前有一次升级 username/codes 这种的url仅对用户自己可见,不能公开访问了。

老v神出鬼没…联系不上…只好自己撸了一个
调试上比较简单拿着processmonitor 配合vm建一些快照,看看日志,就完事了。
然后就是撸代码。

对于 xx 项目来说,NDIS Filter 确实不好用,还是上 WFP 吧,弃坑。有个bug,先不解决了

/*
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;

    //复制驱动程序文件
    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;
    }

    //创建驱动服务
    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 网卡,并添加绑定。用 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) &&  //是以太网或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);

            //禁用启用网卡
            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;

    //获取操作系统版本
    GetOsVer();

    //设定过滤驱动程序路径和实例GUID
    if(Is64BitWindows)
        SysPath = "tcpmasq64.sys";
    else
        SysPath = "tcpmasq32.sys";
    NetCfgInstanceId = "{91E009E2-A9A3-42B7-9E22-3A1D389D7D4D}";

    //安装过滤驱动服务
    printf("Install NDIS Filter\n");
    InstallNdisFilter("tcpmasq", "TcpMasq NT6 LWF Driver", SysPath, NetCfgInstanceId);

    //添加绑定的网卡
    printf("NDIS Filter Bind\n");
    InstallNdisFilterBind("tcpmasq", NetCfgInstanceId);

    //BUG: 重新禁用启用网卡,会丢掉 Bind
    //可能是由于 HKLM\SYSTEM\CurrentControlSet\Control\Network\Config 数据里面没有刚注册的 NDIS Filter
    //Config 读写位于 netcfgx.dll
    //关键字 WRITING CONFIG BLOB 日志写入 C:\Windows\inf\setupapi.dev.log
    //FIXME 

    return 0;
}

HWS计划·2020安全精英夏令营来了!我们在华为松山湖欧洲小镇等你

最后于 1天前 被MengXP编辑 ,原因:


文章来源: https://bbs.pediy.com/thread-261416.htm
如有侵权请联系:admin#unsafe.sh