disemay12/proxybox
Per-process proxy for Windows: winsock hook, isolated profiles and registry, unlimited copies with different proxies
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 ← сохранённые прокси и приложения (создаётся сам)
Как это работает
proxybox.exeзапускаетpbinject*.exe(по разрядности цели), передав прокси черезPB_PROXY.- Инжектор создаёт целевой процесс приостановленным (
CREATE_SUSPENDED), внедряетpbhook{32,64}.dll, снимает паузу. - DLL ставит хуки на
connect/WSAConnect/ConnectEx(MinHook) и поднимает релей на127.0.0.1:<ephemeral>. - Каждый
connect()приложения уходит в релей: заголовок с адресом → релей открывает соединение к прокси →CONNECT(http) илиSOCKS5 CONNECT→ перекачка байтов. - Если прокси — SOCKS5 и подтвердил
UDP ASSOCIATE, DLL заранее открывает ассоциацию и заворачивает датаграммы приложения (send/sendto/WSASend/WSASendTo) в SOCKS5-конверт по RFC 1928. Датаграммный сокет при этомconnect-ится на локальный UDP-релей, поэтому ядро принимает ответы, аgetpeername/recvfromпоказывают приложению исходный адрес сервера. - Браузеры на 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