# vpnhide Скрывает активное VPN-соединение на Android от выбранных приложений. ## Чем vpnhide лучше аналогов? Существующие модули, такие как [NoVPNDetect](https://bitbucket.org/yuri-project/novpndetect) и [NoVPNDetect Enhanced](https://github.com/BlueCat300/NoVPNDetectEnhanced), хукают **внутри процесса** целевого приложения через Xposed. Это означает, что любое приложение с anti-tamper защитой может обнаружить инъекцию и отказаться работать. Автор NoVPNDetect Enhanced прямо пишет: *«Модуль не будет работать если у подключаемого приложения есть защита от LSPosed, проверка на инъекции в память. Например MirPay, Т-Банк.»* vpnhide использует принципиально другой подход: - **lsposed** хукает `system_server` (а не целевое приложение) — данные о VPN удаляются на уровне Binder до того, как попадут в процесс приложения. Anti-tamper SDK проверяет свой процесс и ничего не находит. - **kmod** хукает само ядро — ioctl, netlink и /proc/net фильтруются до возврата из системного вызова. Нулевой след в процессе. Никакой инъекции библиотек. Нечего обнаруживать. - Процесс целевого приложения полностью нетронут — ни Xposed, ни inline-хуков, ни модифицированных регионов памяти. Благодаря этому vpnhide работает с такими приложениями, как MirPay, Т-Банк, Альфа-Банк и другими банковскими/государственными приложениями, которые активно обнаруживают и блокируют модули на основе Xposed. Кроме того, vpnhide покрывает нативные векторы обнаружения (ioctl, netlink, /proc/net), которые аналоги вообще не хукают — именно эти векторы используют приложения на кроссплатформенных фреймворках и нативных SDK. ## Какие модули нужны? Всегда нужен `lsposed` (обрабатывает обнаружение через Java API) плюс один нативный модуль: - **`kmod` + `lsposed`** (рекомендуется) — хуки на уровне ядра, нулевой след в процессе приложения. Невидим для anti-tamper SDK в банковских/госприложениях. Требуется поддерживаемое GKI-ядро (см. ниже). - **`zygisk` + `lsposed`** — хуки libc внутри процесса приложения. Используйте, если ваше устройство не поддерживается сборками kmod, или если нет возможности установить модуль ядра. ## Установка Скачайте последний релиз из [Releases](https://github.com/okhsunrog/vpnhide/releases). ### kmod + lsposed (рекомендуется) 1. Установите `vpnhide-kmod-<ваш-gki>.zip` через менеджер KernelSU-Next → Модули → Установить из хранилища 2. Установите `vpnhide-lsposed.apk` как обычное приложение 3. В менеджере LSPosed включите модуль vpnhide и добавьте **«System Framework»** в его область действия 4. Перезагрузите устройство (обязательно — хуки LSPosed внедряются в `system_server` при загрузке, поэтому модуль должен быть активен до запуска `system_server`) 5. Откройте приложение VPN Hide, предоставьте ему root-доступ (Magisk запросит автоматически; на KernelSU-Next выдайте разрешение вручную в менеджере) и выберите целевые приложения **Как узнать поколение GKI:** выполните `adb shell uname -r`. Вывод выглядит как `6.1.75-android14-11-g...` — поколение `android14-6.1`. Скачайте соответствующий `vpnhide-kmod-android14-6.1.zip`. > **Примечание:** `android14` в названии GKI — это НЕ версия Android, а поколение ядра. Все Pixel с 6 по 9a используют одно ядро `android14-6.1`. Серия Pixel 10 перешла на `android16-6.12`. ### zygisk + lsposed 1. Установите `vpnhide-zygisk.zip` через менеджер KernelSU-Next или Magisk → Модули 2. Установите `vpnhide-lsposed.apk` как обычное приложение 3. В менеджере LSPosed включите модуль vpnhide и добавьте **«System Framework»** в его область действия 4. Перезагрузите устройство (обязательно — хуки LSPosed внедряются в `system_server` при загрузке) 5. Откройте приложение VPN Hide, предоставьте ему root-доступ (Magisk запросит автоматически; на KernelSU-Next выдайте разрешение вручную в менеджере) и выберите целевые приложения ## Настройка **Приложение VPN Hide (рекомендуется):** откройте приложение VPN Hide (устанавливается как `vpnhide-lsposed.apk`) и предоставьте ему root-доступ (Magisk запрашивает автоматически; на KernelSU-Next выдайте разрешение в менеджере). Приложение показывает все установленные приложения с иконками, названиями и поиском. Отметьте приложения, от которых нужно скрыть VPN, нажмите «Сохранить». Работает и с kmod, и с zygisk — автоматически записывает во все нужные файлы через `su`. **WebUI:** на KernelSU-Next откройте модуль в менеджере и нажмите WebUI. Тот же функционал, но доступен только на KernelSU-Next (Magisk не поддерживает WebUI). **Командная строка:** редактируйте `/data/adb/vpnhide_kmod/targets.txt` или `/data/adb/vpnhide_zygisk/targets.txt` напрямую (одно имя пакета на строку). Для применения изменений требуется перезагрузка. После изменения целей принудительно остановите и перезапустите затронутые приложения — хуки вступают в силу при следующем запуске приложения. ## Проверка Установите `vpnhide-test.apk` из релиза, добавьте его в список целевых приложений и запустите при активном VPN. Все проверки должны показать PASS. ## Компоненты | Директория | Что | Как | |---|---|---| | **[kmod/](kmod/)** | Модуль ядра (C) | Хуки `kretprobe` в пространстве ядра. Нулевой след в процессе приложения. ([подробнее](kmod/README.md)) | | **[lsposed/](lsposed/)** | LSPosed-модуль + приложение выбора целей (Kotlin) | Хуки `writeToParcel` в `system_server` для per-UID фильтрации Binder. APK также служит UI для управления целями. ([подробнее](lsposed/README.md)) | | **[zygisk/](zygisk/)** | Zygisk-модуль (Rust) | Inline-хуки `libc.so` в процессе приложения. Альтернатива kmod. ([подробнее](zygisk/README.md)) | | **[test-app/](test-app/)** | Диагностическое приложение (Kotlin + Rust) | 24 проверки, покрывающие все векторы обнаружения. | ## Покрытие обнаружения | # | Вектор обнаружения | SELinux | kmod | zygisk | lsposed | |---|---|---|---|---|---| | 1 | `ioctl(SIOCGIFFLAGS)` на tun0 | | x | x | | | 2 | `ioctl(SIOCGIFNAME)` разрешение индекса в имя | | x | x | | | 3 | `ioctl(SIOCGIFCONF)` перечисление интерфейсов | | x | x | | | 4 | `getifaddrs()` (использует netlink внутри) | | x | x | | | 5 | netlink `RTM_GETLINK` дамп | блок. | x | x | | | 6 | netlink `RTM_GETADDR` дамп (IPv4 + IPv6) | блок. | x | | | | 7 | netlink `RTM_GETROUTE` дамп | блок. | | | | | 8 | `/proc/net/route` | блок. | x | x | | | 9 | `/proc/net/ipv6_route` | блок. | | x | | | 10 | `/proc/net/if_inet6` | блок. | | x | | | 11 | `/proc/net/tcp`, `tcp6` | блок. | | | | | 12 | `/proc/net/udp`, `udp6` | блок. | | | | | 13 | `/proc/net/dev` | блок. | | | | | 14 | `/proc/net/fib_trie` | блок. | | | | | 15 | `/sys/class/net/tun0/` | блок. | | | | | 16 | `NetworkCapabilities` (hasTransport, NOT_VPN, transportInfo) | | | | x | | 17 | `NetworkInfo` (getType, getTypeName) | | | | x | | 18 | `ConnectivityManager.getActiveNetwork()` | | | | x | | 19 | `ConnectivityManager.getAllNetworks()` + VPN-сканирование | | | | x | | 20 | `LinkProperties` (interfaceName, routes, DNS) | | | | x | | 21 | `NetworkInterface.getNetworkInterfaces()` | | x | x | | | 22 | `System.getProperty` (настройки прокси) | | | x | | | 23 | `/proc/net/route` через Java `FileInputStream` | блок. | x | x | | **блок.** = SELinux запрещает доступ для обычных приложений (Android 10+). Хуки не нужны. Строки 1–4, 19 и 21 — единственные векторы, доступные обычным приложениям. Всё остальное либо заблокировано SELinux, либо проходит через Java API (покрывается lsposed). ## Сборка из исходников - **kmod**: `cd kmod && make && ./build-zip.sh` — см. [kmod/BUILDING.md](kmod/BUILDING.md) - **zygisk**: `cd zygisk && ./build-zip.sh` (Rust + NDK + cargo-ndk) - **lsposed**: `cd lsposed && ./gradlew assembleDebug` (JDK 17) - **test-app**: `cd test-app && ./gradlew installDebug` (JDK 17 + Rust + NDK) ## Проверено на - [RKNHardering](https://github.com/xtclovver/RKNHardering/) — все векторы обнаружения чисты - [YourVPNDead](https://github.com/loop-uh/yourvpndead) — все векторы обнаружения чисты Оба реализуют официальную методику обнаружения VPN/прокси Минцифры РФ ([источник](https://t.me/ruitunion/893)). ## Раздельное туннелирование (split tunneling) Корректно работает с конфигурациями VPN с раздельным туннелированием. Затрагиваются только приложения из списка целей. Приложения-детекторы, сравнивающие публичный IP устройства с внешними чекерами, требуют раздельного туннелирования — трафик приложения-детектора должен выходить через оператора, а не через туннель. ## Модель угроз vpnhide скрывает активный VPN от конкретных приложений. Он НЕ предназначен для: - Скрытия root или кастомной прошивки - Обхода Play Integrity - Обмана серверной детекции (утечки DNS, чёрные списки IP, фингерпринтинг латентности/TLS) ## Известные ограничения - `kmod` требует GKI-ядро с `CONFIG_KPROBES=y` (стандарт на устройствах Android 12+) - `lsposed` требует LSPosed, LSPosed-Next или Vector - `zygisk` — только arm64 - Прямые системные вызовы `svc #0` обходят хуки libc в zygisk — для этого и нужен kmod - Серверная детекция неисправима на стороне клиента — используйте раздельное туннелирование ## Лицензия MIT. См. [LICENSE](LICENSE). Модуль ядра объявляет `MODULE_LICENSE("GPL")`, как требуется ядром Linux для разрешения символов `EXPORT_SYMBOL_GPL` во время выполнения.