使用 WinSock2 SOCK_RAW 套接字搭配 SIO_RCVALL IOCTL,可在 Windows 上攔截本機網卡收發的所有 IP 封包。本文提供一個完整的主控台程式,支援:
// IP 標頭
typedef struct _iphdr {
BYTE h_lenver; // 4位版本 | 4位首部長度
BYTE tos;
WORD total_len;
WORD ident;
WORD frag_and_flags;
BYTE ttl;
BYTE proto; // 協議:TCP=6, UDP=17, ICMP=1
WORD checksum;
DWORD sourceIP;
DWORD destIP;
} IP_HEADER;
// TCP 標頭
typedef struct _tcphdr {
WORD th_sport; // 來源埠
WORD th_dport; // 目的埠
DWORD th_seq;
DWORD th_ack;
BYTE th_lenres; // 4位首部長度 | 6位保留
BYTE th_flag; // 6位旗標:FIN,SYN,RST,PSH,ACK,URG
WORD th_win;
WORD th_sum;
WORD th_urp;
} TCP_HEADER;
// UDP 標頭
typedef struct _udphdr {
WORD uh_sport;
WORD uh_dport;
WORD uh_len;
WORD uh_sum;
} UDP_HEADER;
// ICMP 標頭
typedef struct _icmphdr {
BYTE i_type;
BYTE i_code;
WORD i_cksum;
WORD i_id;
WORD i_seq;
DWORD timestamp;
} ICMP_HEADER;
WSAStartup(MAKEWORD(2,1), &wsaData)socket(AF_INET, SOCK_RAW, IPPROTO_IP)gethostname → gethostbyname → bindWSAIoctl(s, SIO_RCVALL, &in, sizeof(in), &out, sizeof(out), &ret, NULL, NULL)while (1) {
recv(s, buf, MAX_PACK_LEN, 0);
DecodeIpPack(buf, len);
}
DecodeIpPack:提取 IP 標頭,依 proto 分派至 TCP/UDP/ICMP 解析器,並套用 IP/埠/字串過濾。DecodeTcpPack:計算 TCP 首部長度(th_lenres >> 4 * 4),解析旗標、埠號、序號、視窗,選擇性輸出負載資料。DecodeUdpPack:解析埠號、長度,選擇性十六進制/ASCII 輸出負載。DecodeIcmpPack:解析類型/代碼(Echo Request=8, Echo Reply=0 等),選擇性輸出負載。IPSpy.exe [/t] [/u] [/i] [/p] [/f:srcIP] [/d:dstIP] [/s:string] [/o:port]
/t 顯示 TCP 封包
/u 顯示 UDP 封包
/i 顯示 ICMP 封包
/p 解碼封包負載 (預設關閉)
/f 來源 IP 過濾
/d 目的 IP 過濾
/s TCP 負載敏感字串過濾
/o 埠號/ICMP 類型過濾
Ws2_32.lib。