5 Commits
0.0.5 ... 0.0.7

Author SHA1 Message Date
ValdikSS
f5ac7c0d67 Change TCP Window Size based on SrcPort, not DstPort.
When HTTPS fragment size was set, the program always used it for HTTP, even
if HTTP fragmentation was disabled. This is due to a bug which checked DstPort,
not SrcPort, and the packets passed DstPort != htons(80) HTTPS check.
2017-06-11 21:50:22 +03:00
ValdikSS
2a5e4a071b Create README.md 2017-06-11 08:35:15 +03:00
Pavel Rubin
ae3abff0b2 Update README.md
Guide to install as a windows service
2017-06-04 19:22:33 +03:00
ValdikSS
d9e27f193c Reimplement -s option to fix unACKed data
Old code used to reduce packet size by one byte to remove space in
HTTP Host header. This introduces one unACKed byte which OS later
tried to send to the host. This byte was \n (the last byte in original
packet) which broke POST requests.

New code in this commit moves "stolen" space in the end of User-Agent
header value and do not reduce packet size anymore.
User-Agent value is used because not all web servers are compatible
with additional space in the end of Host value.

Fix #3
2017-05-25 00:25:21 +03:00
ValdikSS
c721ab0506 Always check for valid HTTP method before any modifications 2017-05-25 00:18:01 +03:00
2 changed files with 68 additions and 17 deletions

View File

@@ -65,6 +65,29 @@ And for x86_64:
`make CPREFIX=x86_64-w64-mingw32 WINDIVERTHEADERS=/path/to/windivert/include WINDIVERTLIBS=/path/to/windivert/amd64` `make CPREFIX=x86_64-w64-mingw32 WINDIVERTHEADERS=/path/to/windivert/include WINDIVERTLIBS=/path/to/windivert/amd64`
# How to install as Windows Service
One way is using an [srvstart](http://www.rozanski.org.uk/software) program.
Unpack it to goodbyedpi directory and create 3 files:
*goodbyedpi.ini*
```INI
[GoodByeDPI]
startup=goodbyedpi.exe
shutdown_method=winmessage
auto_restart=n
```
*srvinstall.bat*
```Batchfile
srvstart install GoodByeDPI -c %CD%\goodbyedpi-svc.ini
```
*srvremove.bat*
```Batchfile
srvstart remove GoodByeDPI
```
Run these batch files as Administrator to install/remove service.
Open Windows Services panel to run service or make it start automaticaly.
# Similar projects # Similar projects
[zapret](https://github.com/bol-van/zapret) by @bol-van (for Linux). [zapret](https://github.com/bol-van/zapret) by @bol-van (for Linux).

View File

@@ -27,6 +27,7 @@ static const char *http10_redirect_302 = "HTTP/1.0 302 ";
static const char *http11_redirect_302 = "HTTP/1.1 302 "; static const char *http11_redirect_302 = "HTTP/1.1 302 ";
static const char *http_host_find = "\r\nHost: "; static const char *http_host_find = "\r\nHost: ";
static const char *http_host_replace = "\r\nhoSt: "; static const char *http_host_replace = "\r\nhoSt: ";
static const char *http_useragent_find = "\r\nUser-Agent: ";
static const char *location_http = "\r\nLocation: http://"; static const char *location_http = "\r\nLocation: http://";
static const char *http_methods[] = { static const char *http_methods[] = {
"GET ", "GET ",
@@ -104,6 +105,12 @@ static PVOID find_host_header(const char *pktdata, int pktlen) {
http_host_find, strlen(http_host_find)); http_host_find, strlen(http_host_find));
} }
/* Finds User-Agent header with \r\n before it */
static PVOID find_useragent_header(const char *pktdata, int pktlen) {
return dumb_memmem(pktdata, pktlen,
http_useragent_find, strlen(http_useragent_find));
}
static void change_window_size(const char *pkt, int size) { static void change_window_size(const char *pkt, int size) {
*(uint16_t*)(pkt + IPV4_HDR_LEN + TCP_WINDOWSIZE_OFFSET) = htons(size); *(uint16_t*)(pkt + IPV4_HDR_LEN + TCP_WINDOWSIZE_OFFSET) = htons(size);
} }
@@ -138,8 +145,8 @@ int main(int argc, char *argv[]) {
do_host_removespace = 0, do_additional_space = 0; do_host_removespace = 0, do_additional_space = 0;
int http_fragment_size = 2; int http_fragment_size = 2;
int https_fragment_size = 2; int https_fragment_size = 2;
char *data_addr, *data_addr_rn, *host_addr, *method_addr; char *data_addr, *data_addr_rn, *host_addr, *useragent_addr, *method_addr;
int host_len, fromhost_uptoend_len; int data_len, host_len;
printf("GoodbyeDPI: Passive DPI blocker and Active DPI circumvention utility\n"); printf("GoodbyeDPI: Passive DPI blocker and Active DPI circumvention utility\n");
@@ -273,7 +280,8 @@ int main(int argc, char *argv[]) {
} }
/* Handle OUTBOUND packet, search for Host header */ /* Handle OUTBOUND packet, search for Host header */
else if (addr.Direction == WINDIVERT_DIRECTION_OUTBOUND && else if (addr.Direction == WINDIVERT_DIRECTION_OUTBOUND &&
packet_dataLen > 16 && ppTcpHdr->DstPort == htons(80) && packet_dataLen > 16 && ppTcpHdr->DstPort == htons(80) &&
find_http_method_end(packet_data) &&
(do_host || do_host_removespace)) { (do_host || do_host_removespace)) {
data_addr = find_host_header(packet_data, packet_dataLen); data_addr = find_host_header(packet_data, packet_dataLen);
@@ -297,21 +305,41 @@ int main(int argc, char *argv[]) {
else if (do_host_removespace) { else if (do_host_removespace) {
host_addr = data_addr + strlen(http_host_find); 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, data_addr_rn = dumb_memmem(host_addr,
fromhost_uptoend_len, packet_dataLen - ((PVOID)host_addr - packet_data),
"\r\n", 2); "\r\n", 2);
if (data_addr_rn) { if (data_addr_rn) {
/* We move Host header value by one byte to the left and then
* "insert" stolen space to the end of User-Agent value because
* some web servers are not tolerant to additional space in the
* end of Host header.
*
* Nothing is done if User-Agent header is missing.
*/
host_len = data_addr_rn - host_addr; host_len = data_addr_rn - host_addr;
if (host_len <= 64) { useragent_addr = find_useragent_header(packet_data, packet_dataLen);
/* Move memory left by 1 byte and reduce packet size for 1 byte */ if (host_len <= 253 && useragent_addr && useragent_addr > host_addr) {
memmove(host_addr - 1, host_addr, fromhost_uptoend_len); /* Performing action only if User-Agent header goes after Host */
/* Reduce "Total Length" in IP header by 1 byte */
*(uint16_t*)(packet + IPV4_TOTALLEN_OFFSET) = ntohs( useragent_addr += strlen(http_useragent_find);
htons(*(uint16_t*)(packet + IPV4_TOTALLEN_OFFSET)) - 1); /* useragent_addr is in the beginning of User-Agent value */
/* Reduce packetLen by 1 byte */
packetLen--; data_len = packet_dataLen - ((PVOID)useragent_addr - packet_data);
//printf("Replaced Host header!\n"); data_addr_rn = dumb_memmem(useragent_addr,
data_len, "\r\n", 2);
/* data_addr_rn is in the end of User-Agent value */
if (data_addr_rn) {
data_len = (PVOID)data_addr_rn - (PVOID)host_addr;
/* Move one byte to the left from "Host:"
* to the end of User-Agen
*/
memmove(host_addr - 1, host_addr, data_len);
/* Put space in the end of User-Agent header */
*(char*)(data_addr_rn - 1) = ' ';
//printf("Replaced Host header!\n");
}
} }
} }
} }
@@ -327,11 +355,11 @@ int main(int argc, char *argv[]) {
if (addr.Direction == WINDIVERT_DIRECTION_INBOUND && if (addr.Direction == WINDIVERT_DIRECTION_INBOUND &&
ppTcpHdr->Syn == 1) { ppTcpHdr->Syn == 1) {
//printf("Changing Window Size!\n"); //printf("Changing Window Size!\n");
if (do_fragment_http && ppTcpHdr->DstPort == htons(80)) { if (do_fragment_http && ppTcpHdr->SrcPort == htons(80)) {
change_window_size(packet, http_fragment_size); change_window_size(packet, http_fragment_size);
WinDivertHelperCalcChecksums(packet, packetLen, 0); WinDivertHelperCalcChecksums(packet, packetLen, 0);
} }
else if (do_fragment_https && ppTcpHdr->DstPort != htons(80)) { else if (do_fragment_https && ppTcpHdr->SrcPort != htons(80)) {
change_window_size(packet, https_fragment_size); change_window_size(packet, https_fragment_size);
WinDivertHelperCalcChecksums(packet, packetLen, 0); WinDivertHelperCalcChecksums(packet, packetLen, 0);
} }