SockGrab/win/main.cpp

144 lines
4.6 KiB
C++
Raw Permalink Normal View History

2024-08-21 02:25:46 +08:00
#include <WinSock2.h>
#include <mstcpip.h>
#include <ws2tcpip.h> // For gethostname()
#include <iostream>
#include <string>
#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;
}