windows上网络抓包以及编辑

WinDivert: Windows Packet Divert https://reqrypt.org/windivert.html

/*
 * netfilter.c
 * (C) 2018, all rights reserved,
 *
 * This file is part of WinDivert.
 *
 * WinDivert is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Lesser General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or (at your
 * option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 * License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * WinDivert is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc., 51
 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

/*
 * DESCRIPTION:
 * This is a simple traffic filter/firewall using WinDivert.
 *
 * usage: netfilter.exe windivert-filter [priority]
 *
 * Any traffic that matches the windivert-filter will be blocked using one of
 * the following methods:
 * - TCP: send a TCP RST to the packet's source.
 * - UDP: send a ICMP(v6) "destination unreachable" to the packet's source.
 * - ICMP/ICMPv6: Drop the packet.
 *
 * This program is similar to Linux's iptables with the "-j REJECT" target.
 */

#include <winsock2.h>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "windivert.h"

#define MAXBUF  0xFFFF

/*
 * Pre-fabricated packets.
 */
typedef struct
{
    WINDIVERT_IPHDR ip;
    WINDIVERT_TCPHDR tcp;
} TCPPACKET, *PTCPPACKET;

typedef struct
{
    WINDIVERT_IPV6HDR ipv6;
    WINDIVERT_TCPHDR tcp;
} TCPV6PACKET, *PTCPV6PACKET;

typedef struct
{
    WINDIVERT_IPHDR ip;
    WINDIVERT_ICMPHDR icmp;
    UINT8 data[];
} ICMPPACKET, *PICMPPACKET;

typedef struct
{
    WINDIVERT_IPV6HDR ipv6;
    WINDIVERT_ICMPV6HDR icmpv6;
    UINT8 data[];
} ICMPV6PACKET, *PICMPV6PACKET;

/*
 * Prototypes.
 */
static void PacketIpInit(PWINDIVERT_IPHDR packet);
static void PacketIpTcpInit(PTCPPACKET packet);
static void PacketIpIcmpInit(PICMPPACKET packet);
static void PacketIpv6Init(PWINDIVERT_IPV6HDR packet);
static void PacketIpv6TcpInit(PTCPV6PACKET packet);
static void PacketIpv6Icmpv6Init(PICMPV6PACKET packet);

/*
 * Entry.
 */
void DumpBuff8(unsigned char *buff, UINT buff_len, UINT print_len, char tail)
{
    UINT i = 0;
    UINT real_print_len = 0;

    real_print_len = buff_len>print_len?print_len:buff_len;

    fprintf(stderr, "\r\n\r\n");
    if (tail) {
        for (i = buff_len - real_print_len; i < buff_len ; ++i) {
            fprintf(stderr, "%02x ", buff[i]);
        }
        fprintf(stderr, "\r\n\r\n");
        for (i = buff_len - real_print_len; i < buff_len ; ++i) {
            fprintf(stderr, "%c ", buff[i]);
        }
    }
    else {
        for (i = 0; i < real_print_len ; ++i) {
            fprintf(stderr, "%02x ", buff[i]);
        }
        fprintf(stderr, "\r\n\r\n");
        for (i = buff_len - real_print_len; i < buff_len ; ++i) {
            fprintf(stderr, "%c ", buff[i]);
        }
    }
    fprintf(stderr, "\r\n\r\n");
}

unsigned char hack_from[] = {0x32, 0x00, 0x30, 0x00, 0x31, 0x00, 0x39, 0x00, 0x2d, 0x00, 0x31, 0x00, 0x2d, 0x00, 0x32, 0x00, 0x35, 0x00};
unsigned char hack_to[] = {0x32, 0x00, 0x30, 0x00, 0x35, 0x00, 0x39, 0x00, 0x2d, 0x00, 0x31, 0x00, 0x2d, 0x00, 0x32, 0x00, 0x35, 0x00};

int __cdecl main(int argc, char **argv)
{
    HANDLE handle, console;
    UINT i;
    INT16 priority = 0;
    unsigned char packet[MAXBUF];
    UINT packet_len;
    WINDIVERT_ADDRESS recv_addr, send_addr;
    PWINDIVERT_IPHDR ip_header;
    PWINDIVERT_IPV6HDR ipv6_header;
    PWINDIVERT_ICMPHDR icmp_header;
    PWINDIVERT_ICMPV6HDR icmpv6_header;
    PWINDIVERT_TCPHDR tcp_header;
    PWINDIVERT_UDPHDR udp_header;
    UINT payload_len;
    const char *err_str;
    
    TCPPACKET reset0;
    PTCPPACKET reset = &reset0;
    UINT8 dnr0[sizeof(ICMPPACKET) + 0x0F*sizeof(UINT32) + 8 + 1];
    PICMPPACKET dnr = (PICMPPACKET)dnr0;

    TCPV6PACKET resetv6_0;
    PTCPV6PACKET resetv6 = &resetv6_0;
    UINT8 dnrv6_0[sizeof(ICMPV6PACKET) + sizeof(WINDIVERT_IPV6HDR) +
        sizeof(WINDIVERT_TCPHDR)];
    PICMPV6PACKET dnrv6 = (PICMPV6PACKET)dnrv6_0;

    // Check arguments.
    switch (argc)
    {
        case 2:
            break;
        case 3:
            priority = (INT16)atoi(argv[2]);
            break;
        default:
            fprintf(stderr, "usage: %s windivert-filter [priority]\n",
                argv[0]);
            fprintf(stderr, "examples:\n");
            fprintf(stderr, "\t%s true\n", argv[0]);
            fprintf(stderr, "\t%s \"outbound and tcp.DstPort == 80\" 1000\n",
                argv[0]);
            fprintf(stderr, "\t%s \"inbound and tcp.Syn\" -400\n", argv[0]);
            exit(EXIT_FAILURE);
    }

    // Initialize all packets.
    PacketIpTcpInit(reset);
    reset->tcp.Rst = 1;
    reset->tcp.Ack = 1;
    PacketIpIcmpInit(dnr);
    dnr->icmp.Type = 3;         // Destination not reachable.
    dnr->icmp.Code = 3;         // Port not reachable.
    PacketIpv6TcpInit(resetv6);
    resetv6->tcp.Rst = 1;
    resetv6->tcp.Ack = 1;
    PacketIpv6Icmpv6Init(dnrv6);
    dnrv6->ipv6.Length = htons(sizeof(WINDIVERT_ICMPV6HDR) + 4 +
        sizeof(WINDIVERT_IPV6HDR) + sizeof(WINDIVERT_TCPHDR));
    dnrv6->icmpv6.Type = 1;     // Destination not reachable.
    dnrv6->icmpv6.Code = 4;     // Port not reachable.

    // Get console for pretty colors.
    console = GetStdHandle(STD_OUTPUT_HANDLE);

    // Divert traffic matching the filter:
    handle = WinDivertOpen(argv[1], WINDIVERT_LAYER_NETWORK, priority, 0);
    if (handle == INVALID_HANDLE_VALUE)
    {
        if (GetLastError() == ERROR_INVALID_PARAMETER &&
            !WinDivertHelperCheckFilter(argv[1], WINDIVERT_LAYER_NETWORK,
                &err_str, NULL))
        {
            fprintf(stderr, "error: invalid filter \"%s\"\n", err_str);
            exit(EXIT_FAILURE);
        }
        fprintf(stderr, "error: failed to open the WinDivert device (%d)\n",
            GetLastError());
        exit(EXIT_FAILURE);
    }

    // Main loop:

    while (TRUE)
    {
        if (!WinDivertRecv(handle, packet, sizeof(packet), &recv_addr, &packet_len))
        {
            // Handle recv error
            continue;
        }

        if (!WinDivertHelperParsePacket(packet, packet_len, &ip_header, NULL,
                NULL, NULL, &tcp_header, NULL, NULL, NULL))
        {
            //fprintf(stderr, "failed to parse packet (%d)\r\n", GetLastError());
        }
        else {

            switch (recv_addr.Direction)
            {
                case WINDIVERT_DIRECTION_OUTBOUND:
                    break;

                case WINDIVERT_DIRECTION_INBOUND:
                    break;
            }


            if (ip_header != NULL)
            {
                UINT8 *src_addr = (UINT8 *)&ip_header->SrcAddr;
                UINT8 *dst_addr = (UINT8 *)&ip_header->DstAddr;

                if (src_addr[0] == 1 && src_addr[1] == 2 && src_addr[2] == 3 && src_addr[3] == 4) {
                    fprintf(stderr, "packet_len %d\r\n", packet_len);
                    fprintf(stderr, "ip.SrcAddr=%u.%u.%u.%u ip.DstAddr=%u.%u.%u.%u \r\n",
                            src_addr[0], src_addr[1], src_addr[2], src_addr[3],
                            dst_addr[0], dst_addr[1], dst_addr[2], dst_addr[3]);
                    DumpBuff8(packet, packet_len, 256, 1);

                    if (packet_len > sizeof(hack_from)) {
                        if (0 == memcmp(hack_from, packet+packet_len-sizeof(hack_from), sizeof(hack_from))) {
                            fprintf(stderr, "found target packet, hack it!");
                            memcpy(packet+packet_len-sizeof(hack_from), hack_to, sizeof(hack_to));
                            fprintf(stderr, "data after hacked:");
                            DumpBuff8(packet, packet_len, 256, 1);
                        }
                    }
                }
                else if (dst_addr[0] == 1 && dst_addr[1] == 2 && dst_addr[2] == 3 && dst_addr[3] == 4) {
                    fprintf(stderr, "packet_len %d\r\n", packet_len);
                    fprintf(stderr, "ip.SrcAddr=%u.%u.%u.%u ip.DstAddr=%u.%u.%u.%u \r\n",
                            src_addr[0], src_addr[1], src_addr[2], src_addr[3],
                            dst_addr[0], dst_addr[1], dst_addr[2], dst_addr[3]);
                    DumpBuff8(packet, packet_len, 256, 1);
                }
            }
        }

        // Modify packet.

        WinDivertHelperCalcChecksums(packet, packet_len, &recv_addr, 0);
        if (!WinDivertSend(handle, packet, packet_len, &recv_addr, NULL))
        {
            // Handle send error
            continue;
        }
    }
    return 0;
}

/*
 * Initialize a PACKET.
 */
static void PacketIpInit(PWINDIVERT_IPHDR packet)
{
    memset(packet, 0, sizeof(WINDIVERT_IPHDR));
    packet->Version = 4;
    packet->HdrLength = sizeof(WINDIVERT_IPHDR) / sizeof(UINT32);
    packet->Id = ntohs(0xDEAD);
    packet->TTL = 64;
}

/*
 * Initialize a TCPPACKET.
 */
static void PacketIpTcpInit(PTCPPACKET packet)
{
    memset(packet, 0, sizeof(TCPPACKET));
    PacketIpInit(&packet->ip);
    packet->ip.Length = htons(sizeof(TCPPACKET));
    packet->ip.Protocol = IPPROTO_TCP;
    packet->tcp.HdrLength = sizeof(WINDIVERT_TCPHDR) / sizeof(UINT32);
}

/*
 * Initialize an ICMPPACKET.
 */
static void PacketIpIcmpInit(PICMPPACKET packet)
{
    memset(packet, 0, sizeof(ICMPPACKET));
    PacketIpInit(&packet->ip);
    packet->ip.Protocol = IPPROTO_ICMP;
}

/*
 * Initialize a PACKETV6.
 */
static void PacketIpv6Init(PWINDIVERT_IPV6HDR packet)
{
    memset(packet, 0, sizeof(WINDIVERT_IPV6HDR));
    packet->Version = 6;
    packet->HopLimit = 64;
}

/*
 * Initialize a TCPV6PACKET.
 */
static void PacketIpv6TcpInit(PTCPV6PACKET packet)
{
    memset(packet, 0, sizeof(TCPV6PACKET));
    PacketIpv6Init(&packet->ipv6);
    packet->ipv6.Length = htons(sizeof(WINDIVERT_TCPHDR));
    packet->ipv6.NextHdr = IPPROTO_TCP;
    packet->tcp.HdrLength = sizeof(WINDIVERT_TCPHDR) / sizeof(UINT32);
}

/*
 * Initialize an ICMP PACKET.
 */
static void PacketIpv6Icmpv6Init(PICMPV6PACKET packet)
{
    memset(packet, 0, sizeof(ICMPV6PACKET));
    PacketIpv6Init(&packet->ipv6);
    packet->ipv6.NextHdr = IPPROTO_ICMPV6;
}

猜你喜欢

转载自www.cnblogs.com/xixiangyuanye/p/10181581.html