mirror of
https://github.com/ValdikSS/GoodbyeDPI.git
synced 2024-11-24 02:49:37 +01:00
--fake-from-hex option: load Fake Packet from HEX data
This option replaces built-in fake packets with the user-supplied ones, could be used multiple times (up to 30). Each fake packet loaded with this option is sent in command line order, every time (on each TLS ClientHello or HTTP GET/POST).
This commit is contained in:
parent
83af8cc541
commit
f0d42129aa
@ -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 <value> 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.
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#include <in6addr.h>
|
||||
@ -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,
|
||||
int ret = 0;
|
||||
for (int i=0; i<fakes_count || i == 0; i++) {
|
||||
if (send_fake_request(w_filter, addr, pkt, packetLen,
|
||||
is_ipv6, FALSE,
|
||||
set_ttl, set_checksum, set_seq);
|
||||
set_ttl, set_checksum, set_seq,
|
||||
fakes[i]))
|
||||
{
|
||||
ret++;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int send_fake_https_request(const HANDLE w_filter,
|
||||
@ -191,7 +217,70 @@ int send_fake_https_request(const HANDLE w_filter,
|
||||
const BYTE set_checksum,
|
||||
const BYTE set_seq
|
||||
) {
|
||||
return send_fake_request(w_filter, addr, pkt, packetLen,
|
||||
int ret = 0;
|
||||
for (int i=0; i<fakes_count || i == 0; i++) {
|
||||
if (send_fake_request(w_filter, addr, pkt, packetLen,
|
||||
is_ipv6, TRUE,
|
||||
set_ttl, set_checksum, set_seq);
|
||||
set_ttl, set_checksum, set_seq,
|
||||
fakes[i]))
|
||||
{
|
||||
ret++;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int fake_add(const unsigned char *data, size_t size) {
|
||||
struct fake_t *fake = malloc(sizeof(struct fake_t));
|
||||
fake->size = 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<len - 1; i+=2) {
|
||||
char num1 = data[i];
|
||||
char num2 = data[i+1];
|
||||
debug("Current num1: %X, num2: %X\n", num1, num2);
|
||||
unsigned char finalchar = 0;
|
||||
char curchar = num1;
|
||||
|
||||
for (int j=0; j<=1; j++) {
|
||||
if (curchar >= '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);
|
||||
}
|
||||
|
@ -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 <value> 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"
|
||||
|
Loading…
Reference in New Issue
Block a user