diff --git a/README.md b/README.md index 1fb625f..0c0dabb 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,9 @@ Usage: goodbyedpi.exe [OPTION...] --reverse-frag fragment (split) the packets just as --native-frag, but send them in the reversed order. Works with the websites which could not handle segmented HTTPS TLS ClientHello (because they receive the TCP flow "combined"). + --fake-from-hex Load fake packets for Fake Request Mode from HEX values (like 1234abcDEF). + This option can be supplied multiple times, in this case each fake packet + would be sent on every request in the command line argument order. --max-payload [value] packets with TCP payload data more than [value] won't be processed. Use this option to reduce CPU usage by skipping huge amount of data (like file transfers) in already established sessions. diff --git a/src/fakepackets.c b/src/fakepackets.c index 6d59cd8..b7fb1e2 100644 --- a/src/fakepackets.c +++ b/src/fakepackets.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -7,6 +8,14 @@ #include "windivert.h" #include "goodbyedpi.h" +struct fake_t { + const unsigned char* data; + size_t size; +}; + +static struct fake_t *fakes[30] = {0}; +int fakes_count = 0; + static const unsigned char fake_http_request[] = "GET / HTTP/1.1\r\nHost: www.w3.org\r\n" "User-Agent: curl/7.65.3\r\nAccept: */*\r\n" "Accept-Encoding: deflate, gzip, br\r\n\r\n"; @@ -54,7 +63,8 @@ static int send_fake_data(const HANDLE w_filter, const BOOL is_https, const BYTE set_ttl, const BYTE set_checksum, - const BYTE set_seq + const BYTE set_seq, + const struct fake_t *fake_data ) { char packet_fake[MAX_PACKET_SIZE]; WINDIVERT_ADDRESS addr_new; @@ -66,6 +76,10 @@ static int send_fake_data(const HANDLE w_filter, PWINDIVERT_TCPHDR ppTcpHdr; unsigned const char *fake_request_data = is_https ? fake_https_request : fake_http_request; UINT fake_request_size = is_https ? sizeof(fake_https_request) : sizeof(fake_http_request) - 1; + if (fake_data) { + fake_request_data = fake_data->data; + fake_request_size = fake_data->size; + } memcpy(&addr_new, addr, sizeof(WINDIVERT_ADDRESS)); memcpy(packet_fake, pkt, packetLen); @@ -148,22 +162,26 @@ static int send_fake_request(const HANDLE w_filter, const BOOL is_https, const BYTE set_ttl, const BYTE set_checksum, - const BYTE set_seq + const BYTE set_seq, + const struct fake_t *fake_data ) { if (set_ttl) { send_fake_data(w_filter, addr, pkt, packetLen, is_ipv6, is_https, - set_ttl, FALSE, FALSE); + set_ttl, FALSE, FALSE, + fake_data); } if (set_checksum) { send_fake_data(w_filter, addr, pkt, packetLen, is_ipv6, is_https, - FALSE, set_checksum, FALSE); + FALSE, set_checksum, FALSE, + fake_data); } if (set_seq) { send_fake_data(w_filter, addr, pkt, packetLen, is_ipv6, is_https, - FALSE, FALSE, set_seq); + FALSE, FALSE, set_seq, + fake_data); } return 0; } @@ -177,9 +195,17 @@ int send_fake_http_request(const HANDLE w_filter, const BYTE set_checksum, const BYTE set_seq ) { - return send_fake_request(w_filter, addr, pkt, packetLen, - is_ipv6, FALSE, - set_ttl, set_checksum, set_seq); + int ret = 0; + for (int i=0; isize = size; + fake->data = data; + + for (size_t k = 0; k <= sizeof(fakes) / sizeof(*fakes); k++) { + if (!fakes[k]) { + fakes[k] = fake; + fakes_count++; + return 0; + } + } + return 3; +} + +int fake_load_from_hex(const char *data) { + size_t len = strlen(data); + if (len < 2 || len % 2 || len > 1420) + return 1; + + unsigned char *finaldata = calloc((len + 2) / 2, 1); + + for (size_t i = 0; i= '0' && curchar <= '9') + curchar -= '0'; + else if (curchar >= 'a' && curchar <= 'f') + curchar -= 'a' - 0xA; + else if (curchar >= 'A' && curchar <= 'F') + curchar -= 'A' - 0xA; + else + return 2; // incorrect character, not a hex data + + if (!j) { + num1 = curchar; + curchar = num2; + continue; + } + num2 = curchar; + } + debug("Processed num1: %X, num2: %X\n", num1, num2); + finalchar = (num1 << 4) | num2; + debug("Final char: %X\n", finalchar); + finaldata[i/2] = finalchar; + } + + return fake_add(finaldata, len / 2); } diff --git a/src/goodbyedpi.c b/src/goodbyedpi.c index 03c85be..bf43e19 100644 --- a/src/goodbyedpi.c +++ b/src/goodbyedpi.c @@ -188,6 +188,7 @@ static struct option long_options[] = { {"native-frag", no_argument, 0, '*' }, {"reverse-frag",no_argument, 0, '(' }, {"max-payload", optional_argument, 0, '|' }, + {"fake-from-hex", required_argument, 0, 'u' }, {"debug-exit", optional_argument, 0, 'x' }, {0, 0, 0, 0 } }; @@ -940,6 +941,11 @@ int main(int argc, char *argv[]) { else max_payload_size = 1200; break; + case 'u': // --fake-from-hex + if (fake_load_from_hex(optarg)) { + printf("WARNING: bad fake HEX value %s\n", optarg); + } + break; case 'x': // --debug-exit debug_exit = true; break; @@ -988,6 +994,9 @@ int main(int argc, char *argv[]) { " --reverse-frag fragment (split) the packets just as --native-frag, but send them in the\n" " reversed order. Works with the websites which could not handle segmented\n" " HTTPS TLS ClientHello (because they receive the TCP flow \"combined\").\n" + " --fake-from-hex Load fake packets for Fake Request Mode from HEX values (like 1234abcDEF).\n" + " This option can be supplied multiple times, in this case each fake packet\n" + " would be sent on every request in the command line argument order.\n" " --max-payload [value] packets with TCP payload data more than [value] won't be processed.\n" " Use this option to reduce CPU usage by skipping huge amount of data\n" " (like file transfers) in already established sessions.\n"