Switch to getopt() and slightly update fragmentation code

This commit is contained in:
ValdikSS 2017-05-17 21:33:44 +03:00
parent 6b40623dce
commit 46af3c2edb
1 changed files with 91 additions and 39 deletions

View File

@ -80,13 +80,15 @@ static PVOID find_host_header(char *pktdata, int pktlen) {
(char*)http_host_find, strlen(http_host_find));
}
static void change_window_size(char *pkt) {
*(pkt + IPV4_HDR_LEN + TCP_WINDOWSIZE_OFFSET) = 0x00;
*(pkt + IPV4_HDR_LEN + TCP_WINDOWSIZE_OFFSET + 1) = 0x02;
static void change_window_size(char *pkt, int size) {
*(uint16_t*)(pkt + IPV4_HDR_LEN + TCP_WINDOWSIZE_OFFSET) = htons(size);
}
int main(int argc, char *argv[]) {
static const char fragment_size_message[] =
"Fragment size should be in range [0 - 65535]\n";
int i, should_reinject = 0;
int opt;
HANDLE w_filter = NULL;
WINDIVERT_ADDRESS addr;
char packet[MAX_PACKET_SIZE];
@ -96,35 +98,83 @@ int main(int argc, char *argv[]) {
PWINDIVERT_IPHDR ppIpHdr;
PWINDIVERT_TCPHDR ppTcpHdr;
int do_passivedpi, do_fragment, do_host, do_host_removespace;
int temp;
char *data_addr, *data_addr_rn, *host_addr = NULL;
int do_passivedpi = 0, do_fragment_http = 0,
do_fragment_https = 0, do_host = 0,
do_host_removespace = 0;
int http_fragment_size = 2;
int https_fragment_size = 2;
char *data_addr, *data_addr_rn, *host_addr;
int host_len, fromhost_uptoend_len;
printf("GoodbyeDPI: Passive DPI blocker and Active DPI circumvention utility\n\n");
printf("GoodbyeDPI: Passive DPI blocker and Active DPI circumvention utility\n");
if (argc == 2) {
temp = atoi(argv[1]);
do_passivedpi = !!(temp & 1);
do_fragment = !!(temp & 2);
do_host = !!(temp & 4);
do_host_removespace = !!(temp & 8);
printf("Block passive: %d, Fragment: %d, hoSt: %d, Host no space: %d\n",
do_passivedpi, do_fragment, do_host, do_host_removespace);
}
else {
printf("goodbyedpi.exe [1: block passive DPI, 2: fragment outbound, "
"4: replace Host with hoSt, 8: remove space between host header and value]\n");
printf("Default: 15 (all enabled)\n");
do_passivedpi = 1;
do_fragment = 1;
do_host = 1;
do_host_removespace = 1;
if (argc == 1) {
/* enable mode -1 by default */
do_passivedpi = do_host = do_host_removespace \
= do_fragment_http = do_fragment_https = 1;
}
printf("Opening filter\n");
while ((opt = getopt(argc, argv, "123prsf:e:")) != -1) {
switch (opt) {
case '1':
do_passivedpi = do_host = do_host_removespace \
= do_fragment_http = do_fragment_https = 1;
break;
case '2':
do_passivedpi = do_host = do_host_removespace \
= do_fragment_http = do_fragment_https = 1;
https_fragment_size = 40;
break;
case '3':
do_passivedpi = do_host = do_host_removespace = 1;
break;
case 'p':
do_passivedpi = 1;
break;
case 'r':
do_host = 1;
break;
case 's':
do_host_removespace = 1;
break;
case 'f':
do_fragment_http = 1;
http_fragment_size = atoi(optarg);
if (http_fragment_size <= 0 || http_fragment_size > 65535) {
printf(fragment_size_message);
exit(EXIT_FAILURE);
}
break;
case 'e':
do_fragment_https = 1;
https_fragment_size = atoi(optarg);
if (https_fragment_size <= 0 || https_fragment_size > 65535) {
printf(fragment_size_message);
exit(EXIT_FAILURE);
}
break;
default:
printf("Usage: goodbyedpi.exe [OPTION...]\n"
" -p block passive DPI\n"
" -r replace Host with hoSt\n"
" -s remove space between host header and its value\n"
" -f [value] set HTTP fragmentation to value\n"
" -e [value] set HTTPS fragmentation to value\n"
"\n"
" -1 enables all options, -f 2 -e 2 (most compatible mode, default)\n"
" -2 enables all options, -f 2 -e 40 (better speed yet still compatible)\n"
" -3 all options except fragmentation (best speed)\n");
exit(EXIT_FAILURE);
}
}
printf("Block passive: %d, Fragment HTTP: %d, Fragment HTTPS: %d, "
"hoSt: %d, Host no space: %d\n",
do_passivedpi, (do_fragment_http ? http_fragment_size : 0),
(do_fragment_https ? https_fragment_size : 0),
do_host, do_host_removespace);
printf("\nOpening filter\n");
filter_num = 0;
if (do_passivedpi) {
@ -178,10 +228,10 @@ int main(int argc, char *argv[]) {
}
/* Handle OUTBOUND packet, search for Host header */
else if (addr.Direction == WINDIVERT_DIRECTION_OUTBOUND &&
packet_dataLen > 16 && ppTcpHdr->DstPort == htons(80)) {
if (do_host || do_host_removespace) {
data_addr = find_host_header(packet_data, packet_dataLen);
}
packet_dataLen > 16 && ppTcpHdr->DstPort == htons(80) &&
(do_host || do_host_removespace)) {
data_addr = find_host_header(packet_data, packet_dataLen);
if (do_host && data_addr) {
/* Replace "Host: " with "hoSt: " */
@ -192,12 +242,12 @@ int main(int argc, char *argv[]) {
if (do_host_removespace && data_addr) {
host_addr = data_addr + strlen(http_host_find);
fromhost_uptoend_len = packet_dataLen - ((PVOID)host_addr - packet_data);
data_addr_rn = dumb_memmem(host_addr,
packet_dataLen - ((PVOID)host_addr - packet_data),
fromhost_uptoend_len,
"\r\n", 2);
if (data_addr_rn) {
host_len = data_addr_rn - host_addr;
fromhost_uptoend_len = packet_dataLen - ((PVOID)host_addr - packet_data);
if (host_len <= 64) {
/* Move memory left by 1 byte and reduce packet size for 1 byte */
memmove(host_addr - 1, host_addr, fromhost_uptoend_len);
@ -210,9 +260,7 @@ int main(int argc, char *argv[]) {
}
}
}
if (do_host || do_host_removespace) {
WinDivertHelperCalcChecksums(packet, packetLen, 0);
}
WinDivertHelperCalcChecksums(packet, packetLen, 0);
}
}
/* Else if we got TCP packet without data */
@ -221,9 +269,13 @@ int main(int argc, char *argv[]) {
/* If we got SYN+ACK packet */
if (addr.Direction == WINDIVERT_DIRECTION_INBOUND &&
ppTcpHdr->Syn == 1) {
if (do_fragment) {
//printf("Changing Window Size!\n");
change_window_size(packet);
//printf("Changing Window Size!\n");
if (do_fragment_http && ppTcpHdr->DstPort == htons(80)) {
change_window_size(packet, http_fragment_size);
WinDivertHelperCalcChecksums(packet, packetLen, 0);
}
else if (do_fragment_https && ppTcpHdr->DstPort != htons(80)) {
change_window_size(packet, https_fragment_size);
WinDivertHelperCalcChecksums(packet, packetLen, 0);
}
}