Skip to content

Commit f0d4212

Browse files
committed
--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).
1 parent 83af8cc commit f0d4212

File tree

3 files changed

+111
-10
lines changed

3 files changed

+111
-10
lines changed

README.md

+3
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ Usage: goodbyedpi.exe [OPTION...]
6464
--reverse-frag fragment (split) the packets just as --native-frag, but send them in the
6565
reversed order. Works with the websites which could not handle segmented
6666
HTTPS TLS ClientHello (because they receive the TCP flow "combined").
67+
--fake-from-hex <value> Load fake packets for Fake Request Mode from HEX values (like 1234abcDEF).
68+
This option can be supplied multiple times, in this case each fake packet
69+
would be sent on every request in the command line argument order.
6770
--max-payload [value] packets with TCP payload data more than [value] won't be processed.
6871
Use this option to reduce CPU usage by skipping huge amount of data
6972
(like file transfers) in already established sessions.

src/fakepackets.c

+99-10
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,21 @@
11
#include <stdio.h>
22
#include <stdlib.h>
3+
#include <stdbool.h>
34
#include <ctype.h>
45
#include <unistd.h>
56
#include <in6addr.h>
67
#include <ws2tcpip.h>
78
#include "windivert.h"
89
#include "goodbyedpi.h"
910

11+
struct fake_t {
12+
const unsigned char* data;
13+
size_t size;
14+
};
15+
16+
static struct fake_t *fakes[30] = {0};
17+
int fakes_count = 0;
18+
1019
static const unsigned char fake_http_request[] = "GET / HTTP/1.1\r\nHost: www.w3.org\r\n"
1120
"User-Agent: curl/7.65.3\r\nAccept: */*\r\n"
1221
"Accept-Encoding: deflate, gzip, br\r\n\r\n";
@@ -54,7 +63,8 @@ static int send_fake_data(const HANDLE w_filter,
5463
const BOOL is_https,
5564
const BYTE set_ttl,
5665
const BYTE set_checksum,
57-
const BYTE set_seq
66+
const BYTE set_seq,
67+
const struct fake_t *fake_data
5868
) {
5969
char packet_fake[MAX_PACKET_SIZE];
6070
WINDIVERT_ADDRESS addr_new;
@@ -66,6 +76,10 @@ static int send_fake_data(const HANDLE w_filter,
6676
PWINDIVERT_TCPHDR ppTcpHdr;
6777
unsigned const char *fake_request_data = is_https ? fake_https_request : fake_http_request;
6878
UINT fake_request_size = is_https ? sizeof(fake_https_request) : sizeof(fake_http_request) - 1;
79+
if (fake_data) {
80+
fake_request_data = fake_data->data;
81+
fake_request_size = fake_data->size;
82+
}
6983

7084
memcpy(&addr_new, addr, sizeof(WINDIVERT_ADDRESS));
7185
memcpy(packet_fake, pkt, packetLen);
@@ -148,22 +162,26 @@ static int send_fake_request(const HANDLE w_filter,
148162
const BOOL is_https,
149163
const BYTE set_ttl,
150164
const BYTE set_checksum,
151-
const BYTE set_seq
165+
const BYTE set_seq,
166+
const struct fake_t *fake_data
152167
) {
153168
if (set_ttl) {
154169
send_fake_data(w_filter, addr, pkt, packetLen,
155170
is_ipv6, is_https,
156-
set_ttl, FALSE, FALSE);
171+
set_ttl, FALSE, FALSE,
172+
fake_data);
157173
}
158174
if (set_checksum) {
159175
send_fake_data(w_filter, addr, pkt, packetLen,
160176
is_ipv6, is_https,
161-
FALSE, set_checksum, FALSE);
177+
FALSE, set_checksum, FALSE,
178+
fake_data);
162179
}
163180
if (set_seq) {
164181
send_fake_data(w_filter, addr, pkt, packetLen,
165182
is_ipv6, is_https,
166-
FALSE, FALSE, set_seq);
183+
FALSE, FALSE, set_seq,
184+
fake_data);
167185
}
168186
return 0;
169187
}
@@ -177,9 +195,17 @@ int send_fake_http_request(const HANDLE w_filter,
177195
const BYTE set_checksum,
178196
const BYTE set_seq
179197
) {
180-
return send_fake_request(w_filter, addr, pkt, packetLen,
181-
is_ipv6, FALSE,
182-
set_ttl, set_checksum, set_seq);
198+
int ret = 0;
199+
for (int i=0; i<fakes_count || i == 0; i++) {
200+
if (send_fake_request(w_filter, addr, pkt, packetLen,
201+
is_ipv6, FALSE,
202+
set_ttl, set_checksum, set_seq,
203+
fakes[i]))
204+
{
205+
ret++;
206+
}
207+
}
208+
return ret;
183209
}
184210

185211
int send_fake_https_request(const HANDLE w_filter,
@@ -191,7 +217,70 @@ int send_fake_https_request(const HANDLE w_filter,
191217
const BYTE set_checksum,
192218
const BYTE set_seq
193219
) {
194-
return send_fake_request(w_filter, addr, pkt, packetLen,
220+
int ret = 0;
221+
for (int i=0; i<fakes_count || i == 0; i++) {
222+
if (send_fake_request(w_filter, addr, pkt, packetLen,
195223
is_ipv6, TRUE,
196-
set_ttl, set_checksum, set_seq);
224+
set_ttl, set_checksum, set_seq,
225+
fakes[i]))
226+
{
227+
ret++;
228+
}
229+
}
230+
return ret;
231+
}
232+
233+
static int fake_add(const unsigned char *data, size_t size) {
234+
struct fake_t *fake = malloc(sizeof(struct fake_t));
235+
fake->size = size;
236+
fake->data = data;
237+
238+
for (size_t k = 0; k <= sizeof(fakes) / sizeof(*fakes); k++) {
239+
if (!fakes[k]) {
240+
fakes[k] = fake;
241+
fakes_count++;
242+
return 0;
243+
}
244+
}
245+
return 3;
246+
}
247+
248+
int fake_load_from_hex(const char *data) {
249+
size_t len = strlen(data);
250+
if (len < 2 || len % 2 || len > 1420)
251+
return 1;
252+
253+
unsigned char *finaldata = calloc((len + 2) / 2, 1);
254+
255+
for (size_t i = 0; i<len - 1; i+=2) {
256+
char num1 = data[i];
257+
char num2 = data[i+1];
258+
debug("Current num1: %X, num2: %X\n", num1, num2);
259+
unsigned char finalchar = 0;
260+
char curchar = num1;
261+
262+
for (int j=0; j<=1; j++) {
263+
if (curchar >= '0' && curchar <= '9')
264+
curchar -= '0';
265+
else if (curchar >= 'a' && curchar <= 'f')
266+
curchar -= 'a' - 0xA;
267+
else if (curchar >= 'A' && curchar <= 'F')
268+
curchar -= 'A' - 0xA;
269+
else
270+
return 2; // incorrect character, not a hex data
271+
272+
if (!j) {
273+
num1 = curchar;
274+
curchar = num2;
275+
continue;
276+
}
277+
num2 = curchar;
278+
}
279+
debug("Processed num1: %X, num2: %X\n", num1, num2);
280+
finalchar = (num1 << 4) | num2;
281+
debug("Final char: %X\n", finalchar);
282+
finaldata[i/2] = finalchar;
283+
}
284+
285+
return fake_add(finaldata, len / 2);
197286
}

src/goodbyedpi.c

+9
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ static struct option long_options[] = {
188188
{"native-frag", no_argument, 0, '*' },
189189
{"reverse-frag",no_argument, 0, '(' },
190190
{"max-payload", optional_argument, 0, '|' },
191+
{"fake-from-hex", required_argument, 0, 'u' },
191192
{"debug-exit", optional_argument, 0, 'x' },
192193
{0, 0, 0, 0 }
193194
};
@@ -940,6 +941,11 @@ int main(int argc, char *argv[]) {
940941
else
941942
max_payload_size = 1200;
942943
break;
944+
case 'u': // --fake-from-hex
945+
if (fake_load_from_hex(optarg)) {
946+
printf("WARNING: bad fake HEX value %s\n", optarg);
947+
}
948+
break;
943949
case 'x': // --debug-exit
944950
debug_exit = true;
945951
break;
@@ -988,6 +994,9 @@ int main(int argc, char *argv[]) {
988994
" --reverse-frag fragment (split) the packets just as --native-frag, but send them in the\n"
989995
" reversed order. Works with the websites which could not handle segmented\n"
990996
" HTTPS TLS ClientHello (because they receive the TCP flow \"combined\").\n"
997+
" --fake-from-hex <value> Load fake packets for Fake Request Mode from HEX values (like 1234abcDEF).\n"
998+
" This option can be supplied multiple times, in this case each fake packet\n"
999+
" would be sent on every request in the command line argument order.\n"
9911000
" --max-payload [value] packets with TCP payload data more than [value] won't be processed.\n"
9921001
" Use this option to reduce CPU usage by skipping huge amount of data\n"
9931002
" (like file transfers) in already established sessions.\n"

0 commit comments

Comments
 (0)