用NPCAP进行抓包
1.下载安装 npcap-1.60.exe
2. 下载 npcap-sdk-1.12
3. VC++ 工程设置中,加入头文件和lib文件的路径。 方便起见,字符集选Multi-Byte
4. 把SDK中的例程序复制粘贴变成自己的测试程序。
程序界面如下:
程序如下:抓包的程序段放在一个线程中,避免阻塞操作界面。
// CAPTest.cpp : Defines the entry point for the application. // 用NPCAP抓包 // XGZ 2022-5-13 SZ #include "stdafx.h" #include "CAPTest.h" #include "process.h" #include "time.h" #include <pcap.h> #pragma comment(lib, "Packet.lib") #pragma comment(lib, "wpcap.lib") #define MAX_LOADSTRING 100 // Global Variables: HINSTANCE hInst; // current instance TCHAR szTitle[MAX_LOADSTRING]; // The title bar text TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name // Forward declarations of functions included in this code module: ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //XGZ #define IDC_COMBOADAPT 1001 #define IDC_BUTTONSTART 1002 #define IDC_EDIT 1003 HWND hWndComboAdapt; HWND hWndButtonStart; HWND hWndEdit; pcap_t *adhandle = NULL; pcap_if_t *alldevs; pcap_if_t *d; int inum; char errbuf[PCAP_ERRBUF_SIZE]; struct pcap_pkthdr *header; const u_char *pkt_data; time_t local_tv_sec; struct tm *ltime; char timestr[16]; int res; int iStart = 0; int PRINT(TCHAR *fmt, ...); VOID ThreadProc1(PVOID pData); int OnCreate(HWND, UINT, WPARAM, LPARAM); int OnPaint(HWND, UINT, WPARAM, LPARAM); int OnSize(HWND, UINT, WPARAM, LPARAM); int OnDestroy(HWND, UINT, WPARAM, LPARAM); int OnButtonStart(HWND, UINT, WPARAM, LPARAM); int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // TODO: Place code here. MSG msg; HACCEL hAccelTable; // Initialize global strings LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadString(hInstance, IDC_CAPTEST, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance); // Perform application initialization: if (!InitInstance (hInstance, nCmdShow)) { return FALSE; } hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_CAPTEST)); // Main message loop: while (GetMessage(&msg, NULL, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return (int) msg.wParam; } ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_CAPTEST)); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = MAKEINTRESOURCE(IDC_CAPTEST); wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); return RegisterClassEx(&wcex); } BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; hInst = hInstance; // Store instance handle in our global variable hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if (!hWnd) { return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; switch (message) { case WM_CREATE: OnCreate(hWnd, message, wParam, lParam); break; case WM_SIZE: OnSize(hWnd, message, wParam, lParam); break; case WM_PAINT: OnPaint(hWnd, message, wParam, lParam); break; case WM_DESTROY: OnDestroy(hWnd, message, wParam, lParam); break; case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); // Parse the menu selections: switch (wmId) { case IDC_BUTTONSTART: OnButtonStart(hWnd, message, wParam, lParam); break; case IDM_ABOUT: MessageBox(hWnd, _T("CAPTest"),_T("MBox"),MB_OK); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } int OnCreate(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int i=0; TCHAR strBuf[1024]; hWndEdit = CreateWindow(TEXT("edit"),NULL, WS_CHILD|WS_BORDER|WS_VISIBLE|ES_MULTILINE|WS_VSCROLL, 10,130,600,400, hWnd, (HMENU) IDC_EDIT, hInst, NULL); hWndButtonStart = CreateWindow(TEXT("button"), TEXT("START"), WS_CHILD|WS_BORDER|WS_VISIBLE, 100, 40, 80, 25, hWnd, (HMENU)IDC_BUTTONSTART, hInst, NULL); hWndComboAdapt = CreateWindow(_T("combobox"), NULL, WS_CHILD|WS_BORDER|WS_VISIBLE|LBS_STANDARD, 10, 10, 600, 250, hWnd, (HMENU)IDC_COMBOADAPT, hInst, NULL); if(SetDllDirectory(_T("C:\\Windows\\System32\\Npcap")) == 0) { return -1; } if(pcap_findalldevs(&alldevs, errbuf) == -1) { return -1; } for(d=alldevs; d; d=d->next) { if (d->description) { wsprintf(strBuf, _T("%d. %s (%s)"), ++i, d->name, d->description); SendMessage(hWndComboAdapt, CB_ADDSTRING, (WPARAM)0, (LPARAM)(LPCTSTR)strBuf); PRINT(strBuf);PRINT(_T("\r\n")); } else { wsprintf(strBuf, _T("%d. %s (%s)"), ++i, d->name, _T(" (No description available)")); SendMessage(hWndComboAdapt, CB_ADDSTRING, (WPARAM)0, (LPARAM)(LPCTSTR)strBuf); PRINT(strBuf);PRINT(_T("\r\n")); } } SendMessage(hWndComboAdapt, CB_SETCURSEL , 4, 0L); return 1; } int OnSize(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int cxClient,cyClient; cxClient = LOWORD (lParam); cyClient = HIWORD (lParam); MoveWindow(hWndComboAdapt, 5, 5, cxClient-10, 250, TRUE); MoveWindow(hWndButtonStart, cxClient-150, 40, 100, 30, TRUE); MoveWindow(hWndEdit, 5, 80, cxClient-10, cyClient-90, TRUE); return DefWindowProc(hWnd, message, wParam, lParam); } int OnPaint(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HDC hdc; RECT rt; hdc = BeginPaint(hWnd, &ps); GetClientRect(hWnd, &rt); EndPaint(hWnd, &ps); return 1; } int OnDestroy(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { if(1==iStart) { iStart =0; MessageBox(hWnd, _T("STOP and EXIT."),_T("MBox"),MB_OK); //for some time to exit. } if(adhandle) { pcap_close(adhandle); adhandle = NULL; } pcap_freealldevs(alldevs); PostQuitMessage(0); return 1; } int OnButtonStart(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int i; if(0==iStart) { iStart = 1; SetWindowText(hWndButtonStart, _T("STOP")); inum = (int)SendMessage(hWndComboAdapt, CB_GETCURSEL , 0, 0L); inum++; PRINT(_T("\r\n Select iNum=%d"),inum); for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++); if(adhandle) { pcap_close(adhandle); adhandle = NULL; } if ((adhandle= pcap_open_live(d->name, // name of the device 65536, // portion of the packet to capture. // 65536 grants that the whole packet will be captured on all the MACs. 1, // promiscuous mode (nonzero means promiscuous) 1000, // read timeout errbuf // error buffer )) == NULL) { fprintf(stderr,"\nUnable to open the adapter. %s is not supported by Npcap\n", d->name); /* Free the device list */ //pcap_freealldevs(alldevs); return -1; } PRINT(_T("\nlistening on %s...\n"), d->description); _beginthread(ThreadProc1, 0, NULL); } else { iStart = 0; SetWindowText(hWndButtonStart, _T("START")); } return 1; } VOID ThreadProc1(PVOID pData) { PRINT(_T("\r\n ThreadProc1 Begin..")); while((res = pcap_next_ex( adhandle, &header, &pkt_data)) >= 0) { if(0== iStart) break; if(res == 0) /* Timeout elapsed */ continue; /* convert the timestamp to readable format */ local_tv_sec = header->ts.tv_sec; ltime=localtime(&local_tv_sec); strftime( timestr, sizeof timestr, "%H:%M:%S", ltime); PRINT(_T("%s,%.6d len:%d \t[%2X %2X %2X %2X %2X %2X <- %2X %2X %2X %2X %2X %2X] \r\n"), timestr, header->ts.tv_usec, header->len, *pkt_data,*(pkt_data+1),*(pkt_data+2),*(pkt_data+3),*(pkt_data+4),*(pkt_data+5), *(pkt_data+6),*(pkt_data+7),*(pkt_data+8),*(pkt_data+9),*(pkt_data+10),*(pkt_data+11)); } if(res == -1) { PRINT(_T("Error reading the packets: %s\n"), pcap_geterr(adhandle)); } PRINT(_T("\r\n ThreadProc1 Exit.")); pcap_close(adhandle); adhandle = NULL; _endthread(); } TCHAR buffer[1024]; int PRINT(TCHAR *fmt, ...) { va_list argptr; int cnt; int iEditTextLength; HWND hWnd; if(NULL == hWndEdit) return 0; va_start(argptr, fmt); cnt = vsprintf(buffer, fmt, argptr); va_end(argptr); iEditTextLength = GetWindowTextLength(hWndEdit); if(iEditTextLength + cnt > 30000) // edit text max length is 30000 { SendMessage(hWndEdit, EM_SETSEL, 0, 10000); SendMessage(hWndEdit, WM_CLEAR, 0, 0); iEditTextLength = iEditTextLength - 10000; } SendMessage(hWndEdit, EM_SETSEL, iEditTextLength, iEditTextLength); SendMessage(hWndEdit, EM_REPLACESEL,0, (LPARAM) buffer); return(cnt); }