2 Commits

Author SHA1 Message Date
ValdikSS
f085c06a2b test 2024-09-06 17:32:32 +03:00
EgorWeders
c5cbbb43f3 Added clang-format check action 2024-08-21 09:21:58 +07:00
9 changed files with 56 additions and 357 deletions

View File

@@ -1,17 +1,28 @@
name: The program crashes, hangs, certain function does not work / Программа падает, зависает, отдельная функция не работает
name: Bug Report / Сообщение об ошибке
description: File a bug report / Сообщить об ошибке в программе
body:
- type: markdown
attributes:
value: |
### Carefully read all the text IN FULL. Take this seriously.
### Use this form only for software bug reports! The website does not open? That's likely NOT a bug, do NOT report it here! You have a question regarding the program? That's not a bug either!
#### If in doubt, [use NTC.party forum](https://ntc.party/c/community-software/goodbyedpi).
### Внимательно прочитайте ВЕСЬ текст ниже. Отнеситесь к этому со всей ответственностью.
### Используйте эту форму только для сообщений об ошибках в программе! Неоткрывающиеся сайты таковыми не являются, вопросы по программе к ошибкам не относятся.
#### Если у вас есть сомнения, [воспользуйтесь форумом NTC.party](https://ntc.party/c/community-software/goodbyedpi).
### USE THIS FORM ONLY FOR BUGS! The webside does not open? That's likely NOT a bug, do NOT report it here!
### USE THIS FORM ONLY FOR BUGS! The webside does not open? That's likely NOT a bug, do NOT report it here!
### USE THIS FORM ONLY FOR BUGS! The webside does not open? That's likely NOT a bug, do NOT report it here!
### ИСПОЛЬЗУЙТЕ ЭТУ ФОРМУ ТОЛЬКО ДЛЯ БАГОВ! Веб-сайт не открывается? Это, скорее всего, не баг, не сообщайте сюда, ВЫ БУДЕТЕ ЗАБАНЕНЫ!
### ИСПОЛЬЗУЙТЕ ЭТУ ФОРМУ ТОЛЬКО ДЛЯ БАГОВ! Веб-сайт не открывается? Это, скорее всего, не баг, не сообщайте сюда, ВЫ БУДЕТЕ ЗАБАНЕНЫ!
### ИСПОЛЬЗУЙТЕ ЭТУ ФОРМУ ТОЛЬКО ДЛЯ БАГОВ! Веб-сайт не открывается? Это, скорее всего, не баг, не сообщайте сюда, ВЫ БУДЕТЕ ЗАБАНЕНЫ!
### ИСПОЛЬЗУЙТЕ ЭТУ ФОРМУ ТОЛЬКО ДЛЯ БАГОВ! Веб-сайт не открывается? Это, скорее всего, не баг, не сообщайте сюда, ВЫ БУДЕТЕ ЗАБАНЕНЫ!
### ИСПОЛЬЗУЙТЕ ЭТУ ФОРМУ ТОЛЬКО ДЛЯ БАГОВ! Веб-сайт не открывается? Это, скорее всего, не баг, не сообщайте сюда, ВЫ БУДЕТЕ ЗАБАНЕНЫ!
### ИСПОЛЬЗУЙТЕ ЭТУ ФОРМУ ТОЛЬКО ДЛЯ БАГОВ! Веб-сайт не открывается? Это, скорее всего, не баг, не сообщайте сюда, ВЫ БУДЕТЕ ЗАБАНЕНЫ!
### ИСПОЛЬЗУЙТЕ ЭТУ ФОРМУ ТОЛЬКО ДЛЯ БАГОВ! Веб-сайт не открывается? Это, скорее всего, не баг, не сообщайте сюда, ВЫ БУДЕТЕ ЗАБАНЕНЫ!
### ИСПОЛЬЗУЙТЕ ЭТУ ФОРМУ ТОЛЬКО ДЛЯ БАГОВ! Веб-сайт не открывается? Это, скорее всего, не баг, не сообщайте сюда, ВЫ БУДЕТЕ ЗАБАНЕНЫ!
### ИСПОЛЬЗУЙТЕ ЭТУ ФОРМУ ТОЛЬКО ДЛЯ БАГОВ! Веб-сайт не открывается? Это, скорее всего, не баг, не сообщайте сюда, ВЫ БУДЕТЕ ЗАБАНЕНЫ!
### ИСПОЛЬЗУЙТЕ ЭТУ ФОРМУ ТОЛЬКО ДЛЯ БАГОВ! Веб-сайт не открывается? Это, скорее всего, не баг, не сообщайте сюда, ВЫ БУДЕТЕ ЗАБАНЕНЫ!
### ИСПОЛЬЗУЙТЕ ЭТУ ФОРМУ ТОЛЬКО ДЛЯ БАГОВ! Веб-сайт не открывается? Это, скорее всего, не баг, не сообщайте сюда, ВЫ БУДЕТЕ ЗАБАНЕНЫ!
### ИСПОЛЬЗУЙТЕ ЭТУ ФОРМУ ТОЛЬКО ДЛЯ БАГОВ! Веб-сайт не открывается? Это, скорее всего, не баг, не сообщайте сюда, ВЫ БУДЕТЕ ЗАБАНЕНЫ!
### ИСПОЛЬЗУЙТЕ ЭТУ ФОРМУ ТОЛЬКО ДЛЯ БАГОВ! Веб-сайт не открывается? Это, скорее всего, не баг, не сообщайте сюда, ВЫ БУДЕТЕ ЗАБАНЕНЫ!
### ИСПОЛЬЗУЙТЕ ЭТУ ФОРМУ ТОЛЬКО ДЛЯ БАГОВ! Веб-сайт не открывается? Это, скорее всего, не баг, не сообщайте сюда, ВЫ БУДЕТЕ ЗАБАНЕНЫ!
GoodbyeDPI does not guarantee to work with your ISP for every blocked website or at all. If GoodbyeDPI can't unblock some or any websites, this is most likely not a software bug, and you should not report it here.
Please only report software bugs, such as:
@@ -19,8 +30,7 @@ body:
* incorrect network packet handling
* antivirus incompatibility
* DNS redirection problems
* memory leaks
* other software issues
* other software
Please make sure to check other opened and closed issues, it could be your bug has been reported already.
For questions, or if in doubt, [use NTC.party forum](https://ntc.party/c/community-software/goodbyedpi).
@@ -33,21 +43,10 @@ body:
* некорректная обработка сетевых пакетов
* несовместимость с антивирусами
* проблемы с перенаправлением DNS
* утечки памяти
* другие ошибки в программе
Также посмотрите другие открытые и закрытые баги. Возможно, ошибка уже обсуждалась или исправлена.
Для вопросов, а также в случае сомнений в определении бага, обращайтесь [на форум NTC.party](https://ntc.party/c/community-software/goodbyedpi).
- type: checkboxes
id: terms
attributes:
label: CAPTCHA
description: Confirm that you have read the text above / Подтвердите, что вы прочитали текст выше
options:
- label: I understand I could be banned from the repository if I misusing issue section not for posting bugs, but for question or 'broken website' report. / Я понимаю, что меня могут заблокировать в репозитории, если я буду использовать раздел issue не для сообщений об ошибках, а для вопросов или сообщении о «неработающем веб-сайте».
required: true
validations:
required: true
- type: input
id: os
attributes:

View File

@@ -1,13 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: The program worked yesterday but not today / Программа работала вчера, но перестала работать сегодня
url: https://ntc.party/c/community-software/goodbyedpi/8
about: Visit support community forum, people will certainly help you! / Посетите форум поддержки, где сообщество вам поможет!
- name: Сertain website is still unreachable / Отдельный веб-сайт всё ещё недоступен
url: https://ntc.party/c/community-software/goodbyedpi/8
about: That could be solved with community support! / Проблема будет решена силами сообщества!
- name: Questions about the program / Вопросы по програме
url: https://ntc.party/c/community-software/goodbyedpi/8
about: Please ask and answer questions on forum / Пожалуйста, задавайте вопросы только на форуме

View File

@@ -1,4 +1,4 @@
name: Feature request / Предложить новую функциональность
name: Feature request / Предложить новую функциональность
description: Suggest an idea or function for this project / Предложить новую идею или функциональность в программе
body:

17
.github/workflows/clang-format-check vendored Normal file
View File

@@ -0,0 +1,17 @@
name: Clang Format Checker
on:
push:
paths:
- 'src/**'
pull_request:
paths:
- 'src/**'
env:
BRANCH_NAME: master
jobs:
check-format:
runs-on: ubuntu-latest
steps:
- uses: wolletd/clang-format-checker@v1
with:
target-ref: ${{ env. BRANCH_NAME }} # required, merge target

2
.gitignore vendored
View File

@@ -1,2 +0,0 @@
*.o
*.exe

View File

@@ -19,8 +19,6 @@ If it works — congratulations! You can use it as-is or configure further.
Download [latest version from Releases page](https://github.com/ValdikSS/GoodbyeDPI/releases) and run.
## Supported arguments
To get relevant information about your version of the program, use the -h (--help) argument at startup.
```
Usage: goodbyedpi.exe [OPTION...]
-p block passive DPI
@@ -66,17 +64,6 @@ 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.
--fake-with-sni <value> Generate fake packets for Fake Request Mode with given SNI domain name.
The packets mimic Mozilla Firefox 130 TLS ClientHello packet
(with random generated fake SessionID, key shares and ECH grease).
Can be supplied multiple times for multiple fake packets.
--fake-gen <value> Generate random-filled fake packets for Fake Request Mode, value of them
(up to 30).
--fake-resend <value> Send each fake packet value number of times.
Default: 1 (send each packet once).
--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.
@@ -99,7 +86,7 @@ Modern modesets (more stable, more compatible, faster):
Note: combination of --wrong-seq and --wrong-chksum generates two different fake packets.
```
## How to check
To check if your ISP's DPI could be circumvented, first make sure that your provider does not poison DNS answers by enabling "Secure DNS (DNS over HTTPS)" option in your browser.
* **Chrome**: Settings → [Privacy and security](chrome://settings/security) → Use secure DNS → With: NextDNS
@@ -154,8 +141,7 @@ Modify them according to your own needs.
# Known issues
* Horribly outdated Windows 7 installations are not able to load WinDivert driver due to missing support for SHA256 digital signatures. Install KB3033929 [x86](https://www.microsoft.com/en-us/download/details.aspx?id=46078)/[x64](https://www.microsoft.com/en-us/download/details.aspx?id=46148), or better, update the whole system using Windows Update.
* Intel/Qualcomm Killer network cards: `Advanced Stream Detect` in Killer Control Center is incompatible with GoodbyeDPI, [disable it](https://github.com/ValdikSS/GoodbyeDPI/issues/541#issuecomment-2296038239).
* QUIK trading software [may interfere with GoodbyeDPI](https://github.com/ValdikSS/GoodbyeDPI/issues/677#issuecomment-2390595606). First start QUIK, then GoodbyeDPI.
* Intel/Qualcomm Killer network cards: `Advanced Stream Detect` in Killer Control Center is incompabitle with GoodbyeDPI, [disable it](https://github.com/ValdikSS/GoodbyeDPI/issues/541#issuecomment-2296038239).
* ~~Some SSL/TLS stacks unable to process fragmented ClientHello packets, and HTTPS websites won't open. Bug: [#4](https://github.com/ValdikSS/GoodbyeDPI/issues/4), [#64](https://github.com/ValdikSS/GoodbyeDPI/issues/64).~~ Fragmentation issues are fixed in v0.1.7.
* ~~ESET Antivirus is incompatible with WinDivert driver [#91](https://github.com/ValdikSS/GoodbyeDPI/issues/91). This is most probably antivirus bug, not WinDivert.~~
@@ -169,9 +155,8 @@ Modify them according to your own needs.
- **[PowerTunnel](https://github.com/krlvm/PowerTunnel)** by @krlvm (for Windows, MacOS and Linux)
- **[PowerTunnel for Android](https://github.com/krlvm/PowerTunnel-Android)** by @krlvm (for Android)
- **[SpoofDPI](https://github.com/xvzc/SpoofDPI)** by @xvzc (for macOS and Linux)
- **[SpoofDPI-Platform](https://github.com/r3pr3ss10n/SpoofDPI-Platform)** by @r3pr3ss10n (for Android, macOS, Windows)
- **[GhosTCP](https://github.com/macronut/ghostcp)** by @macronut (for Windows)
- **[ByeDPI](https://github.com/hufrea/byedpi)** for Linux/Windows + **[ByeDPIAndroid](https://github.com/dovecoteescapee/ByeDPIAndroid/)** / **[ByeByeDPI](https://github.com/romanvht/ByeByeDPI/)** for Android (no root)
- **[ByeDPI](https://github.com/hufrea/byedpi)** for Linux/Windows + **[ByeDPIAndroid](https://github.com/dovecoteescapee/ByeDPIAndroid/)** for Android (no root)
- **[youtubeUnblock](https://github.com/Waujito/youtubeUnblock/)** by @Waujito (for OpenWRT/Entware routers and Linux)
# Kudos

View File

@@ -1,7 +1,5 @@
#include <stdio.h>
#define _CRT_RAND_S
#include <stdlib.h>
#include <stdbool.h>
#include <ctype.h>
#include <unistd.h>
#include <in6addr.h>
@@ -9,15 +7,6 @@
#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;
int fakes_resend = 1;
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";
@@ -57,91 +46,6 @@ static const unsigned char fake_https_request[] = {
0x00, 0x00, 0x00, 0x00, 0x00
};
// Captured from Firefox 130.0.1
static const unsigned char fake_clienthello_part0[] = { // 116 bytes
// TLS 1.2 ClientHello header (DD for length placeholder)
0x16, 0x03, 0x01, 0xDD, 0xDD, 0x01, 0x00, 0xDD, 0xDD, 0x03, 0x03,
// Random bytes (AA for placeholder)
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
// Random Session ID
0x20,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
// Cipher Suites
0x00, 0x22, 0x13, 0x01, 0x13, 0x03, 0x13, 0x02, 0xC0, 0x2B, 0xC0, 0x2F, 0xCC, 0xA9, 0xCC, 0xA8,
0xC0, 0x2C, 0xC0, 0x30, 0xC0, 0x0A, 0xC0, 0x09, 0xC0, 0x13, 0xC0, 0x14, 0x00, 0x9C, 0x00, 0x9D,
0x00, 0x2F, 0x00, 0x35,
// Compression Methods
0x01, 0x00,
// Extensions Length
0xDD, 0xDD,
};
// SNI: 00 00 L1 L1 L2 L2 00 L3 L3 (sni)
// L1 = L+5, L2 = L+3, L3 = L // 9 + L bytes
static const unsigned char fake_clienthello_part1[] = { // 523 bytes
// extended_master_secret
0x00, 0x17, 0x00, 0x00,
// renegotiation_info
0xFF, 0x01, 0x00, 0x01, 0x00,
// supported_groups
0x00, 0x0A, 0x00, 0x0E,
0x00, 0x0C, 0x00, 0x1D, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x01, 0x00, 0x01, 0x01,
// ex_point_formats
0x00, 0x0B, 0x00, 0x02, 0x01, 0x00,
// session_ticket
0x00, 0x23, 0x00, 0x00,
// ALPN
0x00, 0x10, 0x00, 0x0E,
0x00, 0x0C, 0x02, 0x68, 0x32, 0x08, 0x68, 0x74, 0x74, 0x70, 0x2F, 0x31, 0x2E, 0x31,
// status_request
0x00, 0x05, 0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00,
// delegated_credentials
0x00, 0x22, 0x00, 0x0A, 0x00, 0x08, 0x04, 0x03, 0x05, 0x03, 0x06, 0x03, 0x02, 0x03,
// key_share
0x00, 0x33, 0x00, 0x6B, 0x00, 0x69, 0x00, 0x1D, 0x00, 0x20,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0x00, 0x17, 0x00, 0x41, 0x04,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
// supported_versions
0x00, 0x2B, 0x00, 0x05, 0x04, 0x03, 0x04, 0x03, 0x03,
// signature_algorithms
0x00, 0x0D, 0x00, 0x18, 0x00, 0x16, 0x04, 0x03, 0x05, 0x03, 0x06, 0x03, 0x08, 0x04, 0x08, 0x05,
0x08, 0x06, 0x04, 0x01, 0x05, 0x01, 0x06, 0x01, 0x02, 0x03, 0x02, 0x01,
// psk_key_exchange_modes
0x00, 0x2D, 0x00, 0x02, 0x01, 0x01,
// record_size_limit
0x00, 0x1C, 0x00, 0x02, 0x40, 0x01,
// encrypted_client_hello
0xFE, 0x0D, 0x01, 0x19, 0x00, 0x00, 0x01, 0x00, 0x01, 0xAA, 0x00, 0x20,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0x00, 0xEF,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA
};
// JA4: t13d1715h2_5b57614c22b0_5c2c66f702b0
// JA4_r: t13d1715h2_002f,0035,009c,009d,1301,1302,1303,c009,c00a,c013,c014,c02b,c02c,c02f,c030,cca8,cca9_0005,000a,000b,000d,0017,001c,0022,0023,002b,002d,0033,fe0d,ff01_0403,0503,0603,0804,0805,0806,0401,0501,0601,0203,0201
// JA3 Fullstring: 771,4865-4867-4866-49195-49199-52393-52392-49196-49200-49162-49161-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-34-51-43-13-45-28-65037,29-23-24-25-256-257,0
// JA3: b5001237acdf006056b409cc433726b0
static int send_fake_data(const HANDLE w_filter,
const PWINDIVERT_ADDRESS addr,
const char *pkt,
@@ -150,8 +54,7 @@ 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 struct fake_t *fake_data
const BYTE set_seq
) {
char packet_fake[MAX_PACKET_SIZE];
WINDIVERT_ADDRESS addr_new;
@@ -163,10 +66,6 @@ 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);
@@ -249,26 +148,22 @@ 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 struct fake_t *fake_data
const BYTE set_seq
) {
if (set_ttl) {
send_fake_data(w_filter, addr, pkt, packetLen,
is_ipv6, is_https,
set_ttl, FALSE, FALSE,
fake_data);
set_ttl, FALSE, FALSE);
}
if (set_checksum) {
send_fake_data(w_filter, addr, pkt, packetLen,
is_ipv6, is_https,
FALSE, set_checksum, FALSE,
fake_data);
FALSE, set_checksum, FALSE);
}
if (set_seq) {
send_fake_data(w_filter, addr, pkt, packetLen,
is_ipv6, is_https,
FALSE, FALSE, set_seq,
fake_data);
FALSE, FALSE, set_seq);
}
return 0;
}
@@ -282,18 +177,9 @@ int send_fake_http_request(const HANDLE w_filter,
const BYTE set_checksum,
const BYTE set_seq
) {
int ret = 0;
for (int i=0; i<fakes_count || i == 0; i++) {
for (int j=0; j<fakes_resend; j++)
if (send_fake_request(w_filter, addr, pkt, packetLen,
is_ipv6, FALSE,
set_ttl, set_checksum, set_seq,
fakes[i]))
{
ret++;
}
}
return ret;
return send_fake_request(w_filter, addr, pkt, packetLen,
is_ipv6, FALSE,
set_ttl, set_checksum, set_seq);
}
int send_fake_https_request(const HANDLE w_filter,
@@ -305,137 +191,7 @@ int send_fake_https_request(const HANDLE w_filter,
const BYTE set_checksum,
const BYTE set_seq
) {
int ret = 0;
for (int i=0; i<fakes_count || i == 0; i++) {
for (int j=0; j<fakes_resend; j++)
if (send_fake_request(w_filter, addr, pkt, packetLen,
return send_fake_request(w_filter, addr, pkt, packetLen,
is_ipv6, TRUE,
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 * 2))
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);
}
int fake_load_random(unsigned int count, unsigned int maxsize) {
if (count < 1 || count > sizeof(fakes) / sizeof(*fakes))
return 1;
unsigned int random = 0;
for (unsigned int i=0; i<count; i++) {
unsigned int len = 0;
if (rand_s(&len))
return 1;
len = 8 + (len % maxsize);
unsigned char *data = calloc(len, 1);
for (unsigned int j=0; j<len; j++) {
rand_s(&random);
data[j] = random % 0xFF;
}
if (fake_add(data, len))
return 2;
}
return 0;
}
void set_uint16be(unsigned char *buffer, int offset, int value) {
buffer[offset] = (value >> 8) & 0xFF;
buffer[offset + 1] = value & 0xFF;
}
int fake_load_from_sni(const char *domain_name) {
if (!domain_name) {
return 1; // just extra safeguard against NPE
}
// calculate sizes
const int name_size = strlen(domain_name);
const int part0_size = sizeof(fake_clienthello_part0);
const int part1_size = sizeof(fake_clienthello_part1);
const int sni_head_size = 9;
const int packet_size = part0_size + part1_size + sni_head_size + name_size;
// allocate memory
unsigned char *packet = malloc(packet_size);
// copy major parts of packet
memcpy(packet, fake_clienthello_part0, part0_size);
memcpy(&packet[part0_size + sni_head_size + name_size], fake_clienthello_part1, part1_size);
// replace placeholders with random generated values
unsigned int random = 0;
for (int i = 0; i < packet_size; i++) {
if (packet[i] == 0xAA) {
rand_s(&random);
packet[i] = random & 0xFF;
}
}
// write size fields into packet
set_uint16be(packet, 0x0003, packet_size - 5);
set_uint16be(packet, 0x0007, packet_size - 9);
set_uint16be(packet, 0x0072, packet_size - 116);
// write SNI extension
set_uint16be(packet, part0_size + 0, 0x0000);
set_uint16be(packet, part0_size + 2, name_size + 5);
set_uint16be(packet, part0_size + 4, name_size + 3);
packet[part0_size + 6] = 0x00;
set_uint16be(packet, part0_size + 7, name_size);
memcpy(&packet[part0_size + sni_head_size], domain_name, name_size);
// add packet to fakes
return fake_add(packet, packet_size);
set_ttl, set_checksum, set_seq);
}

View File

@@ -1,5 +1,3 @@
extern int fakes_count;
extern int fakes_resend;
int send_fake_http_request(const HANDLE w_filter,
const PWINDIVERT_ADDRESS addr,
const char *pkt,
@@ -18,6 +16,3 @@ int send_fake_https_request(const HANDLE w_filter,
const BYTE set_checksum,
const BYTE set_seq
);
int fake_load_from_hex(const char *data);
int fake_load_from_sni(const char *domain_name);
int fake_load_random(unsigned int count, unsigned int maxsize);

View File

@@ -1,7 +1,7 @@
/*
* GoodbyeDPI — Passive DPI blocker and Active DPI circumvention utility.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
@@ -24,7 +24,7 @@
// My mingw installation does not load inet_pton definition for some reason
WINSOCK_API_LINKAGE INT WSAAPI inet_pton(INT Family, LPCSTR pStringBuf, PVOID pAddr);
#define GOODBYEDPI_VERSION "v0.2.3rc3"
#define GOODBYEDPI_VERSION "v0.2.3"
#define die() do { sleep(20); exit(EXIT_FAILURE); } while (0)
@@ -188,10 +188,6 @@ 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' },
{"fake-with-sni", required_argument, 0, '}' },
{"fake-gen", required_argument, 0, 'j' },
{"fake-resend", required_argument, 0, 't' },
{"debug-exit", optional_argument, 0, 'x' },
{0, 0, 0, 0 }
};
@@ -327,7 +323,7 @@ static HANDLE init(char *filter, UINT64 flags) {
"Please unload it with the following commands ran as administrator:\n\n"
"sc stop windivert\n"
"sc delete windivert\n"
"sc stop windivert14\n"
"sc stop windivert14"
"sc delete windivert14\n");
else if (errorcode == 1275)
printf("This error occurs for various reasons, including:\n"
@@ -944,30 +940,6 @@ 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 '}': // --fake-with-sni
if (fake_load_from_sni(optarg)) {
printf("WARNING: bad domain name for SNI: %s\n", optarg);
}
break;
case 'j': // --fake-gen
if (fake_load_random(atoub(optarg, "Fake generator parameter error!"), 200)) {
puts("WARNING: fake generator has failed!");
}
break;
case 't': // --fake-resend
fakes_resend = atoub(optarg, "Fake resend parameter error!");
if (fakes_resend == 1)
puts("WARNING: fake-resend is 1, no resending is in place!");
else if (!fakes_resend)
puts("WARNING: fake-resend is 0, fake packet mode is disabled!");
else if (fakes_resend > 100)
puts("WARNING: fake-resend value is a little too high, don't you think?");
break;
case 'x': // --debug-exit
debug_exit = true;
break;
@@ -1016,17 +988,6 @@ 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"
" --fake-with-sni <value> Generate fake packets for Fake Request Mode with given SNI domain name.\n"
" The packets mimic Mozilla Firefox 130 TLS ClientHello packet\n"
" (with random generated fake SessionID, key shares and ECH grease).\n"
" Can be supplied multiple times for multiple fake packets.\n"
" --fake-gen <value> Generate random-filled fake packets for Fake Request Mode, value of them\n"
" (up to 30).\n"
" --fake-resend <value> Send each fake packet value number of times.\n"
" Default: 1 (send each packet once).\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"
@@ -1086,9 +1047,7 @@ int main(int argc, char *argv[]) {
"Fake requests, TTL: %s (fixed: %hu, auto: %hu-%hu-%hu, min distance: %hu)\n" /* 17 */
"Fake requests, wrong checksum: %d\n" /* 18 */
"Fake requests, wrong SEQ/ACK: %d\n" /* 19 */
"Fake requests, custom payloads: %d\n" /* 20 */
"Fake requests, resend: %d\n" /* 21 */
"Max payload size: %hu\n", /* 22 */
"Max payload size: %hu\n", /* 20 */
do_passivedpi, do_block_quic, /* 1 */
(do_fragment_http ? http_fragment_size : 0), /* 2 */
(do_fragment_http_persistent ? http_fragment_size : 0),/* 3 */
@@ -1110,9 +1069,7 @@ int main(int argc, char *argv[]) {
do_auto_ttl ? auto_ttl_max : 0, ttl_min_nhops,
do_wrong_chksum, /* 18 */
do_wrong_seq, /* 19 */
fakes_count, /* 20 */
fakes_resend, /* 21 */
max_payload_size /* 22 */
max_payload_size /* 20 */
);
if (do_fragment_http && http_fragment_size > 2 && !do_native_frag) {