From 78b204ac0017f7bff68790a9aff1c4a2d657206c Mon Sep 17 00:00:00 2001 From: taynpg Date: Wed, 21 Aug 2024 02:25:46 +0800 Subject: [PATCH] =?UTF-8?q?add=EF=BC=9A=E5=9F=BA=E7=A1=80win=E7=A4=BA?= =?UTF-8?q?=E4=BE=8B=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/settings.json | 4 +- CMakeLists.txt | 12 ++++ win/main.cpp | 143 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 CMakeLists.txt create mode 100644 win/main.cpp diff --git a/.vscode/settings.json b/.vscode/settings.json index 4ee8847..d8b949d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -136,6 +136,8 @@ "concepts": "cpp", "coroutine": "cpp", "format": "cpp", - "stop_token": "cpp" + "stop_token": "cpp", + "span": "cpp", + "unordered_set": "cpp" } } \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..2a8d83e --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,12 @@ +cmake_minimum_required(VERSION 3.16) + +project(SockGrab) + + +if (MSVC) + add_compile_options(/source-charset:utf-8) + add_compile_options(-D_CRT_SECURE_NO_WARNINGS) +endif() + +add_executable(SockGrab win/main.cpp) +target_link_libraries(SockGrab PRIVATE ws2_32) \ No newline at end of file diff --git a/win/main.cpp b/win/main.cpp new file mode 100644 index 0000000..4514285 --- /dev/null +++ b/win/main.cpp @@ -0,0 +1,143 @@ +#include +#include +#include // For gethostname() + +#include +#include + +#pragma comment(lib, "Ws2_32.lib") + +int main() +{ + WSADATA wsaData; + if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { + std::cout << "Failed to initialize Winsock." << std::endl; + return -1; + } + + // 创建原始套接字 + auto sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP); + if (sock == INVALID_SOCKET) { + std::cout << "Invalid socket. Error code: " << WSAGetLastError() << std::endl; + WSACleanup(); + return -1; + } + + // 获取本地主机名 + char name[128]{}; + if (gethostname(name, sizeof(name)) == SOCKET_ERROR) { + std::cout << "Error getting hostname. Error code: " << WSAGetLastError() << std::endl; + closesocket(sock); + WSACleanup(); + return -1; + } + + // 解析本地主机名 + struct hostent* pHostent = gethostbyname(name); + if (!pHostent) { + std::cout << "Error resolving host. Error code: " << WSAGetLastError() << std::endl; + closesocket(sock); + WSACleanup(); + return -1; + } + + // 绑定本地地址到SOCKET句柄 + sockaddr_in addr; + addr.sin_family = AF_INET; + addr.sin_addr = *(in_addr*)pHostent->h_addr_list[0]; + addr.sin_port = 0; // 0表示让系统选择端口 + + if (bind(sock, (sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR) { + std::cout << "Bind failed. Error code: " << WSAGetLastError() << std::endl; + closesocket(sock); + WSACleanup(); + return -1; + } + + // 设置SOCKET为接收所有流经绑定的IP的网卡的所有数据,包括接收和发送的数据包 + u_long sioarg = 1; + DWORD wt = 0; + if (WSAIoctl(sock, SIO_RCVALL, &sioarg, sizeof(sioarg), NULL, 0, &wt, NULL, NULL) == SOCKET_ERROR) { + std::cout << "WSAIoctl failed. Error code: " << WSAGetLastError() << std::endl; + closesocket(sock); + WSACleanup(); + return -1; + } + + // 创建事件对象 + HANDLE g_event = CreateEvent(NULL, TRUE, FALSE, NULL); + if (g_event == NULL) { + std::cout << "CreateEvent failed. Error code: " << GetLastError() << std::endl; + closesocket(sock); + WSACleanup(); + return -1; + } + + // 使用事件选择 + if (WSAEventSelect(sock, g_event, FD_READ | FD_CLOSE) == SOCKET_ERROR) { + std::cout << "WSAEventSelect failed. Error code: " << WSAGetLastError() << std::endl; + CloseHandle(g_event); + closesocket(sock); + WSACleanup(); + return -1; + } + + // 接收数据并打印 + char buffer[65536]; // 缓冲区大小 + + while (true) { + // 等待事件触发 + DWORD wait_result = WSAWaitForMultipleEvents(1, &g_event, TRUE, WSA_INFINITE, TRUE); + if (wait_result == WSA_WAIT_FAILED) { + std::cout << "WSAWaitForMultipleEvents failed. Error code: " << WSAGetLastError() << std::endl; + break; + } + + // 清除事件 + if (!ResetEvent(g_event)) { + std::cout << "ResetEvent failed. Error code: " << GetLastError() << std::endl; + break; + } + + // 处理接收到的数据 + sockaddr_in source_addr; + int addrlen = sizeof(source_addr); + + int bytes_received = recvfrom(sock, buffer, sizeof(buffer), 0, (sockaddr*)&source_addr, &addrlen); + if (bytes_received == SOCKET_ERROR) { + int error_code = WSAGetLastError(); + if (error_code != WSAEWOULDBLOCK) { + std::cout << "recvfrom error: " << error_code << std::endl; + break; + } + // 如果是非阻塞模式的超时错误,继续循环 + continue; + } + + // 打印接收到的数据 + std::cout << "Received packet of size: " << bytes_received << " bytes" << std::endl; + + // 打印远端 IP 地址和端口 + char ip_address[INET_ADDRSTRLEN]; + if (inet_ntop(AF_INET, &source_addr.sin_addr, ip_address, sizeof(ip_address)) != NULL) { + std::cout << "Source IP: " << ip_address << std::endl; + std::cout << "Source Port: " << ntohs(source_addr.sin_port) << std::endl; + } else { + std::cout << "Error converting IP address. Error code: " << WSAGetLastError() << std::endl; + } + + // 打印数据内容 + for (int i = 0; i < bytes_received; ++i) { + std::cout << std::hex << (unsigned int)(unsigned char)buffer[i] << " "; + if ((i + 1) % 16 == 0) std::cout << std::endl; + } + std::cout << std::endl; + } + + // 清理资源 + CloseHandle(g_event); + closesocket(sock); + WSACleanup(); + + return 0; +}