# 🕵️ Make Every App on Your Windows PC Anonymous Through Tor — One Click, No VPN, No Setup, Completely Free

**URL:** <https://onehack.st/t/make-every-app-on-your-windows-pc-anonymous-through-tor-one-click-no-vpn-no-setup-completely-free/324036>\
**Category:** Tutorials & Methods\
**Tags:** privacy, freebies, tips-tricks, windows\
**Created:** [July 20, 2026, 12:02pm UTC](https://onehack.st/t/make-every-app-on-your-windows-pc-anonymous-through-tor-one-click-no-vpn-no-setup-completely-free/324036 "2026-07-20T12:02:51Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Edgar](https://onehack.st/user_avatar/onehack.st/edgar/32/167100_2.png) [@Edgar](https://onehack.st/u/Edgar)\
**Post date:** [July 20, 2026, 12:02pm UTC](https://onehack.st/t/make-every-app-on-your-windows-pc-anonymous-through-tor-one-click-no-vpn-no-setup-completely-free/324036/1 "2026-07-20T12:02:51Z")

</div>

## 🔒 Hide your real IP in every Windows app at once — free tool routes browsers, messengers, and games through Tor

 ![image](https://onehack.st/uploads/default/original/3X/8/5/85a4396d3ba825f69349142ee631c1fd8a67d0e7.png)

Route **any Windows app** through Tor — system-wide or app-by-app, one click.  
Scans the Tor Browser SOCKS5 port automatically. No config files. No manual setup.

 ![image](https://onehack.st/uploads/default/original/3X/0/b/0bef9dc5355f5a08afcbf1184cdbaf254ab96707.png)

░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

> **🔍 How it works**
>
> Install Tor Browser normally. Run this tool. It handles the rest:
> 
> **1 — Port scan**  
> Finds Tor Browser’s active SOCKS5 port by scanning the process PID. If that fails, brute-forces ports 9000–9500 with an actual SOCKS5 handshake (`\x05\x01\x00`) to verify — not just a TCP ping.
> 
> **2 — System-wide mode**  
> Writes `socks5=127.0.0.1:PORT` directly into the Windows Registry (`HKCU\...\Internet Settings`), then calls `InternetSetOptionW` to refresh WinInet instantly — no restart required. One click to enable, one click to revert.
> 
> **3 — Per-app mode** _(Ctrl+click or Shift+click to select multiple)_
> 
> - **Chrome / Brave / Chromium** → relaunches with `--proxy-server=socks5://127.0.0.1:PORT` and opens `check.torproject.org` to confirm
> - **Firefox** → creates an isolated temp profile with `-no-remote`, routes via env proxy vars
> - **Everything else** (Telegram, Discord, etc.) → use system-wide mode, then open the app
> 
> ⚠ **Known limit:** Chrome/Telegram per-app routing can fail on some setups — enable system-wide mode before launching those if that happens. Will be fixed in a future update. Exit country switching is also coming.
> 
> → **For Telegram, Discord, games:** these apps bypass WinInet entirely. The packet-level fix is [Netch](https://github.com/netchx/netch) — it routes by PID using [WinDivert](https://github.com/basil00/WinDivert) at the kernel packet layer, no system-wide proxy needed.
> 
> ⚠ **Warning:** Don’t enable system-wide mode on a machine with sensitive data — some apps bypass SOCKS or leak DNS. Use it on a clean/throwaway session.

> **💻 The code**
>
> ```python
> import sys
> import os
> import subprocess
> import socket
> import threading
> import time
> import re
> import psutil
> import winreg
> import ctypes
> from PyQt5.QtWidgets import *
> from PyQt5.QtCore import *
> from PyQt5.QtGui import QFont
> 
> class TorPortScanner:
> def __init__ (self):
> self.found_ports = []
> self.active_port = None
> 
> def find_tor_process_ports(self):
> ports = []
> try:
> tor_pids = []
> for proc in psutil.process_iter(['pid', 'name', 'cmdline']):
> try:
> name = proc.info['name'].lower() if proc.info['name'] else ''
> cmdline = ' '.join(proc.info['cmdline'] or []).lower()
> if ('tor' in name or 'firefox' in name) and ('tor' in cmdline or 'browser' in cmdline or 'firefox' in name.lower()):
> tor_pids.append(proc.info['pid'])
> print(f"[DEBUG] Found Tor process: PID={proc.info['pid']}, name={name}")
> except:
> continue
> if not tor_pids:
> for proc in psutil.process_iter(['pid', 'name']):
> try:
> tor_pids.append(proc.info['pid'])
> except:
> continue
> for pid in tor_pids:
> if sys.platform == "win32":
> cmd = f"netstat -ano | findstr {pid}"
> try:
> output = subprocess.check_output(cmd, shell=True, text=True)
> for line in output.splitlines():
> if "LISTENING" in line or "LISTEN" in line:
> match = re.search(r":(\d{4,5})", line)
> if match:
> port = int(match.group(1))
> if 9000 <= port <= 9500:
> ports.append(port)
> print(f"[DEBUG] Found port {port} via PID {pid}")
> except:
> pass
> except Exception as e:
> print(f"[DEBUG] Process search error: {e}")
> return list(set(ports))
> 
> def brute_force_scan(self):
> found = []
> print("[DEBUG] Starting brute force scan...")
> for port in range(9000, 9501):
> try:
> sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
> sock.settimeout(0.1)
> result = sock.connect_ex(('127.0.0.1', port))
> if result == 0:
> try:
> sock.send(b'\x05\x01\x00')
> data = sock.recv(2)
> if data and data[0] == 0x05:
> found.append(port)
> print(f"[DEBUG] Found SOCKS5 port: {port}")
> except:
> pass
> sock.close()
> except:
> continue
> return found
> 
> def test_socks_proxy(self, port, timeout=3):
> try:
> sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
> sock.settimeout(timeout)
> result = sock.connect_ex(('127.0.0.1', port))
> if result == 0:
> sock.send(b'\x05\x01\x00')
> data = sock.recv(2)
> sock.close()
> if data and data[0] == 0x05:
> return True
> sock.close()
> except Exception as e:
> print(f"[DEBUG] Error checking port {port}: {e}")
> return False
> 
> def full_scan(self, progress_callback=None):
> self.found_ports = []
> if progress_callback:
> progress_callback("Searching for Tor process...")
> ports_from_process = self.find_tor_process_ports()
> if ports_from_process:
> self.found_ports.extend(ports_from_process)
> if progress_callback:
> progress_callback(f"Found via process: {ports_from_process}")
> if not self.found_ports:
> if progress_callback:
> progress_callback("Extended port scanning (9000-9500)...")
> ports_from_bruteforce = self.brute_force_scan()
> if ports_from_bruteforce:
> self.found_ports.extend(ports_from_bruteforce)
> if progress_callback:
> progress_callback(f"Found via brute force: {ports_from_bruteforce}")
> self.found_ports = list(set(self.found_ports))
> valid_ports = []
> if self.found_ports:
> if progress_callback:
> progress_callback(f"Checking {len(self.found_ports)} ports for SOCKS5...")
> for i, p in enumerate(self.found_ports):
> if progress_callback:
> progress_callback(f"Checking port {p} ({i+1}/{len(self.found_ports)})...")
> if self.test_socks_proxy(p):
> valid_ports.append(p)
> if progress_callback:
> progress_callback(f"Port {p} ✓ WORKING (SOCKS5)")
> else:
> if progress_callback:
> progress_callback(f"Port {p} ✗ Not responding to SOCKS5")
> self.found_ports = valid_ports
> return self.found_ports
> 
> class TorStarter(QThread):
> log_signal = pyqtSignal(str)
> finished_signal = pyqtSignal(bool)
> 
> def __init__ (self, scanner=None):
> super(). __init__ ()
> self.scanner = scanner
> 
> def run(self):
> paths = []
> if sys.platform == "win32":
> user = os.getlogin()
> paths = [
> r"C:\Program Files\Tor Browser\Browser\firefox.exe",
> rf"C:\Users\{user}\Desktop\Tor Browser\Browser\firefox.exe",
> rf"C:\Users\{user}\Downloads\Tor Browser\Browser\firefox.exe"
> ]
> elif sys.platform == "darwin":
> paths = ["/Applications/Tor Browser.app/Contents/MacOS/firefox"]
> else:
> paths = ["/usr/bin/tor", "/usr/local/bin/tor"]
> for path in paths:
> if os.path.exists(path):
> try:
> self.log_signal.emit(f"Starting Tor: {path}")
> if sys.platform == "win32":
> subprocess.Popen([path], shell=True)
> else:
> subprocess.Popen([path], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
> self.log_signal.emit("Waiting for Tor to start (up to 30 seconds)...")
> for i in range(30):
> time.sleep(1)
> self.log_signal.emit(f"Waiting {i+1}/30 sec...")
> if self.scanner:
> ports = self.scanner.full_scan()
> if ports:
> self.log_signal.emit(f"Tor started! Found ports: {ports}")
> self.finished_signal.emit(True)
> return
> self.log_signal.emit("Tor started, but ports not found. Try manual scan.")
> self.finished_signal.emit(True)
> return
> except Exception as e:
> self.log_signal.emit(f"Start error: {e}")
> continue
> self.log_signal.emit("Tor Browser not found. Please install it.")
> self.finished_signal.emit(False)
> 
> class ProcessUpdater(QThread):
> processes_signal = pyqtSignal(list)
> 
> def run(self):
> while True:
> processes = []
> try:
> for proc in psutil.process_iter(['pid', 'name', 'exe']):
> try:
> name = proc.info['name'] or "Unknown"
> exe = proc.info['exe'] or ""
> if exe and not exe.lower().endswith('.exe'):
> continue
> if name.lower() in ['system', 'idle']:
> continue
> processes.append({'pid': proc.info['pid'], 'name': name, 'exe': exe})
> except:
> continue
> processes.sort(key=lambda x: x['name'].lower())
> self.processes_signal.emit(processes)
> except:
> pass
> time.sleep(5)
> 
> class TorAppSelector(QMainWindow):
> def __init__ (self):
> super(). __init__ ()
> self.scanner = TorPortScanner()
> self.selected_port = None
> self.processes = []
> self.selected_processes = []
> self.system_proxy_active = False
> self.scanning_in_progress = False
> self.updating_processes = False
> self.initUI()
> self.update_status("Waiting...")
> self.process_updater = ProcessUpdater()
> self.process_updater.processes_signal.connect(self.update_process_list)
> self.process_updater.start()
> 
> def initUI(self):
> self.setWindowTitle("Tor App Selector v6.3")
> self.setGeometry(200, 200, 900, 700)
> self.setStyleSheet("""
> QMainWindow { background-color: #1e1e2e; }
> QLabel { color: #cdd6f4; font-size: 13px; font-weight: bold; }
> QPushButton { 
> background-color: #313244; color: #cdd6f4; 
> border: 1px solid #45475a; padding: 8px 15px; 
> border-radius: 6px; font-weight: bold;
> }
> QPushButton:hover { background-color: #45475a; }
> QPushButton#launch_btn {
> background-color: #a6e3a1; color: #1e1e2e; 
> font-size: 14px; padding: 12px;
> }
> QPushButton#launch_btn:hover { background-color: #89d48a; }
> QPushButton#proxy_btn_on {
> background-color: #f9e2af; color: #1e1e2e;
> }
> QPushButton#proxy_btn_on:hover { background-color: #f2d08a; }
> QPushButton#proxy_btn_off {
> background-color: #f38ba8; color: #1e1e2e;
> }
> QPushButton#proxy_btn_off:hover { background-color: #e06b87; }
> QListWidget { 
> background-color: #181825; color: #cdd6f4; 
> border: 1px solid #45475a; border-radius: 4px;
> font-family: 'Courier New'; font-size: 12px;
> }
> QListWidget::item:selected { 
> background-color: #45475a; color: #a6e3a1;
> }
> QTextEdit { 
> background-color: #11111b; color: #89b4fa; 
> border: 1px solid #45475a; border-radius: 4px;
> font-family: 'Courier New';
> }
> QStatusBar { color: #a6e3a1; }
> QProgressBar {
> background-color: #181825;
> border: 1px solid #45475a;
> border-radius: 4px;
> color: #cdd6f4;
> text-align: center;
> }
> QProgressBar::chunk {
> background-color: #89b4fa;
> border-radius: 4px;
> }
> """)
> central = QWidget()
> self.setCentralWidget(central)
> layout = QVBoxLayout(central)
> title = QLabel("Tor App Selector v6.3")
> title.setFont(QFont("Arial", 14, QFont.Bold))
> title.setStyleSheet("color: #89b4fa; padding: 10px;")
> layout.addWidget(title)
> top_layout = QHBoxLayout()
> self.scan_btn = QPushButton("Scan Tor Ports")
> self.scan_btn.clicked.connect(self.start_scan)
> self.start_tor_btn = QPushButton("Start Tor")
> self.start_tor_btn.clicked.connect(self.launch_tor_with_scan)
> self.proxy_btn = QPushButton("Enable System Proxy")
> self.proxy_btn.setObjectName("proxy_btn_off")
> self.proxy_btn.clicked.connect(self.toggle_system_proxy)
> top_layout.addWidget(self.scan_btn)
> top_layout.addWidget(self.start_tor_btn)
> top_layout.addWidget(self.proxy_btn)
> top_layout.addStretch()
> layout.addLayout(top_layout)
> self.progress_bar = QProgressBar()
> self.progress_bar.setVisible(False)
> layout.addWidget(self.progress_bar)
> info_label = QLabel("Select multiple apps: Ctrl+click or Shift+click")
> info_label.setStyleSheet("color: #a6e3a1; font-size: 11px;")
> layout.addWidget(info_label)
> layout.addWidget(QLabel("Available Tor Ports (select one):"))
> self.port_list = QListWidget()
> self.port_list.setMaximumHeight(80)
> self.port_list.itemClicked.connect(self.on_port_selected)
> layout.addWidget(self.port_list)
> layout.addWidget(QLabel("Running Applications (select one or more):"))
> self.process_list = QListWidget()
> self.process_list.setSelectionMode(QListWidget.ExtendedSelection)
> self.process_list.setMaximumHeight(350)
> self.process_list.itemClicked.connect(self.on_process_selected)
> layout.addWidget(self.process_list)
> self.launch_btn = QPushButton("LAUNCH SELECTED APPS VIA TOR")
> self.launch_btn.setObjectName("launch_btn")
> self.launch_btn.clicked.connect(self.launch_selected_apps)
> layout.addWidget(self.launch_btn)
> layout.addWidget(QLabel("Log:"))
> self.log_area = QTextEdit()
> self.log_area.setMaximumHeight(120)
> self.log_area.setReadOnly(True)
> layout.addWidget(self.log_area)
> self.statusBar = QStatusBar()
> self.setStatusBar(self.statusBar)
> 
> def update_status(self, text):
> self.statusBar.showMessage(text)
> 
> def log(self, text):
> self.log_area.append(f"[{time.strftime('%H:%M:%S')}] {text}")
> 
> def update_process_list(self, processes):
> if self.updating_processes:
> return
> self.updating_processes = True
> selected_pids = []
> for item in self.process_list.selectedItems():
> pid_match = re.search(r"PID:\s*(\d+)", item.text())
> if pid_match:
> selected_pids.append(int(pid_match.group(1)))
> self.process_list.clear()
> self.processes = processes
> unique_names = {}
> for proc in processes:
> name = proc['name']
> exe = proc['exe']
> pid = proc['pid']
> skip_names = ['svchost.exe', 'csrss.exe', 'wininit.exe', 'lsass.exe',
> 'winlogon.exe', 'services.exe', 'smss.exe', 'spoolsv.exe',
> 'conhost.exe', 'dwm.exe', 'taskhostw.exe', 'explorer.exe',
> 'python.exe', 'pythonw.exe', 'cmd.exe', 'powershell.exe']
> if name.lower() in skip_names:
> continue
> if name in unique_names:
> unique_names[name] += 1
> display_name = f"{name} (PID: {pid})"
> else:
> unique_names[name] = 1
> display_name = f"{name} (PID: {pid})"
> if 'chrome' in name.lower() or 'firefox' in name.lower() or 'brave' in name.lower():
> display_name = "[Browser] " + display_name
> elif 'telegram' in name.lower():
> display_name = "[Messenger] " + display_name
> elif 'discord' in name.lower():
> display_name = "[Game] " + display_name
> self.process_list.addItem(display_name)
> for i in range(self.process_list.count()):
> item = self.process_list.item(i)
> pid_match = re.search(r"PID:\s*(\d+)", item.text())
> if pid_match:
> pid = int(pid_match.group(1))
> if pid in selected_pids:
> item.setSelected(True)
> self.updating_processes = False
> 
> def on_process_selected(self, item):
> self.selected_processes = []
> for i in range(self.process_list.count()):
> if self.process_list.item(i).isSelected():
> item_text = self.process_list.item(i).text()
> pid_match = re.search(r"PID:\s*(\d+)", item_text)
> if pid_match:
> pid = int(pid_match.group(1))
> for proc in self.processes:
> if proc['pid'] == pid:
> self.selected_processes.append(proc)
> break
> if self.selected_processes:
> names = ", ".join([p['name'] for p in self.selected_processes])
> self.log(f"Selected apps: {len(self.selected_processes)} ({names})")
> 
> def start_scan(self):
> if self.scanning_in_progress:
> return
> self.log("Starting Tor port scan...")
> self.port_list.clear()
> self.update_status("Scanning...")
> self.scanning_in_progress = True
> self.progress_bar.setVisible(True)
> self.progress_bar.setRange(0, 0)
> self.scan_btn.setEnabled(False)
> 
> def update_progress(text):
> self.log(text)
> QApplication.processEvents()
> 
> def scan_thread():
> try:
> ports = self.scanner.full_scan(progress_callback=update_progress)
> self.update_ports_signal.emit(ports)
> except Exception as e:
> self.log(f"Scan error: {e}")
> self.update_ports_signal.emit([])
> 
> class UpdateSignal(QObject):
> update_signal = pyqtSignal(list)
> 
> self.update_signal = UpdateSignal()
> self.update_signal.update_signal.connect(self.update_port_list)
> self.update_ports_signal = self.update_signal.update_signal
> threading.Thread(target=scan_thread, daemon=True).start()
> 
> def update_port_list(self, ports):
> self.port_list.clear()
> if ports:
> for p in ports:
> self.port_list.addItem(f"Port {p} (SOCKS5) ✓")
> self.log(f"✅ Active ports found: {len(ports)}")
> self.update_status(f"✅ Found: {len(ports)} ports")
> self.selected_port = ports[0]
> self.port_list.setCurrentRow(0)
> self.log(f"Auto-selected port: {self.selected_port}")
> else:
> self.port_list.addItem("No active ports found")
> self.log("❌ Ports not found. Start Tor Browser and try again.")
> self.update_status("❌ No ports")
> self.selected_port = None
> self.scanning_in_progress = False
> self.progress_bar.setVisible(False)
> self.scan_btn.setEnabled(True)
> 
> def launch_tor_with_scan(self):
> self.log("Starting Tor Browser...")
> self.scan_btn.setEnabled(False)
> self.start_tor_btn.setEnabled(False)
> self.tor_thread = TorStarter(self.scanner)
> self.tor_thread.log_signal.connect(self.log)
> self.tor_thread.finished_signal.connect(self.on_tor_started)
> self.tor_thread.start()
> self.update_status("Starting Tor...")
> 
> def on_tor_started(self, success):
> self.scan_btn.setEnabled(True)
> self.start_tor_btn.setEnabled(True)
> if success:
> self.log("Tor Browser started, running scan...")
> time.sleep(2)
> self.start_scan()
> else:
> self.log("❌ Failed to start Tor Browser. Check installation.")
> self.update_status("❌ Tor not started")
> 
> def on_port_selected(self, item):
> match = re.search(r"\d+", item.text())
> if match:
> self.selected_port = int(match.group())
> self.log(f"Selected port: {self.selected_port}")
> 
> def toggle_system_proxy(self):
> if not self.selected_port:
> self.log("❌ Select a Tor port first!")
> QMessageBox.warning(self, "Error", "Select a Tor port!")
> return
> if self.system_proxy_active:
> self.disable_system_proxy()
> else:
> self.enable_system_proxy()
> 
> def enable_system_proxy(self):
> try:
> key = winreg.OpenKey(
> winreg.HKEY_CURRENT_USER,
> r"Software\Microsoft\Windows\CurrentVersion\Internet Settings",
> 0, winreg.KEY_SET_VALUE
> )
> winreg.SetValueEx(key, "ProxyEnable", 0, winreg.REG_DWORD, 1)
> winreg.SetValueEx(key, "ProxyServer", 0, winreg.REG_SZ, f"socks5=127.0.0.1:{self.selected_port}")
> winreg.SetValueEx(key, "ProxyOverride", 0, winreg.REG_SZ, "localhost;127.0.0.1;::1")
> winreg.CloseKey(key)
> ctypes.windll.wininet.InternetSetOptionW(0, 39, 0, 0)
> ctypes.windll.wininet.InternetSetOptionW(0, 37, 0, 0)
> self.system_proxy_active = True
> self.proxy_btn.setText(f"Disable System Proxy (port {self.selected_port})")
> self.proxy_btn.setObjectName("proxy_btn_on")
> self.proxy_btn.setStyleSheet(self.styleSheet())
> self.log(f"✅ SYSTEM PROXY ENABLED! All traffic via Tor (port {self.selected_port})")
> self.update_status(f"System proxy active (port {self.selected_port})")
> QMessageBox.information(
> self, "System Proxy Enabled!",
> f"ALL applications now go through Tor (port {self.selected_port})\n\n"
> "WARNING:\n- Internet speed will decrease\n- Some apps may not work\n"
> "- Click 'Disable System Proxy' to revert"
> )
> except Exception as e:
> self.log(f"❌ Error enabling proxy: {e}")
> 
> def disable_system_proxy(self):
> try:
> key = winreg.OpenKey(
> winreg.HKEY_CURRENT_USER,
> r"Software\Microsoft\Windows\CurrentVersion\Internet Settings",
> 0, winreg.KEY_SET_VALUE
> )
> winreg.SetValueEx(key, "ProxyEnable", 0, winreg.REG_DWORD, 0)
> winreg.CloseKey(key)
> ctypes.windll.wininet.InternetSetOptionW(0, 39, 0, 0)
> ctypes.windll.wininet.InternetSetOptionW(0, 37, 0, 0)
> self.system_proxy_active = False
> self.proxy_btn.setText("Enable System Proxy")
> self.proxy_btn.setObjectName("proxy_btn_off")
> self.proxy_btn.setStyleSheet(self.styleSheet())
> self.log("✅ SYSTEM PROXY DISABLED")
> self.update_status("System proxy disabled")
> except Exception as e:
> self.log(f"❌ Error disabling proxy: {e}")
> 
> def launch_selected_apps(self):
> if not self.selected_port:
> self.log("❌ Select a port from the list first!")
> QMessageBox.warning(self, "Error", "Select a Tor port!")
> return
> if not self.selected_processes:
> self.log("❌ Select at least one application from the list!")
> QMessageBox.warning(self, "Error", "Select application(s) from the list!")
> return
> reply = QMessageBox.question(
> self, "Close Old Processes?",
> f"Found {len(self.selected_processes)} application(s).\n\n"
> "Close their current instances before launching via Tor?",
> QMessageBox.Yes | QMessageBox.No
> )
> close_old = (reply == QMessageBox.Yes)
> launched = 0
> errors = []
> for proc_data in self.selected_processes:
> app_name = proc_data['name']
> app_path = proc_data['exe']
> pid = proc_data['pid']
> if not app_path or not os.path.exists(app_path):
> errors.append(f"{app_name}: file not found")
> continue
> self.log(f"Launching {app_name} via Tor (port {self.selected_port})...")
> if close_old:
> try:
> proc = psutil.Process(pid)
> proc.terminate()
> proc.wait(timeout=3)
> self.log(f"Closed old process {app_name} (PID: {pid})")
> except:
> pass
> cmd = [app_path]
> env = os.environ.copy()
> if any(x in app_path.lower() for x in ['chrome', 'brave', 'chromium']):
> cmd.extend([
> f"--proxy-server=socks5://127.0.0.1:{self.selected_port}",
> "--host-resolver-rules=MAP * ~NOTFOUND , EXCLUDE localhost",
> "--new-window",
> "https://check.torproject.org"
> ])
> elif 'firefox' in app_path.lower():
> profile_dir = os.path.join(os.environ['TEMP'], f"tor_profile_{int(time.time())}_{app_name}")
> cmd.extend([
> "-CreateProfile", f"TorProfile_{app_name} {profile_dir}",
> "-P", f"TorProfile_{app_name}",
> "-no-remote", "-new-window",
> "https://check.torproject.org"
> ])
> env['http_proxy'] = f'socks5://127.0.0.1:{self.selected_port}'
> env['https_proxy'] = f'socks5://127.0.0.1:{self.selected_port}'
> else:
> self.log(f" {app_name} is not a browser. Use system proxy for it.")
> try:
> if 'firefox' in app_path.lower():
> subprocess.Popen(cmd, env=env, shell=False)
> else:
> subprocess.Popen(cmd, shell=False)
> launched += 1
> self.log(f"✅ {app_name} launched")
> except Exception as e:
> errors.append(f"{app_name}: {e}")
> if launched > 0:
> self.update_status(f"Launched apps: {launched} via Tor")
> self.log(f"✅ Successfully launched {launched} of {len(self.selected_processes)} apps")
> if errors:
> for err in errors:
> self.log(f"❌ {err}")
> QMessageBox.warning(self, "Partial Success",
> f"Launched: {launched}\nErrors: {len(errors)}\n\n" + "\n".join(errors[:5]))
> elif launched > 0:
> QMessageBox.information(self, "Success!",
> f"✅ All {launched} app(s) launched via Tor (port {self.selected_port})")
> 
> if __name__ == " __main__":
> app = QApplication(sys.argv)
> app.setStyle('Fusion')
> window = TorAppSelector()
> window.show()
> sys.exit(app.exec_())
> 
> ```

> **📦 Requirements + how to run**
>
> **Install Python deps:**
> 
> ```auto
> pip install psutil PyQt5
> 
> ```
> 
> **Also required:** [Tor Browser](https://www.torproject.org/download/) installed (the standard free version — that’s all)
> 
> **Lighter alternative:** don’t want the browser running in the background? Use the [Tor Expert Bundle](https://www.torproject.org/download/tor/) — just `tor.exe`, no GUI. Pair with [NSSM](https://nssm.cc/download) to install it as a Windows service that starts on boot.
> 
> **Run:**
> 
> ```auto
> python tor_app_selector.py
> 
> ```
> 
> **Steps:**
> 
> 1. Open Tor Browser and let it connect to the network
> 2. Run the script → click **Scan Tor Ports** (auto-finds port 9150)
> 3. Choose your mode:
> - **System-wide:** click **Enable System Proxy** → all traffic routes through Tor
> - **Per-app:** Ctrl+click apps in the list → **Launch Selected Apps via Tor**
> 
> 4. Verify at [check.torproject.org](https://check.torproject.org) 🧅

> **✅ Proof it works**
>
> ![image](https://onehack.st/uploads/default/original/3X/8/5/85a672724cf117dde06b44e8d8efaf96574e89e9.png)  
> [check.torproject.org](http://check.torproject.org) confirms the connection — and doesn’t expose that a proxy is in use.
> 
> ![image](https://onehack.st/uploads/default/original/3X/5/9/595c1dc19b014d773d4a4174ff158db018900b2e.png)  
> Speed through Tor is surprisingly usable. Not the crawl most people expect.

> **🔗 Go deeper — fixes, tools & the full rabbit hole**
>
> **✅ Verify your connection first**  
> Before trusting any proxy setup — check for leaks:
> 
> - [DNS Leak Test](https://www.dnsleaktest.com/) — are your DNS queries bypassing Tor?
> - [IPLeak.net](https://ipleak.net/) — IP address, DNS, and WebRTC in one test
> - [BrowserLeaks WebRTC](https://browserleaks.com/webrtc) — Chrome/Firefox can leak your real IP via WebRTC even through SOCKS5
> - [BrowserLeaks DNS](https://browserleaks.com/dns) — resolves 50 random domains to show which DNS server actually answers
> 
> · · · · · · · · · · · · · · · ·
> 
> **🎮 Route games, Telegram, Discord (they ignore WinInet)**  
> These apps use raw TCP/UDP that bypasses the Windows system proxy entirely. Two solutions:
> 
> - [Netch](https://github.com/netchx/netch) / [releases](https://github.com/netchx/netch/releases/latest) — per-process proxy using WinDivert; routes any EXE through SOCKS5 at the packet level, no system-wide setting
> - [tun2socks](https://github.com/xjasonlyu/tun2socks/releases/latest) — creates a virtual TUN adapter and routes ALL traffic through Tor’s SOCKS5; apps can’t bypass it
> - [proxychains-windows](https://github.com/shunf4/proxychains-windows) — Winsock hook approach; injects into the target process and redirects connect() calls; no kernel driver needed
> - [ProxiFyre](https://github.com/wiresock/proxifyre) / [releases](https://github.com/wiresock/proxifyre/releases) — per-app SOCKS5 proxifier using NDISAPI; routes TCP + UDP
> 
> · · · · · · · · · · · · · · · ·
> 
> **⚙ Run Tor without the browser (lighter setup)**
> 
> - [Tor Expert Bundle](https://www.torproject.org/download/tor/) — official standalone `tor.exe` (no browser, ~10MB)
> - [Expert Bundle v15.0.18 direct download](https://archive.torproject.org/tor-package-archive/torbrowser/15.0.18/tor-expert-bundle-windows-x86_64-15.0.18.tar.gz) — Windows x86\_64
> - [NSSM](https://nssm.cc/download) — Non-Sucking Service Manager; wraps tor.exe as a persistent Windows service
> - [matinrco/tor](https://github.com/matinrco/tor) — pre-configured Expert Bundle for Windows with VBS launcher, SOCKS5 on 9050, no browser
> - [SuperUser: tor.exe as Windows service](https://superuser.com/questions/1631178/how-to-configure-tor-as-service-on-windows) — using Tor’s built-in `--service install` flag (no NSSM needed)
> - [Sample torrc gist](https://gist.github.com/NaveenB2004/abae1c674afc4e6bfaba6a80d3020625) — SocksPort 9050, ControlPort 9051, CookieAuthentication, DataDirectory, pluggable transport lines
> 
> · · · · · · · · · · · · · · · ·
> 
> **🌍 Add exit country switching right now (don’t wait for v7)**  
> The exit country feature is already built into Tor — you just need Python’s `stem` library to control it:
> 
> - [stem](https://github.com/torproject/stem) / [PyPI](https://pypi.org/project/stem/) — official Python Tor controller (`pip install stem`)
> - [stem tutorial: ExitNodes selection](https://stem.torproject.org/tutorials/to_russia_with_love.html) — pick exit country via `NEWNYM` + `ExitNodes {US}` in 5 lines
> - [stem API: Controller class](https://stem.torproject.org/api/control.html) — full NEWNYM, signal, circuit, stream methods
> - [torrc man page](https://manpages.debian.org/unstable/tor/torrc.5.en.html) — `IsolateDestAddr`, `IsolateSOCKSAuth`, multi-SocksPort for per-app circuit isolation
> - [Tor Control Protocol spec](https://spec.torproject.org/control-spec) — NEWNYM, MAPADDRESS, ATTACHSTREAM, EXTENDCIRCUIT reference
> 
> · · · · · · · · · · · · · · · ·
> 
> **🔬 The tech inside this tool**
> 
> - [basil00/Tallow](https://github.com/basil00/Tallow) — transparent Tor for Windows via WinDivert; the packet-level reference implementation of what this tool does at the registry level
> - [basil00/WinDivert](https://github.com/basil00/WinDivert) — the kernel driver powering Netch, Tallow, GoodbyeDPI, and most Windows transparent proxifiers
> - [ValdikSS/GoodbyeDPI](https://github.com/ValdikSS/GoodbyeDPI) — shows WinDivert NETWORK\_LAYER per-packet filtering and manipulation patterns
> - [WinDivert API docs](https://reqrypt.org/windivert-doc.html) — full programming reference for WinDivertOpen, filters, WINDIVERT\_LAYER
> 
> · · · · · · · · · · · · · · · ·
> 
> **💨 Heavier alternatives (if you need everything routed, reliably)**
> 
> - [sing-box](https://github.com/SagerNet/sing-box) / [releases](https://github.com/SagerNet/sing-box/releases/latest) — universal proxy platform; TUN inbound + SOCKS5 outbound; routes games, Discord, everything
> - [Clash Verge Rev](https://github.com/clash-verge-rev/clash-verge-rev) / [releases](https://github.com/clash-verge-rev/clash-verge-rev/releases/latest) — GUI for mihomo; TUN mode toggle; Windows installer; point SOCKS5 outbound at port 9150
> - [sing-box TUN docs](https://sing-box.sagernet.org/configuration/inbound/tun/) — `auto_route`, `strict_route`, stack options
> 
> · · · · · · · · · · · · · · · ·
> 
> **🧅 Bypass DPI — when Tor itself is blocked**  
> Standard Tor traffic gets fingerprinted and killed by corporate/ISP DPI. Pluggable transports make it look like HTTPS:
> 
> - [Expert Bundle dist index](https://dist.torproject.org/torbrowser/15.0.18/) — the bundle already includes `lyrebird.exe` (obfs4), `snowflake.exe`, `meek_client.exe` as standalone binaries
> - [obfs4 source repo](https://gitlab.com/yawning/obfs4) — obfuscated Tor transport; add `ClientTransportPlugin obfs4 exec /path/lyrebird.exe` to torrc
> - [Snowflake](https://snowflake.torproject.org/) — WebRTC-based Tor bridge; bypasses DPI that targets Tor’s TLS fingerprint
> - [Pluggable Transports spec](https://github.com/Pluggable-Transports/Pluggable-Transports-spec) — the IPC protocol any PT binary implements
> 
> · · · · · · · · · · · · · · · ·
> 
> **🌐 Other anonymity networks — same SOCKS5 interface, different network**  
> This tool’s SOCKS5 port scan works with any anonymity daemon, not just Tor:
> 
> - [i2pd](https://github.com/PurpleI2P/i2pd) / [releases](https://github.com/PurpleI2P/i2pd/releases) — C++ I2P router; SOCKS5 proxy on port 4447, HTTP proxy on 4444; runs as Windows service
> - [geti2p.net](https://geti2p.net/en/download) — Java I2P router; Windows installer with built-in browser config
> - [Lokinet](https://lokinet.org/) / [releases](https://github.com/oxen-io/lokinet/releases) — creates a virtual network adapter on Windows; onion-routed at the IP layer
> - [Yggdrasil](https://github.com/yggdrasil-network/yggdrasil-go/releases) — end-to-end encrypted mesh network; Windows MSI installer

░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

_Tor was already running on your machine. This just makes everything else use it._

---

<div class="post-metadata">

**Author:** ![CharaDreemurr](https://onehack.st/user_avatar/onehack.st/charadreemurr/32/175603_2.png) [@CharaDreemurr](https://onehack.st/u/CharaDreemurr)\
**Post date:** [July 20, 2026, 12:28pm UTC](https://onehack.st/t/make-every-app-on-your-windows-pc-anonymous-through-tor-one-click-no-vpn-no-setup-completely-free/324036/2 "2026-07-20T12:28:36Z")

</div>

you don’t need nssm to install the tor service bundle as a service  
you can just run `tor.exe --service install`
