本帖最后由 VisualEleven 于 2011-01-12 15:15:13 编辑

解决方案 »

  1.   

    以下是安装LSP////////////////////////////////////////////////////////
    // InstDemo.cpp#include <Ws2spi.h>
    #include <Sporder.h> // 定义了WSCWriteProviderOrder函数#include <windows.h>
    #include <stdio.h>#pragma comment(lib, "Ws2_32.lib")
    #pragma comment(lib, "Rpcrt4.lib") // 实现了UuidCreate函数
    #pragma comment(lib, "Sporder.lib ") // 要安装的LSP的硬编码,在移除的时候还要使用它
    GUID  ProviderGuid = {0xd3c21122, 0x85e1, 0x48f3, {0x9a,0xb6,0x23,0xd9,0x0c,0x73,0x07,0xef}};
    LPWSAPROTOCOL_INFOW GetProvider(LPINT lpnTotalProtocols)
    {
    DWORD dwSize = 0;
    int nError;
    LPWSAPROTOCOL_INFOW pProtoInfo = NULL;

    // 取得需要的长度
    if(::WSCEnumProtocols(NULL, pProtoInfo, &dwSize, &nError) == SOCKET_ERROR)
    {
    if(nError != WSAENOBUFS)
    return NULL;
    }

    pProtoInfo = (LPWSAPROTOCOL_INFOW)::GlobalAlloc(GPTR, dwSize);
    *lpnTotalProtocols = ::WSCEnumProtocols(NULL, pProtoInfo, &dwSize, &nError);
    return pProtoInfo;
    }void FreeProvider(LPWSAPROTOCOL_INFOW pProtoInfo)
    {
    ::GlobalFree(pProtoInfo);
    }
    // 将LSP安装到UDP协议提供者之上
    int InstallProvider(WCHAR *wszDllPath)
    {
    WCHAR wszLSPName[] = L"TinyLSP"; // 我们的LSP的名称
    int nError = NO_ERROR; LPWSAPROTOCOL_INFOW pProtoInfo;
    int nProtocols;
    WSAPROTOCOL_INFOW UDPLayeredInfo, UDPChainInfo; // 我们要安装的UDP分层协议和协议链
    DWORD dwUdpOrigCatalogId, dwLayeredCatalogId; // 在Winsock目录中找到原来的UDP协议服务提供者,我们的LSP要安装在它之上
    // 枚举所有服务程序提供者
    pProtoInfo = GetProvider(&nProtocols);
    for(int i=0; i<nProtocols; i++)
    {
    if(pProtoInfo[i].iAddressFamily == AF_INET && pProtoInfo[i].iProtocol == IPPROTO_UDP)
    {
    memcpy(&UDPChainInfo, &pProtoInfo[i], sizeof(UDPLayeredInfo));
    // 
    UDPChainInfo.dwServiceFlags1 = UDPChainInfo.dwServiceFlags1 & ~XP1_IFS_HANDLES;  
    // 保存原来的入口ID
    dwUdpOrigCatalogId = pProtoInfo[i].dwCatalogEntryId;
    break;
    }
    }   // 首先安装分层协议,获取一个Winsock库安排的目录ID号,即dwLayeredCatalogId
    // 直接使用下层协议的WSAPROTOCOL_INFOW结构即可
    memcpy(&UDPLayeredInfo, &UDPChainInfo, sizeof(UDPLayeredInfo));
    // 修改协议名称,类型,设置PFL_HIDDEN标志
    wcscpy(UDPLayeredInfo.szProtocol, wszLSPName);
    UDPLayeredInfo.ProtocolChain.ChainLen = LAYERED_PROTOCOL; // LAYERED_PROTOCOL即0
    UDPLayeredInfo.dwProviderFlags |= PFL_HIDDEN;
    // 安装
    if(::WSCInstallProvider(&ProviderGuid, 
    wszDllPath, &UDPLayeredInfo, 1, &nError) == SOCKET_ERROR)
    return nError;
    // 重新枚举协议,获取分层协议的目录ID号
    FreeProvider(pProtoInfo);
    pProtoInfo = GetProvider(&nProtocols);
    for(i=0; i<nProtocols; i++)
    {
    if(memcmp(&pProtoInfo[i].ProviderId, &ProviderGuid, sizeof(ProviderGuid)) == 0)
    {
    dwLayeredCatalogId = pProtoInfo[i].dwCatalogEntryId;
    break;
    }
    } // 安装协议链
    // 修改协议名称,类型
    WCHAR wszChainName[WSAPROTOCOL_LEN + 1];
    swprintf(wszChainName, L"%ws over %ws", wszLSPName, UDPChainInfo.szProtocol);
    wcscpy(UDPChainInfo.szProtocol, wszChainName);
    if(UDPChainInfo.ProtocolChain.ChainLen == 1)
    {
    UDPChainInfo.ProtocolChain.ChainEntries[1] = dwUdpOrigCatalogId;
    }
    else
    {
    for(i=UDPChainInfo.ProtocolChain.ChainLen; i>0 ; i--)
    {
    UDPChainInfo.ProtocolChain.ChainEntries[i] = UDPChainInfo.ProtocolChain.ChainEntries[i-1];
    }
    }
    UDPChainInfo.ProtocolChain.ChainLen ++;
    // 将我们的分层协议置于此协议链的顶层
    UDPChainInfo.ProtocolChain.ChainEntries[0] = dwLayeredCatalogId; 
    // 获取一个Guid,安装之
    GUID ProviderChainGuid;
    if(::UuidCreate(&ProviderChainGuid) == RPC_S_OK)
    {
    if(::WSCInstallProvider(&ProviderChainGuid, 
    wszDllPath, &UDPChainInfo, 1, &nError) == SOCKET_ERROR)
    return nError;
    }
    else
    return GetLastError(); // 重新排序Winsock目录,将我们的协议链提前
    // 重新枚举安装的协议
    FreeProvider(pProtoInfo);
    pProtoInfo = GetProvider(&nProtocols); DWORD dwIds[20];
    int nIndex = 0;
    // 添加我们的协议链
    for(i=0; i<nProtocols; i++)
    {
    if((pProtoInfo[i].ProtocolChain.ChainLen > 1) &&
    (pProtoInfo[i].ProtocolChain.ChainEntries[0] == dwLayeredCatalogId))
    dwIds[nIndex++] = pProtoInfo[i].dwCatalogEntryId;
    }
    // 添加其它协议
    for(i=0; i<nProtocols; i++)
    {
    if((pProtoInfo[i].ProtocolChain.ChainLen <= 1) ||
    (pProtoInfo[i].ProtocolChain.ChainEntries[0] != dwLayeredCatalogId))
    dwIds[nIndex++] = pProtoInfo[i].dwCatalogEntryId;
    }
    // 重新排序Winsock目录
    nError = ::WSCWriteProviderOrder(dwIds, nIndex); FreeProvider(pProtoInfo);
    return nError;
    }void RemoveProvider()
    {
    LPWSAPROTOCOL_INFOW pProtoInfo;
    int nProtocols;
    DWORD dwLayeredCatalogId; // 根据Guid取得分层协议的目录ID号
    pProtoInfo = GetProvider(&nProtocols);
    int nError;
    for(int i=0; i<nProtocols; i++)
    {
    if(memcmp(&ProviderGuid, &pProtoInfo[i].ProviderId, sizeof(ProviderGuid)) == 0)
    {
    dwLayeredCatalogId = pProtoInfo[i].dwCatalogEntryId;
    break;
    }
    } if(i < nProtocols)
    {
    // 移除协议链
    for(i=0; i<nProtocols; i++)
    {
    if((pProtoInfo[i].ProtocolChain.ChainLen > 1) &&
    (pProtoInfo[i].ProtocolChain.ChainEntries[0] == dwLayeredCatalogId))
    {
    ::WSCDeinstallProvider(&pProtoInfo[i].ProviderId, &nError);
    }
    }
    // 移除分层协议
    ::WSCDeinstallProvider(&ProviderGuid, &nError);
    }
    }////////////////////////////////////////////////////int binstall = 0;
    void main()
    {
    if(binstall)
    {
    if(InstallProvider(L"lsp.dll") == ERROR_SUCCESS)
    {
    printf(" Install successully \n");
    }
    else
    {
    printf(" Install failed \n");
    }
    }
    else
    RemoveProvider();
    }
      

  2.   

    以下是安装LSP////////////////////////////////////////////////////////
    // InstDemo.cpp#include <Ws2spi.h>
    #include <Sporder.h> // 定义了WSCWriteProviderOrder函数#include <windows.h>
    #include <stdio.h>#pragma comment(lib, "Ws2_32.lib")
    #pragma comment(lib, "Rpcrt4.lib") // 实现了UuidCreate函数
    #pragma comment(lib, "Sporder.lib ") // 要安装的LSP的硬编码,在移除的时候还要使用它
    GUID  ProviderGuid = {0xd3c21122, 0x85e1, 0x48f3, {0x9a,0xb6,0x23,0xd9,0x0c,0x73,0x07,0xef}};
    LPWSAPROTOCOL_INFOW GetProvider(LPINT lpnTotalProtocols)
    {
    DWORD dwSize = 0;
    int nError;
    LPWSAPROTOCOL_INFOW pProtoInfo = NULL;

    // 取得需要的长度
    if(::WSCEnumProtocols(NULL, pProtoInfo, &dwSize, &nError) == SOCKET_ERROR)
    {
    if(nError != WSAENOBUFS)
    return NULL;
    }

    pProtoInfo = (LPWSAPROTOCOL_INFOW)::GlobalAlloc(GPTR, dwSize);
    *lpnTotalProtocols = ::WSCEnumProtocols(NULL, pProtoInfo, &dwSize, &nError);
    return pProtoInfo;
    }void FreeProvider(LPWSAPROTOCOL_INFOW pProtoInfo)
    {
    ::GlobalFree(pProtoInfo);
    }
    // 将LSP安装到UDP协议提供者之上
    int InstallProvider(WCHAR *wszDllPath)
    {
    WCHAR wszLSPName[] = L"TinyLSP"; // 我们的LSP的名称
    int nError = NO_ERROR; LPWSAPROTOCOL_INFOW pProtoInfo;
    int nProtocols;
    WSAPROTOCOL_INFOW UDPLayeredInfo, UDPChainInfo; // 我们要安装的UDP分层协议和协议链
    DWORD dwUdpOrigCatalogId, dwLayeredCatalogId; // 在Winsock目录中找到原来的UDP协议服务提供者,我们的LSP要安装在它之上
    // 枚举所有服务程序提供者
    pProtoInfo = GetProvider(&nProtocols);
    for(int i=0; i<nProtocols; i++)
    {
    if(pProtoInfo[i].iAddressFamily == AF_INET && pProtoInfo[i].iProtocol == IPPROTO_UDP)
    {
    memcpy(&UDPChainInfo, &pProtoInfo[i], sizeof(UDPLayeredInfo));
    // 
    UDPChainInfo.dwServiceFlags1 = UDPChainInfo.dwServiceFlags1 & ~XP1_IFS_HANDLES;  
    // 保存原来的入口ID
    dwUdpOrigCatalogId = pProtoInfo[i].dwCatalogEntryId;
    break;
    }
    }   // 首先安装分层协议,获取一个Winsock库安排的目录ID号,即dwLayeredCatalogId
    // 直接使用下层协议的WSAPROTOCOL_INFOW结构即可
    memcpy(&UDPLayeredInfo, &UDPChainInfo, sizeof(UDPLayeredInfo));
    // 修改协议名称,类型,设置PFL_HIDDEN标志
    wcscpy(UDPLayeredInfo.szProtocol, wszLSPName);
    UDPLayeredInfo.ProtocolChain.ChainLen = LAYERED_PROTOCOL; // LAYERED_PROTOCOL即0
    UDPLayeredInfo.dwProviderFlags |= PFL_HIDDEN;
    // 安装
    if(::WSCInstallProvider(&ProviderGuid, 
    wszDllPath, &UDPLayeredInfo, 1, &nError) == SOCKET_ERROR)
    return nError;
    // 重新枚举协议,获取分层协议的目录ID号
    FreeProvider(pProtoInfo);
    pProtoInfo = GetProvider(&nProtocols);
    for(i=0; i<nProtocols; i++)
    {
    if(memcmp(&pProtoInfo[i].ProviderId, &ProviderGuid, sizeof(ProviderGuid)) == 0)
    {
    dwLayeredCatalogId = pProtoInfo[i].dwCatalogEntryId;
    break;
    }
    } // 安装协议链
    // 修改协议名称,类型
    WCHAR wszChainName[WSAPROTOCOL_LEN + 1];
    swprintf(wszChainName, L"%ws over %ws", wszLSPName, UDPChainInfo.szProtocol);
    wcscpy(UDPChainInfo.szProtocol, wszChainName);
    if(UDPChainInfo.ProtocolChain.ChainLen == 1)
    {
    UDPChainInfo.ProtocolChain.ChainEntries[1] = dwUdpOrigCatalogId;
    }
    else
    {
    for(i=UDPChainInfo.ProtocolChain.ChainLen; i>0 ; i--)
    {
    UDPChainInfo.ProtocolChain.ChainEntries[i] = UDPChainInfo.ProtocolChain.ChainEntries[i-1];
    }
    }
    UDPChainInfo.ProtocolChain.ChainLen ++;
    // 将我们的分层协议置于此协议链的顶层
    UDPChainInfo.ProtocolChain.ChainEntries[0] = dwLayeredCatalogId; 
    // 获取一个Guid,安装之
    GUID ProviderChainGuid;
    if(::UuidCreate(&ProviderChainGuid) == RPC_S_OK)
    {
    if(::WSCInstallProvider(&ProviderChainGuid, 
    wszDllPath, &UDPChainInfo, 1, &nError) == SOCKET_ERROR)
    return nError;
    }
    else
    return GetLastError(); // 重新排序Winsock目录,将我们的协议链提前
    // 重新枚举安装的协议
    FreeProvider(pProtoInfo);
    pProtoInfo = GetProvider(&nProtocols); DWORD dwIds[20];
    int nIndex = 0;
    // 添加我们的协议链
    for(i=0; i<nProtocols; i++)
    {
    if((pProtoInfo[i].ProtocolChain.ChainLen > 1) &&
    (pProtoInfo[i].ProtocolChain.ChainEntries[0] == dwLayeredCatalogId))
    dwIds[nIndex++] = pProtoInfo[i].dwCatalogEntryId;
    }
    // 添加其它协议
    for(i=0; i<nProtocols; i++)
    {
    if((pProtoInfo[i].ProtocolChain.ChainLen <= 1) ||
    (pProtoInfo[i].ProtocolChain.ChainEntries[0] != dwLayeredCatalogId))
    dwIds[nIndex++] = pProtoInfo[i].dwCatalogEntryId;
    }
    // 重新排序Winsock目录
    nError = ::WSCWriteProviderOrder(dwIds, nIndex); FreeProvider(pProtoInfo);
    return nError;
    }void RemoveProvider()
    {
    LPWSAPROTOCOL_INFOW pProtoInfo;
    int nProtocols;
    DWORD dwLayeredCatalogId; // 根据Guid取得分层协议的目录ID号
    pProtoInfo = GetProvider(&nProtocols);
    int nError;
    for(int i=0; i<nProtocols; i++)
    {
    if(memcmp(&ProviderGuid, &pProtoInfo[i].ProviderId, sizeof(ProviderGuid)) == 0)
    {
    dwLayeredCatalogId = pProtoInfo[i].dwCatalogEntryId;
    break;
    }
    } if(i < nProtocols)
    {
    // 移除协议链
    for(i=0; i<nProtocols; i++)
    {
    if((pProtoInfo[i].ProtocolChain.ChainLen > 1) &&
    (pProtoInfo[i].ProtocolChain.ChainEntries[0] == dwLayeredCatalogId))
    {
    ::WSCDeinstallProvider(&pProtoInfo[i].ProviderId, &nError);
    }
    }
    // 移除分层协议
    ::WSCDeinstallProvider(&ProviderGuid, &nError);
    }
    }////////////////////////////////////////////////////int binstall = 0;
    void main()
    {
    if(binstall)
    {
    if(InstallProvider(L"lsp.dll") == ERROR_SUCCESS)
    {
    printf(" Install successully \n");
    }
    else
    {
    printf(" Install failed \n");
    }
    }
    else
    RemoveProvider();
    }
      

  3.   

    没看过,楼上的,帮忙推荐一本windows 网络编程的书,谢谢鸟!
      

  4.   

    你 WSPSendTo里什么都不做拦截直接调用下一个提供者看看
      

  5.   

    试过了 不会导致任何问题 就是这几句导致部分dns失效的吧:
    SOCKADDR_IN sa = *(SOCKADDR_IN*)lpTo;
        if(sa.sin_port == htons(4567))
        {
            int    iError;
            g_NextProcTable.lpWSPShutdown(s, SD_BOTH, &iError);
            *lpErrno = WSAECONNABORTED;
     
            ODS(L" deny a sendto ");
            return SOCKET_ERROR;
        }
      

  6.   

    可能DNS解析用这个端口来监听 那这么说代码是没问题的
      

  7.   

    那假如想禁止登陆qq 就在sendto里禁了目的端口8000就行了吧?可是我试过好多端口号 随便什么端口号都会导致qq无法登陆,这是为什么呢?另外还有输入www.baidu.com是打不开的,输ip可以,搜一些东西也能显示,但是更进一层就打不开了,这是为什么呢?多谢您了!
      

  8.   

    改成了禁用目的端口8000 输出日志显示确实登录qq的时候8000端口被禁用了 qq很聪明,自动寻找8001端口还是顽强地登录了
      

  9.   


    lsp 一直我就没找个没bug的代码.
      

  10.   


    前辈您好,我在王艳平的书里还看到她把lsp装到了raw协议之上,不知道这么做有什么作用呢,另外想请教您如果想截原始数据包,我应该用什么程序去测试呢?上周试了windows自带的远程桌面连接和局域网共享文件夹还有ping程序,都没有成功截获原始数据包,希望前辈能指点一二啊!!!多谢多谢!
      

  11.   


    王艳平的书里代码第七章基本上还是没有问题的,我试过,只是个别for循环里的局部变量i没声明罢了,我也在学lsp,多多交流~