samp.directory
← Scripts and libraries

disemay12/proxybox

Per-process proxy for Windows: winsock hook, isolated profiles and registry, unlimited copies with different proxies

Tool★ 0updated yesterdayMITRust
Open on GitHub

README.md

proxybox

Запускает любое приложение Windows через выбранный прокси — по одному прокси на процесс. Можно запустить сколько угодно копий одной программы, каждая со своим прокси.

Готовые бинарники — в Releases: proxybox-v1.0.0-win.zip (распаковать и запустить proxybox.exe).

dist/
  proxybox.exe      ← GUI (Rust + egui)
  pbinject.exe      ← инжектор x64 (C++)
  pbhook64.dll      ← хук winsock x64 (C++)
  pbinject32.exe    ← инжектор x86 (C++)
  pbhook32.dll      ← хук winsock x86 (C++)
  live-socks5.tsv   ← проверенные socks5
  live-proxies.tsv  ← проверенные http
  proxybox.json     ← сохранённые прокси и приложения (создаётся сам)

Как это работает

  1. proxybox.exe запускает pbinject*.exe (по разрядности цели), передав прокси через PB_PROXY.
  2. Инжектор создаёт целевой процесс приостановленным (CREATE_SUSPENDED), внедряет pbhook{32,64}.dll, снимает паузу.
  3. DLL ставит хуки на connect / WSAConnect / ConnectEx (MinHook) и поднимает релей на 127.0.0.1:<ephemeral>.
  4. Каждый connect() приложения уходит в релей: заголовок с адресом → релей открывает соединение к прокси → CONNECT (http) или SOCKS5 CONNECT → перекачка байтов.
  5. Если прокси — SOCKS5 и подтвердил UDP ASSOCIATE, DLL заранее открывает ассоциацию и заворачивает датаграммы приложения (send/sendto/WSASend/WSASendTo) в SOCKS5-конверт по RFC 1928. Датаграммный сокет при этом connect-ится на локальный UDP-релей, поэтому ядро принимает ответы, а getpeername/recvfrom показывают приложению исходный адрес сервера.
  6. Браузеры на Chromium идут мимо инъекции: для них поднимается локальный HTTP-мост и передаётся --proxy-server.

Хук живёт только внутри процесса: две копии одного exe — два независимых прокси, без системных настроек. Если приложению не назначен прокси, при запуске берётся первый из списка. Режим UDP пишется в лог строкой pbproxy: armed via … udp=associate|direct.

Интерфейс

Одно окно:

  • Прокси — выпадающий список сверху. Выбранный прокси назначается выделенному приложению сразу. В метке — пинг из последней проверки и · UDP у прокси с подтверждённым UDP ASSOCIATE; после трёх неудач подряд прокси помечается · мёртв (красным), но остаётся в списке.
  • Найти — автопоиск бесплатных прокси: качает публичные списки socks5/http, проверяет каждое двойным реальным запросом и оставляет только те, что ответили (сортировка по пингу). Время — 1–3 минуты, прогресс видно в строке состояния. Всё, что добавлено вручную, автопоиск не выбрасывает.
  • + рядом с ним — добавить свой прокси: тип (SOCKS5/HTTP), хост, порт, логин и пароль (необязательно). Прокси сохраняется вместе с остальными.
  • Приложения — строки со списком: имя, путь, чип прокси. ▶ запускает копию, ✕ удаляет, двойной клик — тоже запуск, правый клик — аргументы командной строки.
  • + Приложение — выбрать exe с диска. Из запущенных — добавить уже работающую программу из списка окон, вместе с её exe-путём.
  • Проверить — реальный запрос через выбранный прокси (встроенный клиент, без curl.exe): возвращает внешний IP и наличие UDP, результат в статусной строке. Все — то же для всего списка параллельно, в фоне.
  • Мониторинг — прокси, назначенные приложениям, перепроверяются в фоне раз в 30 секунд; пинг и «мёртв» обновляются сами, даже без нажатий.
  • Сетка — превью окон: живые кадры только тех процессов, которые запущены через proxybox, без перекладывания самих окон. Fullscreen-игры один раз переводятся в оконный режим. Клик по плитке — фокус, «×» — закрыть, «развернуть» — восстановить свёрнутое. Рядом — число колонок (Авто подбирает по 16:9). Ctrl+Alt+G переключает превью из любого приложения, proxybox при этом не сворачивается.
  • Enter — запустить выделенное, Delete — удалить.

Всё, что добавлено, сразу пишется в proxybox.json рядом с exe и подхватывается при следующем запуске.

Превью окон

Сетка показывает не настоящие окна, а кадры процессов, запущенных через proxybox. Сами окна остаются на своих местах: их можно двигать, разворачивать и сворачивать.

  • В превью попадают только процессы, запущенные из proxybox: при старте запоминается PID инжектора, дальше воркер обходит дерево процессов (сама игра, дочерние процессы браузера). Приложения, запущенные мимо proxybox, не показываются.
  • Служебные окна pbinject*.exe и conhost.exe отфильтрованы.
  • Воркер раз в 600 мс снимает кадр через PrintWindow(PW_RENDERFULLCONTENT) и отдаёт его в UI как текстуру. Свёрнутое окно не снимается: плитка показывает «свёрнуто» и кнопку «развернуть».
  • Fullscreen-игра один раз переводится в оконный режим: снимается рамка, размер — 2/3 рабочей области. Если игра не поддалась — один раз отправляется Alt+Enter. При выходе из proxybox окно возвращается в исходное состояние.
  • Плитка: клик — фокус/восстановление, «×» — WM_CLOSE, «фокус» — на передний план. Колонки: Авто (лучшее приближение к 16:9) или фиксированные 2–5, выбор хранится в grid_cols.
  • Превью живут в главном окне proxybox, сворачивать его не нужно. Ctrl+Alt+G переключает режим глобально.

Ограничения: эксклюзивный fullscreen некоторые игры не отпускают даже после Alt+Enter; PrintWindow может вернуть чёрный кадр для отдельных D3D- или защищённых окон — тогда плитка показывает «кадр недоступен».

Сборка

powershell -ExecutionPolicy Bypass -File proxybox-rs\build.ps1      # GUI (Rust)
powershell -ExecutionPolicy Bypass -File proxybox\build.ps1         # pbinject + pbhook (x64 + x86, MinGW-w64)

GUI: Rust 1.99 + eframe 0.28, тулчейн x86_64-pc-windows-gnu, линковка через MinGW. Native-часть: MinGW-w64 (x86_64 + i686) + MinHook (лежит в third_party/minhook).

Если тулчейны не в PATH, укажите каталоги с компиляторами:

$env:MINGW64_BIN = 'C:\mingw64\bin'          # gcc / g++
$env:MINGW32_BIN = 'C:\mingw32\bin'          # i686-w64-mingw32-gcc / g++

MINHOOK_DIR переопределяет путь к MinHook, по умолчанию — third_party\minhook.

Обновление списков прокси

Проще всего — кнопка Найти в приложении: она сама скачивает списки, проверяет и оставляет только рабочие.

То же самое из консоли (если нужен файл live-*.tsv):

powershell -ExecutionPolicy Bypass -File proxybox\tools\refresh-proxies.ps1 -Protocol both

Качает свежие списки из четырёх источников, проверяет каждое прокси дважды через http://api.ipify.org (запрос идёт внутри туннеля: CONNECT для http, SOCKS5 с доменным именем для socks5) и пишет live-socks5.tsv / live-proxies.tsv в dist/. При первом запуске (пустой proxybox.json) приложение подхватывает эти файлы.

Постоянных бесплатных прокси не существует — публичные живут часы. Поэтому список надо обновлять перед работой: кнопка «Найти» занимает 1–3 минуты и оставляет только проверенные.

Мультиаккаунт

Каждый запуск — отдельная копия со своей папкой профиля и своим туннелем:

  • Браузер (Chrome/Edge/Brave/…): копия 1 → profiles\<имя>-<N>\1, копия 2 → \2. У каждой свои cookie и логины, окна живут одновременно.
  • Обычное приложение: процессу подменяются APPDATA, LOCALAPPDATA, TEMP на profiles\<имя>-<N>\<копия>\…, а HKCU переводится в приватный файл-улей registry.hive (RegLoadAppKey + RegOverridePredefKey). Приложение видит чистый профиль пользователя и чистый реестр — значит можно залогиниться вторым аккаунтом, не выходя из первого.
  • Electron/Chromium-приложения (ZCode, VS Code, Discord, Telegram Desktop и подобные): SHGetKnownFolderPath ищет профиль мимо HKCU, поэтому в процесс ставятся хуки на SHGetFolderPathW/A, SHGetKnownFolderPath, SHGetSpecialFolderPathW и SHGetFolderPathAndSubDirW. Каждая копия получает свой userData, requestSingleInstanceLock больше не сталкивается, и копии живут одновременно.
  • HOME и USERPROFILE на копию: ~/.zcode, ~/.gitconfig, os.homedir() и дочерние процессы видят profiles\<имя>-<N>\<копия>\Home.
  • direct:// изолирует так же: реестр, папки и shell-хуки ставятся до выбора туннеля; прокси можно не назначать.
  • Дочерние процессы: pbhook ставит хук на kernelbase!CreateProcessInternalW и внедряет себя в каждого потомка, поэтому samp.exe → gta_sa.exe получают тот же прокси, тот же приватный HKCU и те же папки профиля. Дети делят улей копии (RegLoadAppKey на один файл поддерживается), отдельный улей им не нужен. Для 64-битного родителя и 32-битного ребёнка инъекцию делает pbinject32.exe --attach. Туннель готов до старта ребёнка, если приложение само создаёт его приостановленным (как SA-MP); для остальных детей действует окно 400 мс — см. ограничение про медленный прокси.
  • Firefox: своя папка профиля на копию (-profile … -no-remote) и жёстко прописанный HTTP-прокси на локальный мост в user.js — иначе его socket-процесс ходит мимо DLL. Копии не сливаются в одно окно.
  • Разные прокси на аккаунт: добавь один и тот же exe дважды (это разрешено) — у каждой записи свой прокси и своя нумерация копий.
  • Вернуться к аккаунту: правый клик по строке → «Запустить копию: 1 2 3…». Копия стартует с той же папкой профиля, то есть с тем же залогиненным аккаунтом.
  • Сброс: там же «Сбросить копии» — удаляет профили этой записи и начинает нумерацию заново.
  • Остановка: у работающего приложения в строке появляется кнопка с квадратом — она завершает всё дерево процессов (лаунчер, игру, дочерние), листья раньше родителей. В футере — «Стоп всё», на плитке превью — «■» рядом с «×» для конкретного окна. Защищённый или запущенный от администратора процесс не убивается молча: статус скажет, сколько осталось живыми.

Ограничение: клиент Steam дополнительно держит глобальный мьютекс (не по пути userData) и находит уже запущенный экземпляр по окну — изоляции реестра и APPDATA недостаточно. Обход: скопировать папку установки Steam (второй steam.exe), добавить копию в список и назначить ей прокси. Приложения, которые читают сессию из своего установочного каталога или глобального мьютекса, ведут себя так же.

Ограничения

  • UDP проксируется только через SOCKS5 с UDP ASSOCIATE. Для HTTP-прокси и SOCKS5 без ассоциации датаграммы идут напрямую: pbhook в этом режиме ничего не перехватывает. Режим виден в логе (udp=associate|direct) и в метке прокси (· UDP).
  • UDP-ответы маршрутизируются по адресу сервера. Если сервер отвечает не с того адреса, с которого принимал, или прокси шлёт ответы не с BND-адреса, датаграмма может уйти не в тот сокет или потеряться — смотри udp: reply without route в логе. Overlapped-приём/отправка (WSARecvFrom/WSASendTo с OVERLAPPED) идёт мимо перепаковки.
  • SA-MP / open.mp: игра нативно ходит UDP на порт 7777. Через pbhook она поедет, только если прокси подтвердил · UDP; иначе используйте RakLite с нативным SOCKS5 (см. RAKLITE.md).
  • IPv6-назначения идут напрямую — релей и UDP-ассоциация только IPv4.
  • x86 и x64 поддерживаются. Лаунчер читает PE-заголовок цели и выбирает pbinject32.exe + pbhook32.dll или 64-битную пару.
  • Браузеры на Chromium (Chrome, Edge, Brave, Vivaldi, Opera, Яндекс) запускаются с --proxy-server=http://127.0.0.1:<порт> на локальный мост: их сетевой процесс отдельный, DLL туда не внедряется, а socks5:// в Chrome требует remote-DNS, которого бесплатные прокси не умеют. Каждая копия получает свой --user-data-dir, поэтому окна не сливаются в одно.
  • Firefox: хук внедряется в основной процесс, но часть трафика идёт через socket-процесс — надёжнее задать прокси в профиле.
  • Защищённые процессы могут блокировать CreateRemoteThread — тогда в статусе будет «не удалось внедрить хук».
  • Дочерние процессы перехватываются через CreateProcess-семейство. Запуск через COM-расширения оболочки (ShellExecuteEx), через AppInfo с повышением прав или прямыми вызовами NtCreateUserProcess в обход Win32 хук не видит: такой ребёнок стартует без прокси и без своего HKCU. Остальные потомки (обычный CreateProcessA/W, ShellExecute без COM-повышения) наследуются.
  • Защищённый/повышенный процесс нельзя ни внедрить, ни завершить без тех же прав: proxybox сообщит «живы: N — нет прав / защищённый процесс», а не сделает вид, что всё остановлено. Запускайте proxybox от администратора, если цель повышена.
  • Консольные цели запускаются без окна и без conhost (DETACHED_PROCESS): их stdout/stderr не видны, если приложение не пишет лог само. В управляемой сессии хук так же отвязывает консоль у дочерних консольных процессов приложения (если только оно само не попросило CREATE_NEW_CONSOLE). Это сделано намеренно, чтобы не мелькали CMD-окна.
  • Медленный прокси задерживает старт: лаунчер ждёт готовности туннеля (до 5 с), а дочерние процессы, которых приложение возобновляет само, — до 5 с; дети, которых приостановил сам proxybox, ждут не более 400 мс, чтобы не сериализовать запуск десятков процессов Electron. Если прокси не ответил за это время, первые соединения могут уйти напрямую — в логе будет childinject: proxy arm timeout.
  • Прокси видит ваш трафик (TLS остаётся TLS, но метаданные и SNI — нет). Не логинься через бесплатные прокси в то, что жалко.
  • Второй экземпляр не стартует: proxybox держит одноместный мьютекс и поднимает уже запущенное окно. Иначе два процесса делили proxybox.json и нумерацию профилей.
  • Конфиг пишется атомарно (временный файл + rename), старый формат proxybox.json / proxybox.ini читается и конвертируется один раз: прокси получают стабильные id, приложения ссылаются на proxy_id, поэтому обновление списков больше не рвёт привязки.

Диагностика

  • dist\logs\bridge.log — браузерный мост: каждая строка CONNECT host:443 -> ok означает, что запрос ушёл в прокси. Если после открытия сайта лога нет — браузер пошёл мимо.
  • dist\logs\<timestamp>-<pid>.log — хук приложения: sandbox: pbready signaled, sandbox: pbarm signaled, sandbox: shell folder hooks armed, registry: HKCU -> …, pbproxy: direct, tunnel off (sandbox active), childinject: hooked kernelbase!CreateProcessInternalW, childinject: hit n=1 pid=… image=…, childinject: injected pid=…, childinject: 32-bit helper attached pid=…, childinject: ready event unseen, async arm pid=…, pbproxy: armed via ... udp=associate|direct, connect via proxy ..., udp: associate ok relay=IP:PORT, udp: proxying datagrams, udp: lazy redirect on sendto, udp: associate failed (...), udp: control channel lost, udp proxying off.

Проверить прокси вручную:

curl.exe -x socks5://1.2.3.4:1080 https://api.ipify.org

Лицензия

MIT — см. LICENSE. Сторонние компоненты: THIRD_PARTY_NOTICES.md.

cppeguihttp-proxymultiboxingproxyrustsa-mpsocks5win32windows

This page is built from what GitHub publishes about the repository. samp.directory does not host the code. Report a problem with this listing