|
@ -440,28 +440,119 @@ static inline void change_window_size(const PWINDIVERT_TCPHDR ppTcpHdr, unsigned |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/* HTTP method end without trailing space */ |
|
|
/* HTTP method end without trailing space */ |
|
|
static PVOID find_http_method_end(const char *pkt, unsigned int http_frag, int *is_fragmented) { |
|
|
static const char *find_http_method_end(const char *pkt, unsigned int http_frag, int *is_fragmented) { |
|
|
unsigned int i; |
|
|
switch (*pkt) { |
|
|
for (i = 0; i<(sizeof(http_methods) / sizeof(*http_methods)); i++) { |
|
|
case 'G': |
|
|
if (memcmp(pkt, http_methods[i], strlen(http_methods[i])) == 0) { |
|
|
if (strncmp(pkt, "GET", 3) == 0) { |
|
|
if (is_fragmented) |
|
|
if (is_fragmented) |
|
|
*is_fragmented = 0; |
|
|
*is_fragmented = 0; |
|
|
return (char*)pkt + strlen(http_methods[i]) - 1; |
|
|
return pkt + 3; |
|
|
} |
|
|
} |
|
|
/* Try to find HTTP method in a second part of fragmented packet */ |
|
|
break; |
|
|
if ((http_frag == 1 || http_frag == 2) && |
|
|
case 'P': |
|
|
memcmp(pkt, http_methods[i] + http_frag, |
|
|
if (strncmp(pkt, "POST", 4) == 0) { |
|
|
strlen(http_methods[i]) - http_frag) == 0 |
|
|
if (is_fragmented) |
|
|
) |
|
|
*is_fragmented = 0; |
|
|
{ |
|
|
return pkt + 4; |
|
|
if (is_fragmented) |
|
|
} |
|
|
*is_fragmented = 1; |
|
|
break; |
|
|
return (char*)pkt + strlen(http_methods[i]) - http_frag - 1; |
|
|
case 'H': |
|
|
} |
|
|
if (strncmp(pkt, "HEAD", 4) == 0) { |
|
|
|
|
|
if (is_fragmented) |
|
|
|
|
|
*is_fragmented = 0; |
|
|
|
|
|
return pkt + 4; |
|
|
|
|
|
} |
|
|
|
|
|
break; |
|
|
|
|
|
case 'O': |
|
|
|
|
|
if (strncmp(pkt, "OPTIONS", 7) == 0) { |
|
|
|
|
|
if (is_fragmented) |
|
|
|
|
|
*is_fragmented = 0; |
|
|
|
|
|
return pkt + 7; |
|
|
|
|
|
} |
|
|
|
|
|
break; |
|
|
|
|
|
case 'D': |
|
|
|
|
|
if (strncmp(pkt, "DELETE", 6) == 0) { |
|
|
|
|
|
if (is_fragmented) |
|
|
|
|
|
*is_fragmented = 0; |
|
|
|
|
|
return pkt + 6; |
|
|
|
|
|
} |
|
|
|
|
|
break; |
|
|
|
|
|
case 'T': |
|
|
|
|
|
if (strncmp(pkt, "TRACE", 5) == 0) { |
|
|
|
|
|
if (is_fragmented) |
|
|
|
|
|
*is_fragmented = 0; |
|
|
|
|
|
return pkt + 5; |
|
|
|
|
|
} |
|
|
|
|
|
break; |
|
|
|
|
|
case 'C': |
|
|
|
|
|
if (strncmp(pkt, "CONNECT", 7) == 0) { |
|
|
|
|
|
if (is_fragmented) |
|
|
|
|
|
*is_fragmented = 0; |
|
|
|
|
|
return pkt + 7; |
|
|
|
|
|
} |
|
|
|
|
|
break; |
|
|
|
|
|
default: |
|
|
|
|
|
/* Try to find HTTP method in a second part of fragmented packet */ |
|
|
|
|
|
if ((http_frag == 1 || http_frag == 2)) { |
|
|
|
|
|
switch (*pkt) { |
|
|
|
|
|
case 'E': |
|
|
|
|
|
if (strncmp(pkt, "ET", http_frag) == 0) { |
|
|
|
|
|
if (is_fragmented) |
|
|
|
|
|
*is_fragmented = 1; |
|
|
|
|
|
return pkt + http_frag - 1; |
|
|
|
|
|
} |
|
|
|
|
|
break; |
|
|
|
|
|
case 'S': |
|
|
|
|
|
if (strncmp(pkt, "ST", http_frag) == 0) { |
|
|
|
|
|
if (is_fragmented) |
|
|
|
|
|
*is_fragmented = 1; |
|
|
|
|
|
return pkt + http_frag - 1; |
|
|
|
|
|
} |
|
|
|
|
|
break; |
|
|
|
|
|
case 'A': |
|
|
|
|
|
if (strncmp(pkt, "AD", http_frag) == 0) { |
|
|
|
|
|
if (is_fragmented) |
|
|
|
|
|
*is_fragmented = 1; |
|
|
|
|
|
return pkt + http_frag - 1; |
|
|
|
|
|
} |
|
|
|
|
|
break; |
|
|
|
|
|
case 'N': |
|
|
|
|
|
if (strncmp(pkt, "NS", http_frag) == 0) { |
|
|
|
|
|
if (is_fragmented) |
|
|
|
|
|
*is_fragmented = 1; |
|
|
|
|
|
return pkt + http_frag - 1; |
|
|
|
|
|
} |
|
|
|
|
|
break; |
|
|
|
|
|
case 'L': |
|
|
|
|
|
if (strncmp(pkt, "LE", http_frag) == 0) { |
|
|
|
|
|
if (is_fragmented) |
|
|
|
|
|
*is_fragmented = 1; |
|
|
|
|
|
return pkt + http_frag - 1; |
|
|
|
|
|
} |
|
|
|
|
|
break; |
|
|
|
|
|
case 'R': |
|
|
|
|
|
if (strncmp(pkt, "RACE", http_frag + 1) == 0) { |
|
|
|
|
|
if (is_fragmented) |
|
|
|
|
|
*is_fragmented = 1; |
|
|
|
|
|
return pkt + http_frag - 1; |
|
|
|
|
|
} |
|
|
|
|
|
break; |
|
|
|
|
|
case 'O': |
|
|
|
|
|
if (strncmp(pkt, "ONNECT", http_frag + 1) == 0) { |
|
|
|
|
|
if (is_fragmented) |
|
|
|
|
|
*is_fragmented = 1; |
|
|
|
|
|
return pkt + http_frag - 1; |
|
|
|
|
|
} |
|
|
|
|
|
break; |
|
|
|
|
|
default: |
|
|
|
|
|
return NULL; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
return NULL; |
|
|
return NULL; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Fragment and send the packet.
|
|
|
/** Fragment and send the packet.
|
|
|
* |
|
|
* |
|
|
* This function cuts off the end of the packet (step=0) or |
|
|
* This function cuts off the end of the packet (step=0) or |
|
@ -484,40 +575,36 @@ static void send_native_fragment(HANDLE w_filter, WINDIVERT_ADDRESS addr, |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (step == 0) { |
|
|
switch(step) { |
|
|
if (packet_v4) |
|
|
case 0: |
|
|
ppIpHdr->Length = htons( |
|
|
if (packet_v4) |
|
|
ntohs(ppIpHdr->Length) - |
|
|
ppIpHdr->Length = htons( |
|
|
packet_dataLen + fragment_size |
|
|
ntohs(ppIpHdr->Length) - |
|
|
); |
|
|
packet_dataLen + fragment_size |
|
|
else if (packet_v6) |
|
|
); |
|
|
ppIpV6Hdr->Length = htons( |
|
|
else if (packet_v6) |
|
|
ntohs(ppIpV6Hdr->Length) - |
|
|
ppIpV6Hdr->Length = htons( |
|
|
packet_dataLen + fragment_size |
|
|
ntohs(ppIpV6Hdr->Length) - |
|
|
); |
|
|
packet_dataLen + fragment_size |
|
|
//printf("step0 (%d:%d), pp:%d, was:%d, now:%d\n",
|
|
|
); |
|
|
// packet_v4, packet_v6, ntohs(ppIpHdr->Length),
|
|
|
packetLen = packetLen - packet_dataLen + fragment_size; |
|
|
// packetLen, packetLen - packet_dataLen + fragment_size);
|
|
|
break; |
|
|
packetLen = packetLen - packet_dataLen + fragment_size; |
|
|
case 1: |
|
|
} |
|
|
if (packet_v4) |
|
|
|
|
|
ppIpHdr->Length = htons( |
|
|
else if (step == 1) { |
|
|
ntohs(ppIpHdr->Length) - fragment_size |
|
|
if (packet_v4) |
|
|
); |
|
|
ppIpHdr->Length = htons( |
|
|
else if (packet_v6) |
|
|
ntohs(ppIpHdr->Length) - fragment_size |
|
|
ppIpV6Hdr->Length = htons( |
|
|
); |
|
|
ntohs(ppIpV6Hdr->Length) - fragment_size |
|
|
else if (packet_v6) |
|
|
); |
|
|
ppIpV6Hdr->Length = htons( |
|
|
memmove(packet_data, |
|
|
ntohs(ppIpV6Hdr->Length) - fragment_size |
|
|
(char*)packet_data + fragment_size, |
|
|
); |
|
|
packet_dataLen - fragment_size); |
|
|
//printf("step1 (%d:%d), pp:%d, was:%d, now:%d\n", packet_v4, packet_v6, ntohs(ppIpHdr->Length),
|
|
|
packetLen -= fragment_size; |
|
|
// packetLen, packetLen - fragment_size);
|
|
|
|
|
|
memmove(packet_data, |
|
|
ppTcpHdr->SeqNum = htonl(ntohl(ppTcpHdr->SeqNum) + fragment_size); |
|
|
(char*)packet_data + fragment_size, |
|
|
break; |
|
|
packet_dataLen - fragment_size); |
|
|
|
|
|
packetLen -= fragment_size; |
|
|
|
|
|
|
|
|
|
|
|
ppTcpHdr->SeqNum = htonl(ntohl(ppTcpHdr->SeqNum) + fragment_size); |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
addr.IPChecksum = 0; |
|
|
addr.IPChecksum = 0; |
|
@ -532,9 +619,9 @@ static void send_native_fragment(HANDLE w_filter, WINDIVERT_ADDRESS addr, |
|
|
NULL, &addr |
|
|
NULL, &addr |
|
|
); |
|
|
); |
|
|
memcpy(packet, packet_bak, orig_packetLen); |
|
|
memcpy(packet, packet_bak, orig_packetLen); |
|
|
//printf("Sent native fragment of %d size (step%d)\n", packetLen, step);
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int main(int argc, char *argv[]) { |
|
|
int main(int argc, char *argv[]) { |
|
|
static enum packet_type_e { |
|
|
static enum packet_type_e { |
|
|
unknown, |
|
|
unknown, |
|
|