vpnhide/lsposed
okhsunrog b21df83d6b feat(lsposed): auto-enable debug logging during diagnostic captures
The off-by-default toggle silenced VpnHide logs everywhere — which
silently broke the two diagnostic capture paths that bug reports
actually depend on: Start recording would share a logcat with zero
VpnHide-tagged lines, and Collect debug log would zip up a useless
`logcat.txt` stub.

Extract applyDebugLoggingRuntime() that pushes the flag to runtime
sinks (VpnHideLog.enabled + the two flag files) without writing
SharedPreferences. exportDebugZip and LogcatRecorder.start call it to
force-enable on entry when the persisted preference is OFF; on exit
they reconcile against the current SharedPreferences state so a user
who flipped the UI toggle mid-capture wins over the rollback.

Rewrites the toggle's description string to reflect that users don't
need to touch it for one-off bug reports — the capture buttons handle
it — and keep the toggle as an escape hatch for "emit logs
continuously" cases.
2026-04-18 01:23:21 +03:00
..
app feat(lsposed): auto-enable debug logging during diagnostic captures 2026-04-18 01:23:21 +03:00
gradle feat: replace lsposed status screen with Compose target picker UI 2026-04-12 02:42:23 +03:00
native feat: debug logging toggle, off by default 2026-04-17 19:09:07 +03:00
build.gradle.kts feat: replace lsposed status screen with Compose target picker UI 2026-04-12 02:42:23 +03:00
gradle.properties monorepo: combine vpnhide-zygisk, vpnhide (lsposed), and vpnhide-kmod 2026-04-11 15:01:49 +03:00
gradlew monorepo: combine vpnhide-zygisk, vpnhide (lsposed), and vpnhide-kmod 2026-04-11 15:01:49 +03:00
gradlew.bat monorepo: combine vpnhide-zygisk, vpnhide (lsposed), and vpnhide-kmod 2026-04-11 15:01:49 +03:00
README.md refactor: drop WebUI and action.sh from kmod and zygisk modules 2026-04-13 16:28:39 +03:00
settings.gradle.kts monorepo: combine vpnhide-zygisk, vpnhide (lsposed), and vpnhide-kmod 2026-04-11 15:01:49 +03:00

vpnhide -- LSPosed module + target picker app

Hooks writeToParcel() in system_server to strip VPN data before Binder serialization reaches target apps. Part of vpnhide.

The APK also serves as the target management UI for the entire vpnhide project — it writes targets for both kmod and zygisk modules.

Zero presence in the target app's process -- only "System Framework" is needed in the LSPosed scope.

What it hooks

writeToParcel() on three classes inside system_server:

Class Effect
NetworkCapabilities VPN transport and capability flags stripped before serialization. Covers hasTransport(VPN), getAllNetworks() + VPN scan, getTransportInfo().
NetworkInfo VPN type rewritten to WIFI before serialization
LinkProperties VPN interface name and routes stripped before serialization

Uses a ThreadLocal save/restore pattern so the original values are preserved for non-target callers.

Per-UID filtering

Filtering is controlled by Binder.getCallingUid() -- only apps whose UID appears in the target list see the filtered view. System services, VPN clients, and everything else see real data.

Target management

Target UIDs are loaded from /data/system/vpnhide_uids.txt. A FileObserver (inotify) watches for changes and reloads the list immediately -- no reboot needed.

This file is written by:

  • The VPN Hide app (this APK's target picker UI)
  • The module's service.sh on boot

Target picker app

The APK includes a Compose UI for managing target apps across all vpnhide modules:

  • Lists all installed apps with icons, names, and package names
  • Text search filter
  • System apps toggle (selected system apps always visible)
  • Save writes to all target locations via su:
    • /data/adb/vpnhide_kmod/targets.txt (if kmod is installed)
    • /data/adb/vpnhide_zygisk/targets.txt (if zygisk is installed)
    • /data/adb/modules/vpnhide_zygisk/targets.txt (Magisk module dir copy)
    • /proc/vpnhide_targets (kmod live update, no reboot needed)
    • /data/system/vpnhide_uids.txt (system_server hooks, live reload via inotify)

Works on KernelSU, Magisk, and any other root solution.

Install

  1. Build the APK (./gradlew assembleDebug).
  2. Install: adb install app/build/outputs/apk/debug/app-debug.apk.
  3. Open LSPosed/Vector manager, go to Modules, enable VPN Hide.
  4. Add "System Framework" to the module's scope. No other apps should be in scope.
  5. Reboot.
  6. Open the VPN Hide app to manage target apps.

Combined use with kmod

For apps with aggressive anti-tamper SDKs, full VPN hiding requires covering both native and Java API paths without any hooks in the target app's process:

  • kmod covers native: ioctl, getifaddrs (netlink), /proc/net/route.
  • This module covers Java APIs: NetworkCapabilities, NetworkInfo, LinkProperties via writeToParcel() in system_server.

Together they provide complete VPN hiding with zero footprint in the target process.

Debugging

adb logcat | grep VpnHide

Build

./gradlew assembleDebug

Requires JDK 17. Output: app/build/outputs/apk/debug/app-debug.apk.

License

MIT. See LICENSE.