目前遇到了这个问题,我现在监听网卡上的数据,而且是只监听Tcp的包,前面的我已经做到了,用的是winpcap,  目的:我想只获取与浏览器(IE, FIREFOX, GOOGLE, OPERA....)相关的包,并且想精确到只接收哪个浏览器的包,因为用户需要这个功能。我有几个想法。1. 是我最初的想法
    因为我的机器请求了一个地址后,他会告诉对方将开哪个端口接收数据,对方接到请求后会发一部分数据过来并且指明是发到哪个端口的,我这个时候通过这个端口去枚举计算机里面的所有进程打开的端口,然后一一对比端口,最后我可以确定这个端口是给哪个进程在使用。那么我就可以确定这个进程是不是浏览器进程。(这个方法我已经做到了,但是在用户下载东西的时候,我的程序会不停的去枚举这些数据)结果,几分钟2G的内存都快没有了。如果有必要,我可以提供枚举端口的代码。2. 钩子
    当然我才接触VC刚2个月(还有4天就2个月了),对这个不是很清楚,我不知道想法是否成立,我想钩住某个东西,在系统开一个端口的时候我确定一下这个端口是哪个进程开的(如果这个时候不用枚举获得那就太好了,我不知道行不行),如果是与浏览器相关的我把它放到一个队列里面,如果有tcp数据过来的时候,我根据它的端口与队列里面的端口比对一下,自然就知道数据发往哪个浏览器了。3. 还是钩子
   我的想法是这样的(不知道是否可行),用一个钩子锁定一个.exe,例如ieex...exe(IE的进程名称), 如果用户有创建一个IE实例的时候,我得到它的句柄,然后再钩一下,也就是他每次开一个端口的时候,这个时候我获取它所开的端口,其余的操作与2差不多了,也就是比对,然后确定数据发送到的浏览器。这三个方法比起来,1是最简单的,也是最容易想的,但是使用效果,和效率不行,我觉得不可取,而且现在那个耗内存的原因在哪我也不知道(不下东西的时候很正常),
当然如果有其他的方法获取到TCP包对应的进程就更好了。
目前就三个想法。我相信好多人也希望知道解答方法。所以请高手们帮帮忙。如果我的想法有什么错误,请帮忙更正一下。

解决方案 »

  1.   

    现在监控都是根据协议,端口等来的,要么就是HTTP协议等,一般是不会区分浏览器的,只要是HTTP的都监控,对于HTTP可以根据端口,包格式等来区分
      

  2.   

    对不起,我的帖子好像没有打广告吧!只是这问题,目前也有好几兄弟提过,而我前面也提过好几次也没见冒泡过,所以希望置顶的。如果您觉得哪里有广告成分,请帮我去掉。谢谢!
    可能是得说一下需求,大家应该听说过“影音***”(为避免广告嫌疑,后面不写了),他主要获取当前用户得到的媒体地址,用户可以下载,而我现在大概的实现了他的功能,即获取用户当前所播放媒体的地址,并且知道了当前媒体的格式,那么用户可以过滤掉自己不想要的格式,但是用户还需要过滤掉例如:IE(希望版主不要认为我在为IE做广告),或者Firefox...,我目前就是要做这个功能,所以才问了上面那些问题!由于周末没法上网,没发回复大家,请谅解!
      

  3.   

    试着用用pcausa公司的开发包,不过好像要米米买哦,他们会给你文档的.
      

  4.   

    shell command:
    netstat -an
      

  5.   

    几分钟2G的内存都快没有了
    ----------------------
    估计你那里内存泄露了,也就是new出来没有释放,调查一下吧
      

  6.   

    回楼上的,没有看到有new的地方和malloc的地方,总共也就200行代码不到!
      

  7.   


    CAdvancement::CAdvancement(void) : pAllocateAndGetTcpExtableFromStack(NULL)
    {
    //TCP 端口状态
    char TcpState[][32] = 
    {
    TEXT("???"),
    TEXT("CLOSED"),
    TEXT("LISTENING"),
    TEXT("SYN_SENT"),
    TEXT("SYN_RCVD"),
    TEXT("ESTABLISHED"),
    TEXT("FIN_WAIT1"),
    TEXT("FIN_WAIT2"),
    TEXT("CLOSE_WAIT"),
    TEXT("CLOSING"),
    TEXT("LAST_ACK"),
    TEXT("TIME_WAIT"),
    TEXT("DELETE_TCB")
    }; // 初始化一些信息
    WSADATA WSAData;
    // 开始Socket服务
    if( WSAStartup(MAKEWORD(1, 1), &WSAData ))
    {
    m_error = "WSAStartup error!";
    return;
    } // 加载所需DLL
    HMODULE m_hIpDLL = LoadLibrary( "iphlpapi.dll");
    if (!m_hIpDLL)
    {
    m_error = "Load iphlpapi.dll error!";
    return;
    }
    pAllocateAndGetTcpExtableFromStack =
    (_AllocateAndGetTcpExtableFromStack)GetProcAddress(m_hIpDLL, "AllocateAndGetTcpExTableFromStack");
    }CAdvancement::~CAdvancement(void)
    {
    ::FreeLibrary(m_hIpDLL);
    // 结束Socket服务
    ::WSACleanup();
    }// 由PID获得进程文件名
    CString CAdvancement::ProcessPidToName(DWORD ProcessPId)
    {
    // CreateToolhelp32Snapshot 遍历进程快照
    HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
    PROCESSENTRY32 processEntry = { 0 };
    processEntry.dwSize = sizeof(PROCESSENTRY32);  CString szProcessName;
    char ProcessName[256];
    ZeroMemory(ProcessName, 256);
    lstrcpy(ProcessName, "Idle");
    if (hProcessSnap == INVALID_HANDLE_VALUE) 
    {
    CloseHandle(hProcessSnap);
    szProcessName = ProcessName;
    return szProcessName;
    }
    BOOL bRet=Process32First(hProcessSnap, &processEntry); while(Process32Next(hProcessSnap, &processEntry)) 
    {
    if (processEntry.th32ProcessID == ProcessPId)
    {
       MODULEENTRY32 me32 = {0}; 
       me32.dwSize = sizeof(MODULEENTRY32); 
       HANDLE hModuleSnap = CreateToolhelp32Snapshot
    (TH32CS_SNAPMODULE, processEntry.th32ProcessID); 
       
       Module32First(hModuleSnap, &me32); // 获得进程全路径
       lstrcpy(ProcessName, me32.szExePath);
       CloseHandle(hProcessSnap);
       szProcessName = ProcessName;
       return szProcessName; 
    }
    }  CloseHandle(hProcessSnap);
    return szProcessName;
    }// 显示我们要的信息
    CString CAdvancement::ExportPort(u_short portId)
    {
    CString browserInfo = "";
    vector<u_short> vecPortList;
    DWORD i;
    PMIB_TCPEXTABLE TCPExTable;
    if(pAllocateAndGetTcpExtableFromStack(&TCPExTable, TRUE, GetProcessHeap(), 2, 2))
    {
    m_error = "AllocateAndGetTcpExTableFromStack Error!";
    return browserInfo;
    } // 我们只监视TCP
    for( i = 0; i < TCPExTable->dwNumEntries; i++ )
    {
    // 找到媒体多对应的端口
    if (htons((WORD)TCPExTable->table[i].dwLocalPort) == portId)
    break;
    }

    if (i != TCPExTable->dwNumEntries)
    {
    browserInfo = GetExeName(ProcessPidToName(TCPExTable->table[i].dwProcessPID));
    }
    return browserInfo;
    }
    CString CAdvancement::GetExeName(CString exePath)
    {
    int nLastLinePos = exePath.ReverseFind('\\');
    if (nLastLinePos != -1)
    return exePath.Mid(nLastLinePos + 1).MakeLower();
    else
    return "";
    }
      

  8.   

    上面是类,
    bool CMedia::InBrowserFilter(u_int16_t port)
    {
    CAdvancement advancement;
    CString strPosserExt = advancement.ExportPort(port); // AfxMessageBox(strPosserExt);
    std::vector<CString>::iterator theIterator; theIterator = find(m_VecBrowserFilter.begin(), m_VecBrowserFilter.end(), strPosserExt); if (theIterator != m_VecBrowserFilter.end())
    return true;
    else
    return false;
    }这里是调用,请帮忙看看!
      

  9.   

    用这个函数吧
    GetTcpTablemsdn的例子#include <winsock2.h>
    #include <ws2tcpip.h>
    #include <iphlpapi.h>
    #include <stdio.h>#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
    #define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
    /* Note: could also use malloc() and free() */int main()
    {    // Declare and initialize variables
        PMIB_TCPTABLE pTcpTable;
        DWORD dwSize = 0;
        DWORD dwRetVal = 0;    char szLocalAddr[128];
        char szRemoteAddr[128];    struct in_addr IpAddr;    int i;    pTcpTable = (MIB_TCPTABLE *) MALLOC(sizeof (MIB_TCPTABLE));
        if (pTcpTable == NULL) {
            printf("Error allocating memory\n");
            exit(1);
        }    dwSize = sizeof (MIB_TCPTABLE);
    // Make an initial call to GetTcpTable to
    // get the necessary size into the dwSize variable
        if ((dwRetVal = GetTcpTable(pTcpTable, &dwSize, TRUE)) ==
            ERROR_INSUFFICIENT_BUFFER) {
            FREE(pTcpTable);
            pTcpTable = (MIB_TCPTABLE *) MALLOC(dwSize);
            if (pTcpTable == NULL) {
                printf("Error allocating memory\n");
                exit(1);
            }
        }
    // Make a second call to GetTcpTable to get
    // the actual data we require
        if ((dwRetVal = GetTcpTable(pTcpTable, &dwSize, TRUE)) == NO_ERROR) {
            printf("\tNumber of entries: %d\n", (int) pTcpTable->dwNumEntries);
            for (i = 0; i < (int) pTcpTable->dwNumEntries; i++) {
                IpAddr.S_un.S_addr = (u_long) pTcpTable->table[i].dwLocalAddr;
                strcpy_s(szLocalAddr, sizeof (szLocalAddr), inet_ntoa(IpAddr));
                IpAddr.S_un.S_addr = (u_long) pTcpTable->table[i].dwRemoteAddr;
                strcpy_s(szRemoteAddr, sizeof (szRemoteAddr), inet_ntoa(IpAddr));            printf("\n\tTCP[%d] State: %ld - ", i,
                       pTcpTable->table[i].dwState);
                switch (pTcpTable->table[i].dwState) {
                case MIB_TCP_STATE_CLOSED:
                    printf("CLOSED\n");
                    break;
                case MIB_TCP_STATE_LISTEN:
                    printf("LISTEN\n");
                    break;
                case MIB_TCP_STATE_SYN_SENT:
                    printf("SYN-SENT\n");
                    break;
                case MIB_TCP_STATE_SYN_RCVD:
                    printf("SYN-RECEIVED\n");
                    break;
                case MIB_TCP_STATE_ESTAB:
                    printf("ESTABLISHED\n");
                    break;
                case MIB_TCP_STATE_FIN_WAIT1:
                    printf("FIN-WAIT-1\n");
                    break;
                case MIB_TCP_STATE_FIN_WAIT2:
                    printf("FIN-WAIT-2 \n");
                    break;
                case MIB_TCP_STATE_CLOSE_WAIT:
                    printf("CLOSE-WAIT\n");
                    break;
                case MIB_TCP_STATE_CLOSING:
                    printf("CLOSING\n");
                    break;
                case MIB_TCP_STATE_LAST_ACK:
                    printf("LAST-ACK\n");
                    break;
                case MIB_TCP_STATE_TIME_WAIT:
                    printf("TIME-WAIT\n");
                    break;
                case MIB_TCP_STATE_DELETE_TCB:
                    printf("DELETE-TCB\n");
                    break;
                default:
                    printf("UNKNOWN dwState value\n");
                    break;
                }
                printf("\tTCP[%d] Local Addr: %s\n", i, szLocalAddr);
                printf("\tTCP[%d] Local Port: %d\n", i,
                       ntohs(pTcpTable->table[i].dwLocalPort));
                printf("\tTCP[%d] Remote Addr: %s\n", i, szRemoteAddr);
                printf("\tTCP[%d] Remote Port: %d\n", i,
                       ntohs(pTcpTable->table[i].dwRemotePort));
            }
        } else {
            printf("\tGetTcpTable failed with %d\n", dwRetVal);
            FREE(pTcpTable);
            exit(1);
        }
    }
      

  10.   

    做某个进程的钩子.勾住send recv等 socket API这样区分ie firefox之类的就很方便了.
      

  11.   

    回楼上,这个问题我也想过,但是好像没有找到能运行这样的钩子实例啊,如果说钩住某个进程,也说不过去,因为有些端口开了以后,可能2秒就关了(即下载一个图片的时间端口就关闭了),弱弱的问一下,钩住socket从哪知道是ie或者firefox? 我是新手,请谅解!
      

  12.   

    lz自己把问题 搞复杂了,可以用http协议过滤,user-agent里面就有信息,再说浏览器都是用http协议的