From 95102904d98e8ffdc0f9822e23e13fa8d0d5b555 Mon Sep 17 00:00:00 2001 From: moreweb <82875181+iWebbIO@users.noreply.github.com> Date: Fri, 26 Jun 2026 16:47:03 +0330 Subject: [PATCH 1/6] Update main.py --- main.py | 69 +++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 60 insertions(+), 9 deletions(-) diff --git a/main.py b/main.py index 3170b25..8f19484 100644 --- a/main.py +++ b/main.py @@ -51,21 +51,25 @@ async def relay_main_loop(sock_1: socket.socket, sock_2: socket.socket, peer_tas try: data = await loop.sock_recv(sock_1, 65575) if not data: - raise ValueError("eof") + break if first_prefix_data: data = first_prefix_data + data first_prefix_data = b"" - sent_len = await loop.sock_sendall(sock_2, data) - if sent_len != len(data): - raise ValueError("incomplete send") - except Exception: - sock_1.close() - sock_2.close() - peer_task.cancel() - return + await loop.sock_sendall(sock_2, data) + except (ConnectionResetError, OSError, asyncio.CancelledError): + break except Exception: traceback.print_exc() sys.exit("relay main loop error!") + finally: + if peer_task and not peer_task.done(): + for sock in (sock_1, sock_2): + try: + sock.shutdown(socket.SHUT_RDWR) + except OSError: + pass + sock_1.close() + sock_2.close() async def handle(incoming_sock: socket.socket, incoming_remote_addr): @@ -215,7 +219,54 @@ async def main(): asyncio.create_task(handle(incoming_sock, addr)) +def select_network_interface() -> str: + ips = [] + try: + hostname = socket.gethostname() + for ip in socket.gethostbyname_ex(hostname)[2]: + if ip not in ips: + ips.append(ip) + except Exception: + pass + + try: + for info in socket.getaddrinfo(socket.gethostname(), None, socket.AF_INET): + ip = info[4][0] + if ip not in ips: + ips.append(ip) + except Exception: + pass + + if "127.0.0.1" not in ips: + ips.append("127.0.0.1") + + try: + default_ip = get_default_interface_ipv4(CONNECT_IP) + if default_ip and default_ip not in ips: + ips.append(default_ip) + except Exception: + pass + + print("Available network interfaces:") + for idx, ip in enumerate(ips, 1): + print(f"{idx}. {ip}") + + while True: + try: + choice = input(f"Select network interface (1-{len(ips)}): ").strip() + choice_idx = int(choice) - 1 + if 0 <= choice_idx < len(ips): + selected_ip = ips[choice_idx] + print(f"Using network interface: {selected_ip}") + return selected_ip + else: + print(f"Invalid selection. Please enter a number between 1 and {len(ips)}.") + except ValueError: + print("Invalid input. Please enter a valid number.") + + if __name__ == "__main__": + INTERFACE_IPV4 = select_network_interface() w_filter = "tcp and " + "(" + "(ip.SrcAddr == " + INTERFACE_IPV4 + " and ip.DstAddr == " + CONNECT_IP + ")" + " or " + "(ip.SrcAddr == " + CONNECT_IP + " and ip.DstAddr == " + INTERFACE_IPV4 + ")" + ")" fake_tcp_injector = FakeTcpInjector(w_filter, fake_injective_connections) threading.Thread(target=fake_tcp_injector.run, args=(), daemon=True).start() From 0108353ed06dc55359166be8003b061864fde019 Mon Sep 17 00:00:00 2001 From: moreweb <82875181+iWebbIO@users.noreply.github.com> Date: Fri, 26 Jun 2026 16:54:12 +0330 Subject: [PATCH 2/6] Update config.json --- config.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config.json b/config.json index 189ba03..ed8701e 100644 --- a/config.json +++ b/config.json @@ -1,7 +1,7 @@ { "LISTEN_HOST": "0.0.0.0", "LISTEN_PORT": 40443, - "CONNECT_IP": "188.114.98.0", + "CONNECT_IP": "188.114.99.0", "CONNECT_PORT": 443, - "FAKE_SNI": "auth.vercel.com" + "FAKE_SNI": "chatgpt.com" } \ No newline at end of file From 3c7be7dcd06f381412db9511bc738aba025ee57d Mon Sep 17 00:00:00 2001 From: moreweb <82875181+iWebbIO@users.noreply.github.com> Date: Sat, 27 Jun 2026 07:20:05 +0330 Subject: [PATCH 3/6] Update main.py --- main.py | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index 8f19484..2945d07 100644 --- a/main.py +++ b/main.py @@ -5,6 +5,7 @@ import traceback import threading import json +import ctypes # from utils.proxy_protocols import parse_vless_protocol from utils.network_tools import get_default_interface_ipv4 @@ -219,6 +220,47 @@ async def main(): asyncio.create_task(handle(incoming_sock, addr)) +def is_admin() -> bool: + if os.name == 'nt': + try: + return ctypes.windll.shell32.IsUserAnAdmin() != 0 + except Exception: + return False + else: + try: + return os.getuid() == 0 + except AttributeError: + return False + + +def run_as_admin(): + if os.name == 'nt': + try: + if getattr(sys, 'frozen', False): + # Executable mode + ret = ctypes.windll.shell32.ShellExecuteW( + None, "runas", sys.executable, " ".join(sys.argv[1:]), None, 1 + ) + else: + # Script mode + script = sys.argv[0] + params = f'"{script}" ' + " ".join([f'"{arg}"' for arg in sys.argv[1:]]) + ret = ctypes.windll.shell32.ShellExecuteW( + None, "runas", sys.executable, params, None, 1 + ) + if int(ret) <= 32: + print("Administrator privileges were denied. Exiting.") + sys.exit(1) + else: + sys.exit(0) + except Exception as e: + print(f"Failed to elevate privileges: {e}") + sys.exit(1) + else: + print("Please run this script as root/administrator.") + sys.exit(1) + + def select_network_interface() -> str: ips = [] try: @@ -240,6 +282,7 @@ def select_network_interface() -> str: if "127.0.0.1" not in ips: ips.append("127.0.0.1") + default_ip = "" try: default_ip = get_default_interface_ipv4(CONNECT_IP) if default_ip and default_ip not in ips: @@ -249,11 +292,20 @@ def select_network_interface() -> str: print("Available network interfaces:") for idx, ip in enumerate(ips, 1): - print(f"{idx}. {ip}") + suffix = " (Default)" if ip == default_ip else "" + print(f"{idx}. {ip}{suffix}") + default_prompt = f" [Default: {default_ip}]" if default_ip else "" while True: try: - choice = input(f"Select network interface (1-{len(ips)}): ").strip() + choice = input(f"Select network interface (1-{len(ips)}){default_prompt}: ").strip() + if not choice: + if default_ip: + print(f"Using default network interface: {default_ip}") + return default_ip + else: + print("No default interface available. Please make a selection.") + continue choice_idx = int(choice) - 1 if 0 <= choice_idx < len(ips): selected_ip = ips[choice_idx] @@ -266,6 +318,10 @@ def select_network_interface() -> str: if __name__ == "__main__": + if not is_admin(): + print("This application requires administrator privileges. Attempting to elevate...") + run_as_admin() + INTERFACE_IPV4 = select_network_interface() w_filter = "tcp and " + "(" + "(ip.SrcAddr == " + INTERFACE_IPV4 + " and ip.DstAddr == " + CONNECT_IP + ")" + " or " + "(ip.SrcAddr == " + CONNECT_IP + " and ip.DstAddr == " + INTERFACE_IPV4 + ")" + ")" fake_tcp_injector = FakeTcpInjector(w_filter, fake_injective_connections) From f019473e2f4816fdd0b67d8ab6e4c6260ae58bdf Mon Sep 17 00:00:00 2001 From: moreweb <82875181+iWebbIO@users.noreply.github.com> Date: Sat, 27 Jun 2026 20:05:32 +0330 Subject: [PATCH 4/6] Update main.py --- main.py | 237 ++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 203 insertions(+), 34 deletions(-) diff --git a/main.py b/main.py index 2945d07..eb3f66f 100644 --- a/main.py +++ b/main.py @@ -6,6 +6,8 @@ import threading import json import ctypes +import subprocess +import time # from utils.proxy_protocols import parse_vless_protocol from utils.network_tools import get_default_interface_ipv4 @@ -261,71 +263,238 @@ def run_as_admin(): sys.exit(1) -def select_network_interface() -> str: - ips = [] +def get_adapters(): + # Returns a list of dictionaries: [{'IPAddress': '...', 'InterfaceAlias': '...'}] + cmd = ["powershell", "-Command", "Get-NetIPAddress -AddressFamily IPv4 | Select-Object IPAddress, InterfaceAlias | ConvertTo-Json"] try: - hostname = socket.gethostname() - for ip in socket.gethostbyname_ex(hostname)[2]: - if ip not in ips: - ips.append(ip) + res = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, check=True) + if res.stdout.strip(): + data = json.loads(res.stdout) + if isinstance(data, dict): + return [data] + return data except Exception: pass + return [] + +def get_real_default_interface(connect_ip="8.8.8.8") -> tuple[str, str]: + # Returns (InterfaceAlias, IPAddress) + adapters = get_adapters() + ip_to_name = {a['IPAddress']: a['InterfaceAlias'] for a in adapters if 'IPAddress' in a and 'InterfaceAlias' in a} + name_to_ips = {} + for a in adapters: + if 'IPAddress' in a and 'InterfaceAlias' in a: + name_to_ips.setdefault(a['InterfaceAlias'], []).append(a['IPAddress']) + + def is_proxy_tun(name: str) -> bool: + name_lower = name.lower() + return any(x in name_lower for x in ["xray", "sing", "wintun", "tun", "tap", "loopback", "pseudo"]) + + routes = [] + cmd = ["powershell", "-Command", "Get-NetRoute -DestinationPrefix '0.0.0.0/0' | Select-Object NextHop, InterfaceAlias, RouteMetric | ConvertTo-Json"] try: - for info in socket.getaddrinfo(socket.gethostname(), None, socket.AF_INET): - ip = info[4][0] - if ip not in ips: - ips.append(ip) + res = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, check=True) + if res.stdout.strip(): + routes_data = json.loads(res.stdout) + if isinstance(routes_data, dict): + routes = [routes_data] + elif isinstance(routes_data, list): + routes = routes_data except Exception: pass - if "127.0.0.1" not in ips: - ips.append("127.0.0.1") + physical_routes = [] + for r in routes: + name = r.get('InterfaceAlias', '') + if name and not is_proxy_tun(name): + physical_routes.append(r) + + if physical_routes: + physical_routes.sort(key=lambda x: x.get('RouteMetric', 9999)) + best_name = physical_routes[0]['InterfaceAlias'] + ips = name_to_ips.get(best_name, []) + for ip in ips: + if not ip.startswith("169.254") and not ip.startswith("127."): + return best_name, ip + + for name, ips in name_to_ips.items(): + if not is_proxy_tun(name): + for ip in ips: + if not ip.startswith("169.254") and not ip.startswith("127."): + return name, ip - default_ip = "" try: - default_ip = get_default_interface_ipv4(CONNECT_IP) - if default_ip and default_ip not in ips: - ips.append(default_ip) + default_ip = get_default_interface_ipv4(connect_ip) + if default_ip: + name = ip_to_name.get(default_ip, "Unknown") + return name, default_ip except Exception: pass - print("Available network interfaces:") - for idx, ip in enumerate(ips, 1): - suffix = " (Default)" if ip == default_ip else "" - print(f"{idx}. {ip}{suffix}") + return "Unknown", "" + + +def select_network_interface() -> tuple[str, str]: + adapters = get_adapters() + adapter_ips = {} + for a in adapters: + name = a.get('InterfaceAlias') + ip = a.get('IPAddress') + if name and ip: + adapter_ips.setdefault(name, []).append(ip) + + # Fallback if powershell command returned nothing (e.g. not on Windows) + if not adapter_ips: + try: + hostname = socket.gethostname() + ips = socket.gethostbyname_ex(hostname)[2] + adapter_ips['Default Adapter'] = ips + except Exception: + pass + + if 'Loopback Pseudo-Interface 1' not in adapter_ips and 'Loopback' not in adapter_ips: + for name in list(adapter_ips.keys()): + if 'loopback' in name.lower() or 'pseudo' in name.lower(): + break + else: + adapter_ips['Loopback Pseudo-Interface 1'] = ['127.0.0.1'] + + default_name, default_ip = get_real_default_interface(CONNECT_IP) - default_prompt = f" [Default: {default_ip}]" if default_ip else "" + print("Available network interfaces:") + names_list = list(adapter_ips.keys()) + for idx, name in enumerate(names_list, 1): + ips = adapter_ips[name] + ip_str = ", ".join(ips) + is_default = " (Default)" if name == default_name else "" + print(f"{idx}. {name}: {ip_str}{is_default}") + + default_prompt = f" [Default: {default_name}]" if default_name else "" while True: try: - choice = input(f"Select network interface (1-{len(ips)}){default_prompt}: ").strip() + choice = input(f"Select network interface (1-{len(names_list)}){default_prompt}: ").strip() if not choice: - if default_ip: - print(f"Using default network interface: {default_ip}") - return default_ip + if default_name: + for ip in adapter_ips.get(default_name, []): + if not ip.startswith("169.254"): + print(f"Using default network interface: {default_name} ({ip})") + return default_name, ip + ip = adapter_ips.get(default_name, [""])[0] + print(f"Using default network interface: {default_name} ({ip})") + return default_name, ip else: print("No default interface available. Please make a selection.") continue choice_idx = int(choice) - 1 - if 0 <= choice_idx < len(ips): - selected_ip = ips[choice_idx] - print(f"Using network interface: {selected_ip}") - return selected_ip + if 0 <= choice_idx < len(names_list): + selected_name = names_list[choice_idx] + ips = adapter_ips[selected_name] + selected_ip = "" + for ip in ips: + if not ip.startswith("169.254"): + selected_ip = ip + break + if not selected_ip and ips: + selected_ip = ips[0] + print(f"Using network interface: {selected_name} ({selected_ip})") + return selected_name, selected_ip else: - print(f"Invalid selection. Please enter a number between 1 and {len(ips)}.") + print(f"Invalid selection. Please enter a number between 1 and {len(names_list)}.") except ValueError: print("Invalid input. Please enter a valid number.") +fake_tcp_injector = None +injector_thread = None + + +def run_injector_safe(w_filter, connections): + global fake_tcp_injector + try: + fake_tcp_injector = FakeTcpInjector(w_filter, connections) + fake_tcp_injector.run() + except Exception as e: + print(f"\n[Info] Injector stopped: {e}") + + +def stop_injector(): + global fake_tcp_injector + if fake_tcp_injector: + try: + fake_tcp_injector.w.close() + except Exception: + pass + fake_tcp_injector = None + + +def start_injector(ip: str): + global fake_tcp_injector, injector_thread + w_filter = "tcp and " + "(" + "(ip.SrcAddr == " + ip + " and ip.DstAddr == " + CONNECT_IP + ")" + " or " + "(ip.SrcAddr == " + CONNECT_IP + " and ip.DstAddr == " + ip + ")" + ")" + print(f"\n[Info] Starting Fake TCP Injector with filter: {w_filter}") + injector_thread = threading.Thread( + target=run_injector_safe, + args=(w_filter, fake_injective_connections), + daemon=True + ) + injector_thread.start() + + +def monitor_adapter_loop(adapter_name: str, initial_ip: str): + global INTERFACE_IPV4 + last_ip = initial_ip + + if last_ip: + start_injector(last_ip) + else: + print(f"\n[Warning] Adapter '{adapter_name}' is currently disconnected. Waiting for it to connect...") + + while True: + time.sleep(2) + current_ip = "" + try: + adapters = get_adapters() + for a in adapters: + if a.get('InterfaceAlias') == adapter_name: + ip = a.get('IPAddress') + if ip and not ip.startswith("169.254"): + current_ip = ip + break + except Exception: + pass + + if last_ip and not current_ip: + print(f"\n[Warning] Adapter '{adapter_name}' disconnected! Pausing tunnel...") + stop_injector() + last_ip = "" + INTERFACE_IPV4 = "" + + elif current_ip and current_ip != last_ip: + if not last_ip: + print(f"\n[Info] Adapter '{adapter_name}' connected (IP: {current_ip}). Resuming tunnel...") + else: + print(f"\n[Info] Adapter '{adapter_name}' IP changed from {last_ip} to {current_ip}. Rebinding tunnel...") + stop_injector() + + INTERFACE_IPV4 = current_ip + last_ip = current_ip + start_injector(current_ip) + + if __name__ == "__main__": if not is_admin(): print("This application requires administrator privileges. Attempting to elevate...") run_as_admin() - INTERFACE_IPV4 = select_network_interface() - w_filter = "tcp and " + "(" + "(ip.SrcAddr == " + INTERFACE_IPV4 + " and ip.DstAddr == " + CONNECT_IP + ")" + " or " + "(ip.SrcAddr == " + CONNECT_IP + " and ip.DstAddr == " + INTERFACE_IPV4 + ")" + ")" - fake_tcp_injector = FakeTcpInjector(w_filter, fake_injective_connections) - threading.Thread(target=fake_tcp_injector.run, args=(), daemon=True).start() + INTERFACE_NAME, INTERFACE_IPV4 = select_network_interface() + + # Start the adapter monitoring and rebinding loop in a daemon thread + threading.Thread( + target=monitor_adapter_loop, + args=(INTERFACE_NAME, INTERFACE_IPV4), + daemon=True + ).start() + print("هشن شومافر تیامح دینکیم هدافتسا دازآ تنرتنیا هب یسرتسد یارب همانرب نیا زا رگا") print( "دراد امش تیامح هب زاین هک مراد رظن رد دازآ تنرتنیا هب ناریا مدرم مامت یسرتسد یارب یدایز یاه همانرب و اه هژورپ") From 3d291bb7826a0d73562cae291422401033c63cba Mon Sep 17 00:00:00 2001 From: moreweb <82875181+iWebbIO@users.noreply.github.com> Date: Sun, 28 Jun 2026 14:06:31 +0330 Subject: [PATCH 5/6] . --- fake_tcp.py | 4 +- main.py | 164 ++++++++++++++++++++++++++++++++++------------------ 2 files changed, 111 insertions(+), 57 deletions(-) diff --git a/fake_tcp.py b/fake_tcp.py index 8baf26c..01f3af5 100644 --- a/fake_tcp.py +++ b/fake_tcp.py @@ -3,6 +3,7 @@ import sys import threading import time +from concurrent.futures import ThreadPoolExecutor from pydivert import Packet @@ -29,6 +30,7 @@ class FakeTcpInjector(TcpInjector): def __init__(self, w_filter: str, connections: dict[tuple, FakeInjectiveConnection]): super().__init__(w_filter) self.connections = connections + self.executor = ThreadPoolExecutor(max_workers=64) def fake_send_thread(self, packet: Packet, connection: FakeInjectiveConnection): time.sleep(0.001) @@ -143,7 +145,7 @@ def on_outbound_packet(self, packet: Packet, connection: FakeInjectiveConnection self.w.send(packet, False) connection.sch_fake_sent = True - threading.Thread(target=self.fake_send_thread, args=(packet, connection), daemon=True).start() + self.executor.submit(self.fake_send_thread, packet, connection) return self.on_unexpected_packet(packet, connection, "unexpected outbound packet") return diff --git a/main.py b/main.py index eb3f66f..1facb38 100644 --- a/main.py +++ b/main.py @@ -25,19 +25,55 @@ def get_exe_dir(): return os.path.dirname(os.path.abspath(__file__)) -# Build the path to config.json +# Load or create the config config_path = os.path.join(get_exe_dir(), 'config.json') +if not os.path.exists(config_path): + default_config = { + "LISTEN_HOST": "0.0.0.0", + "LISTEN_PORT": 40443, + "CONNECT_IP": "188.114.99.0", + "CONNECT_PORT": 443, + "FAKE_SNI": "chatgpt.com" + } + try: + with open(config_path, 'w') as f: + json.dump(default_config, f, indent=2) + print(f"[Info] Created default config.json at {config_path}") + config = default_config + except Exception as e: + print(f"[Warning] Could not write default config.json: {e}") + config = default_config +else: + try: + with open(config_path, 'r') as f: + config = json.load(f) + except Exception as e: + print(f"[Error] Failed to read config.json: {e}. Using default configuration.") + config = { + "LISTEN_HOST": "0.0.0.0", + "LISTEN_PORT": 40443, + "CONNECT_IP": "188.114.99.0", + "CONNECT_PORT": 443, + "FAKE_SNI": "chatgpt.com" + } + +LISTEN_HOST = config.get("LISTEN_HOST", "0.0.0.0") +LISTEN_PORT = config.get("LISTEN_PORT", 40443) +FAKE_SNI = config.get("FAKE_SNI", "chatgpt.com").encode() +CONNECT_IP = config.get("CONNECT_IP", "188.114.99.0") +CONNECT_PORT = config.get("CONNECT_PORT", 443) +INTERFACE_IPV4 = get_default_interface_ipv4(CONNECT_IP) -# Load the config -with open(config_path, 'r') as f: - config = json.load(f) -LISTEN_HOST = config["LISTEN_HOST"] -LISTEN_PORT = config["LISTEN_PORT"] -FAKE_SNI = config["FAKE_SNI"].encode() -CONNECT_IP = config["CONNECT_IP"] -CONNECT_PORT = config["CONNECT_PORT"] -INTERFACE_IPV4 = get_default_interface_ipv4(CONNECT_IP) +def check_windivert_binaries(): + """Helper to check if WinDivert binaries are present in script or workdir.""" + if os.name == 'nt': + exe_dir = get_exe_dir() + wd_files = ["WinDivert.dll", "WinDivert64.sys"] + missing = [f for f in wd_files if not os.path.exists(os.path.join(exe_dir, f)) and not os.path.exists(os.path.join(os.getcwd(), f))] + if missing: + print(f"[Note] WinDivert binaries ({', '.join(missing)}) were not found in the application directory.") + print(" If the application fails to start packet capture, please download WinDivert and place them here.") DATA_MODE = "tls" BYPASS_METHOD = "wrong_seq" @@ -76,6 +112,8 @@ async def relay_main_loop(sock_1: socket.socket, sock_2: socket.socket, peer_tas async def handle(incoming_sock: socket.socket, incoming_remote_addr): + conn_id = f"{incoming_remote_addr[0]}:{incoming_remote_addr[1]}" + print(f"[+] Client connected: {conn_id}") try: loop = asyncio.get_running_loop() # try: @@ -119,14 +157,14 @@ async def handle(incoming_sock: socket.socket, incoming_remote_addr): # else: # print(data) # sys.exit("impossible address type!") - + # try: # fake_sni_host, data_mode, bypass_method = UUID_FAKE_MAP[uuid_bytes] # except KeyError: # print("unmatched uuid", uuid_bytes) # incoming_sock.close() # return - + # if data_mode == "http": # ... if DATA_MODE == "tls": @@ -147,58 +185,41 @@ async def handle(incoming_sock: socket.socket, incoming_remote_addr): BYPASS_METHOD, incoming_sock) fake_injective_connections[fake_injective_conn.id] = fake_injective_conn try: - await loop.sock_connect(outgoing_sock, (CONNECT_IP, CONNECT_PORT)) - except Exception: - fake_injective_conn.monitor = False - del fake_injective_connections[fake_injective_conn.id] - outgoing_sock.close() - incoming_sock.close() - return - - # if bypass_method == "wrong_checksum": - # ... - - if BYPASS_METHOD == "wrong_seq": try: - await asyncio.wait_for(fake_injective_conn.t2a_event.wait(), 2) - if fake_injective_conn.t2a_msg == "unexpected_close": - raise ValueError("unexpected close") - if fake_injective_conn.t2a_msg == "fake_data_ack_recv": - pass - else: - sys.exit("impossible t2a msg!") + await loop.sock_connect(outgoing_sock, (CONNECT_IP, CONNECT_PORT)) except Exception: - fake_injective_conn.monitor = False - del fake_injective_connections[fake_injective_conn.id] outgoing_sock.close() incoming_sock.close() return - else: - sys.exit("unknown bypass method!") - - fake_injective_conn.monitor = False - del fake_injective_connections[fake_injective_conn.id] - - # early_data = data[payload_index:] - # if early_data: - # try: - # sent_len = await loop.sock_sendall(outgoing_sock, early_data) - # if sent_len != len(early_data): - # raise ValueError("incomplete send") - # except Exception: - # outgoing_sock.close() - # incoming_sock.close() - # return + + if BYPASS_METHOD == "wrong_seq": + try: + await asyncio.wait_for(fake_injective_conn.t2a_event.wait(), 2) + if fake_injective_conn.t2a_msg == "unexpected_close": + raise ValueError("unexpected close") + if fake_injective_conn.t2a_msg == "fake_data_ack_recv": + pass + else: + sys.exit("impossible t2a msg!") + except Exception: + outgoing_sock.close() + incoming_sock.close() + return + else: + sys.exit("unknown bypass method!") + finally: + fake_injective_conn.monitor = False + fake_injective_connections.pop(fake_injective_conn.id, None) oti_task = asyncio.create_task( relay_main_loop(outgoing_sock, incoming_sock, asyncio.current_task(), b"")) # bytes([version, 0]) await relay_main_loop(incoming_sock, outgoing_sock, oti_task, b"") - - - + except Exception: traceback.print_exc() sys.exit("handle should not raise exception") + finally: + print(f"[-] Client disconnected: {conn_id}") async def main(): @@ -362,13 +383,30 @@ def select_network_interface() -> tuple[str, str]: default_name, default_ip = get_real_default_interface(CONNECT_IP) - print("Available network interfaces:") + def is_proxy_tun(n: str) -> bool: + n_lower = n.lower() + return any(x in n_lower for x in ["xray", "sing", "wintun", "tun", "tap", "loopback", "pseudo"]) + + print("\n==================================================") + print("Available Network Interfaces:") names_list = list(adapter_ips.keys()) for idx, name in enumerate(names_list, 1): ips = adapter_ips[name] ip_str = ", ".join(ips) is_default = " (Default)" if name == default_name else "" - print(f"{idx}. {name}: {ip_str}{is_default}") + + # Determine label type + if name == default_name: + label = "[Physical/Active Default]" + elif "loopback" in name.lower() or "pseudo" in name.lower(): + label = "[Loopback]" + elif is_proxy_tun(name): + label = "[TUN/VPN/Virtual]" + else: + label = "[Other/LAN]" + + print(f" {idx}. {name:<30} -> {ip_str:<20} {label}{is_default}") + print("==================================================\n") default_prompt = f" [Default: {default_name}]" if default_name else "" while True: @@ -430,7 +468,12 @@ def stop_injector(): def start_injector(ip: str): global fake_tcp_injector, injector_thread - w_filter = "tcp and " + "(" + "(ip.SrcAddr == " + ip + " and ip.DstAddr == " + CONNECT_IP + ")" + " or " + "(ip.SrcAddr == " + CONNECT_IP + " and ip.DstAddr == " + ip + ")" + ")" + w_filter = ( + "tcp and " + f"((ip.SrcAddr == {ip} and ip.DstAddr == {CONNECT_IP} and tcp.DstPort == {CONNECT_PORT}) or " + f"(ip.SrcAddr == {CONNECT_IP} and ip.DstAddr == {ip} and tcp.SrcPort == {CONNECT_PORT})) and " + "(tcp.Syn or tcp.Rst or tcp.Fin or tcp.PayloadLength == 0)" + ) print(f"\n[Info] Starting Fake TCP Injector with filter: {w_filter}") injector_thread = threading.Thread( target=run_injector_safe, @@ -486,6 +529,8 @@ def monitor_adapter_loop(adapter_name: str, initial_ip: str): print("This application requires administrator privileges. Attempting to elevate...") run_as_admin() + check_windivert_binaries() + INTERFACE_NAME, INTERFACE_IPV4 = select_network_interface() # Start the adapter monitoring and rebinding loop in a daemon thread @@ -501,4 +546,11 @@ def monitor_adapter_loop(adapter_name: str, initial_ip: str): print("\n") print("USDT (BEP20): 0x76a768B53Ca77B43086946315f0BDF21156bF424\n") print("@patterniha") - asyncio.run(main()) + + try: + asyncio.run(main()) + except KeyboardInterrupt: + print("\n[Info] KeyboardInterrupt received. Stopping services gracefully...") + stop_injector() + print("[Info] Goodbye!") + sys.exit(0) From 2b7044aa7ea1434e9efa67ac9cb01934bb080ae2 Mon Sep 17 00:00:00 2001 From: moreweb <82875181+iWebbIO@users.noreply.github.com> Date: Mon, 6 Jul 2026 08:22:36 +0000 Subject: [PATCH 6/6] Update .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index b7faf40..f25dd42 100644 --- a/.gitignore +++ b/.gitignore @@ -205,3 +205,4 @@ cython_debug/ marimo/_static/ marimo/_lsp/ __marimo__/ +*.lnk