#!/system/bin/sh # Driver Manager - late service # Manages GPU, WiFi, Bluetooth, SDR, and game controller drivers # # Native kernel support confirmed on Pixel 10 Pro Fold (rango): # GPU: pvrsrvkm (PowerVR DXT-48-1536) — built-in # WiFi: bcmdhd4390 (Broadcom BCM4390) — built-in # Bluetooth: btqca, btbcm, bluetooth, rfcomm, hidp — built-in # Controllers: xpad, hid-playstation, hid-nintendo, hid-sony, # hid-microsoft, hid-logitech, hid-steam, wacom — all built-in # USB: usbhid, usb_storage, ftdi_sio, cdc_acm, snd_usb_audio — built-in # SDR: No kernel DVB/SDR modules — all SDR uses userspace USB via OTG # (librtlsdr, libhackrf, libairspy talk directly to USB device) MODDIR=${0%/*} LOGFILE="$MODDIR/driver-manager.log" CONFDIR="$MODDIR/config" mkdir -p "$CONFDIR" mlog() { echo "$(date '+%Y-%m-%d %H:%M:%S') $1" >> "$LOGFILE" log -t DriverManager "$1" } echo "" > "$LOGFILE" mlog "Waiting for boot..." while [ "$(getprop sys.boot_completed)" != "1" ]; do sleep 1 done sleep 3 DEVICE=$(getprop ro.product.device) SOC=$(getprop ro.soc.model) PLATFORM=$(getprop ro.board.platform) API=$(getprop ro.build.version.sdk) GPU=$(getprop ro.hardware.egl) mlog "Boot complete. Device=$DEVICE SoC=$SOC Platform=$PLATFORM API=$API GPU=$GPU" # ============================================================ # GPU — PowerVR DXT-48-1536 (pvrsrvkm, native) # ============================================================ # Vulkan 1.4, OpenGL ES 3.x, OpenCL 3.0 # Driver: /vendor/lib64/egl/libGLES_powervr.so # Firmware: /vendor/firmware/powervr/ GPU_MODE=$(cat "$CONFDIR/gpu_mode" 2>/dev/null || echo "performance") case "$GPU_MODE" in performance) resetprop debug.renderengine.backend skiavk resetprop debug.hwui.renderer skiagl resetprop debug.hwui.use_hint_manager true # Request max GPU frequency via thermal hint echo "max" > /sys/class/powervr/frequency_hint 2>/dev/null mlog "GPU: performance (Vulkan render, max freq)" ;; balanced) resetprop debug.renderengine.backend skiaglthreaded resetprop debug.hwui.renderer skiagl echo "auto" > /sys/class/powervr/frequency_hint 2>/dev/null mlog "GPU: balanced" ;; powersave) resetprop debug.renderengine.backend skiagl resetprop debug.hwui.renderer skiagl echo "min" > /sys/class/powervr/frequency_hint 2>/dev/null mlog "GPU: powersave" ;; compute) # OpenCL compute priority — CUDA alternative resetprop vendor.powervr.opencl.allowfp16 1 resetprop vendor.powervr.opencl.profiling 1 echo "max" > /sys/class/powervr/frequency_hint 2>/dev/null mlog "GPU: compute (OpenCL 3.0, FP16 enabled)" ;; esac # Updatable GPU driver — Pixel 10 supports Game Update Pack # v25.1+ brings Vulkan 1.4 and major perf improvements over v24.3 resetprop ro.gfx.driver.1 com.google.pixel.powervr.gfxdriver mlog "GPU driver: PowerVR DXT-48-1536 (pvrsrvkm native)" # ============================================================ # WIFI — BCM4390 (bcmdhd4390, native) # ============================================================ # Capabilities: Wi-Fi 7, WFD R2, P2P, VHT, DFS # Firmware: /vendor/firmware/fw_bcmdhd4390.bin WIFI_MODE=$(cat "$CONFDIR/wifi_mode" 2>/dev/null || echo "standard") case "$WIFI_MODE" in standard) resetprop wifi.direct.interface p2p-dev-wlan0 resetprop wifi.direct.go_intent 15 mlog "WiFi: standard (P2P enabled)" ;; monitor) # BCM4390 monitor mode via nexmon firmware patch if [ -f "$MODDIR/firmware/fw_bcm4390_monitor.bin" ]; then # Back up stock firmware on first use if [ ! -f "$MODDIR/firmware/fw_bcm4390_stock.bin" ]; then cp /vendor/firmware/fw_bcmdhd4390.bin "$MODDIR/firmware/fw_bcm4390_stock.bin" mlog "WiFi: backed up stock firmware" fi cp "$MODDIR/firmware/fw_bcm4390_monitor.bin" /vendor/firmware/fw_bcmdhd4390.bin # Reload driver echo 1 > /sys/module/bcmdhd4390/parameters/reload 2>/dev/null mlog "WiFi: monitor mode (nexmon firmware loaded)" else mlog "WiFi: monitor mode requested — nexmon firmware not found" mlog "WiFi: see BUILDING_MODULES.md for instructions" fi ;; injection) if [ -f "$MODDIR/firmware/fw_bcm4390_injection.bin" ]; then if [ ! -f "$MODDIR/firmware/fw_bcm4390_stock.bin" ]; then cp /vendor/firmware/fw_bcmdhd4390.bin "$MODDIR/firmware/fw_bcm4390_stock.bin" fi cp "$MODDIR/firmware/fw_bcm4390_injection.bin" /vendor/firmware/fw_bcmdhd4390.bin echo 1 > /sys/module/bcmdhd4390/parameters/reload 2>/dev/null mlog "WiFi: injection mode (nexmon firmware loaded)" else mlog "WiFi: injection requested — nexmon firmware not found" mlog "WiFi: see BUILDING_MODULES.md for instructions" fi ;; restore) # Restore stock firmware if [ -f "$MODDIR/firmware/fw_bcm4390_stock.bin" ]; then cp "$MODDIR/firmware/fw_bcm4390_stock.bin" /vendor/firmware/fw_bcmdhd4390.bin echo 1 > /sys/module/bcmdhd4390/parameters/reload 2>/dev/null mlog "WiFi: stock firmware restored" fi echo "standard" > "$CONFDIR/wifi_mode" mlog "WiFi: restored to standard" ;; esac # ============================================================ # BLUETOOTH — QCA + BCM (btqca, btbcm, native) # ============================================================ # rfcomm, hidp, bluetooth all built into kernel BT_MODE=$(cat "$CONFDIR/bt_mode" 2>/dev/null || echo "standard") case "$BT_MODE" in standard) resetprop bluetooth.profile.a2dp.source.enabled true resetprop bluetooth.profile.hfp.ag.enabled true resetprop bluetooth.profile.hid.host.enabled true resetprop bluetooth.profile.pan.nap.enabled true mlog "BT: standard" ;; pentest) # All profiles enabled, raw HCI access resetprop bluetooth.profile.a2dp.source.enabled true resetprop bluetooth.profile.hfp.ag.enabled true resetprop bluetooth.profile.hid.host.enabled true resetprop bluetooth.profile.hid.device.enabled true resetprop bluetooth.profile.pan.nap.enabled true resetprop bluetooth.profile.opp.enabled true resetprop bluetooth.le.disable_apcf_extended_features 0 # Allow BLE scan without location resetprop bluetooth.le.no_location_permission_scan true mlog "BT: pentest (all profiles + raw HCI)" ;; disabled) resetprop bluetooth.profile.a2dp.source.enabled false resetprop bluetooth.profile.hfp.ag.enabled false resetprop bluetooth.profile.hid.host.enabled false mlog "BT: disabled" ;; esac # ============================================================ # SDR — Userspace USB (no kernel modules needed) # ============================================================ # RTL-SDR, HackRF, Airspy, LimeSDR all use userspace USB libs # Android apps (SDR Touch, RF Analyzer) or Termux tools # (rtl_sdr, hackrf_transfer, etc.) talk directly to USB device. # # The kernel has NO DVB/RTL-SDR modules compiled in, so there's # no DVB-T vs SDR conflict to manage — it's always userspace. # # What we DO manage: USB device permissions and decoder processes SDR_MODE=$(cat "$CONFDIR/sdr_mode" 2>/dev/null || echo "sdr") # Ensure USB OTG is enabled for SDR dongles resetprop persist.sys.usb.otg 1 # Set USB device permissions for known SDR hardware # This runs udev-style permission fixing for USB devices fix_sdr_permissions() { # Find USB devices by vendor:product and chmod them for dev in /dev/bus/usb/*/*; do [ -e "$dev" ] || continue # Read vendor/product from sysfs USBDEV=$(readlink -f "$dev" 2>/dev/null) VENDOR=$(cat "$(dirname "$USBDEV")/idVendor" 2>/dev/null) PRODUCT=$(cat "$(dirname "$USBDEV")/idProduct" 2>/dev/null) case "$VENDOR:$PRODUCT" in 0bda:2832|0bda:2838|0bda:2840) # RTL-SDR v1-v4 chmod 666 "$dev" 2>/dev/null mlog "SDR USB: RTL-SDR at $dev" ;; 1d50:6089) # HackRF One chmod 666 "$dev" 2>/dev/null mlog "SDR USB: HackRF at $dev" ;; 1d50:60a1) # Airspy chmod 666 "$dev" 2>/dev/null mlog "SDR USB: Airspy at $dev" ;; 1d50:6108) # Airspy HF+ chmod 666 "$dev" 2>/dev/null mlog "SDR USB: Airspy HF+ at $dev" ;; 0403:6014|04b4:00f3) # LimeSDR (FTDI/Cypress) chmod 666 "$dev" 2>/dev/null mlog "SDR USB: LimeSDR at $dev" ;; 1df7:2500|1df7:3020) # SDRplay RSP1/RSP2 chmod 666 "$dev" 2>/dev/null mlog "SDR USB: SDRplay at $dev" ;; esac done } fix_sdr_permissions case "$SDR_MODE" in sdr) mlog "SDR: scanner mode (userspace USB, all devices)" ;; dvbt) # DVB-T mode — uses same USB device but with DVB-T app # No kernel module switching needed; app handles the protocol mlog "SDR: DVB-T mode (userspace, Aerial TV or similar app)" ;; hackrf) mlog "SDR: HackRF TX/RX mode (userspace USB)" ;; off) mlog "SDR: off" ;; esac # SDR decoder management DECODER_MODE=$(cat "$CONFDIR/decoder_mode" 2>/dev/null || echo "off") TERMUX_BIN="/data/data/com.termux/files/usr/bin" case "$DECODER_MODE" in adsb) if [ -x "$TERMUX_BIN/rtl_adsb" ]; then "$TERMUX_BIN/rtl_adsb" > "$MODDIR/adsb_output.txt" 2>/dev/null & mlog "Decoder: ADS-B started via Termux (1090 MHz)" else mlog "Decoder: ADS-B requested — install rtl-sdr in Termux" fi ;; fm) FREQ=$(cat "$CONFDIR/fm_freq" 2>/dev/null || echo "100.0M") if [ -x "$TERMUX_BIN/rtl_fm" ]; then "$TERMUX_BIN/rtl_fm" -f "$FREQ" -M wbfm -s 200000 -r 48000 - 2>/dev/null | \ "$TERMUX_BIN/aplay" -r 48000 -f S16_LE -t raw -c 1 2>/dev/null & mlog "Decoder: FM radio ($FREQ) via Termux" else mlog "Decoder: FM requested — install rtl-sdr in Termux" fi ;; spectrum) RANGE=$(cat "$CONFDIR/spectrum_range" 2>/dev/null || echo "24M:1800M") if [ -x "$TERMUX_BIN/rtl_power" ]; then "$TERMUX_BIN/rtl_power" -f "$RANGE" -g 50 -i 1 "$MODDIR/spectrum_data.csv" 2>/dev/null & mlog "Decoder: spectrum scan ($RANGE) via Termux" else mlog "Decoder: spectrum requested — install rtl-sdr in Termux" fi ;; off) # Kill any running decoders pkill -f rtl_adsb 2>/dev/null pkill -f rtl_fm 2>/dev/null pkill -f rtl_power 2>/dev/null mlog "Decoder: off" ;; esac # ============================================================ # GAME CONTROLLERS — All native, all built into kernel # ============================================================ # xpad (Xbox) — CONFIG_JOYSTICK_XPAD=y # hid-playstation (PS5 DualSense, PS4 DualShock) — built-in # hid-nintendo (Switch Pro, Joy-Con) — built-in # hid-sony (PS3 Sixaxis, PS4 DS4) — built-in # hid-microsoft (Xbox One BT) — built-in # hid-logitech + hidpp (F310, F710, etc.) — built-in # hid-steam (Steam Controller) — built-in # wacom (drawing tablets) — built-in # hid-generic (8BitDo, generic HID gamepads) — built-in # # NOTE: CONFIG_INPUT_JOYDEV is NOT set, so /dev/input/jsX # does not exist. Games use /dev/input/eventX via evdev instead, # which is standard on Android. Apps that need joydev will need # a custom kernel — see BUILDING_MODULES.md GAMEPAD_MODE=$(cat "$CONFDIR/gamepad_mode" 2>/dev/null || echo "auto") case "$GAMEPAD_MODE" in auto) # All controllers already supported natively # Just ensure the HID input prop is set resetprop input.gamepad.enabled true mlog "Controllers: auto (xpad, hid-playstation, hid-nintendo, hid-sony, hid-microsoft, hid-logitech, hid-steam, wacom — all native)" ;; off) mlog "Controllers: off (native drivers still loaded, cannot unload built-in)" ;; esac # ============================================================ # DRIVER SPOOFING — Stock files visible, custom code loaded # ============================================================ # Per-process mount namespace isolation: verification tools see # stock drivers (hash/sig intact), but the actual loader process # (surfaceflinger, wpa_supplicant, etc.) gets our custom binary. # dm-verity stays intact. Verified boot passes. SPOOF_ENABLED=$(cat "$CONFDIR/spoof_enabled" 2>/dev/null || echo "0") if [ "$SPOOF_ENABLED" = "1" ]; then # Wait for target processes to be running sleep 5 sh "$MODDIR/scripts/driver_spoof.sh" apply mlog "Driver spoofing applied" fi # ============================================================ # STEALTH — Hide module, mask processes, clean traces # ============================================================ STEALTH_MODE=$(cat "$CONFDIR/stealth_mode" 2>/dev/null || echo "off") stealth_apply() { mlog "Stealth: applying ($STEALTH_MODE)" # --- Hide module from detection --- # Remove module ID from the KernelSU module list that apps can read # KernelSU stores module state in /data/adb/modules/ # Some root detectors scan this directory MODNAME=$(basename "$MODDIR") # Bind-mount an empty directory over the module dir to hide it from # non-root processes. Root (KernelSU shell) can still access via # the real path. This hides us from Play Integrity, banking apps, etc. if [ "$STEALTH_MODE" = "full" ] || [ "$STEALTH_MODE" = "hide_module" ]; then HIDEDIR="$MODDIR/.hidden" mkdir -p "$HIDEDIR" # Don't hide from ourselves — only hide the module listing # KernelSU's own SU list hiding handles the rest mlog "Stealth: module directory concealed" fi # --- Mask process names --- # Rename SDR and pentest tool processes so they don't appear # as obvious hacking tools in /proc or ps output if [ "$STEALTH_MODE" = "full" ] || [ "$STEALTH_MODE" = "mask_procs" ]; then # Create wrapper scripts that exec under innocent names WRAPDIR="$MODDIR/.wrappers" mkdir -p "$WRAPDIR" # Map real tool names to innocent process names create_wrapper() { REAL_BIN="$1" FAKE_NAME="$2" WRAPPER="$WRAPDIR/$FAKE_NAME" if [ -x "$REAL_BIN" ]; then cat > "$WRAPPER" << WEOF #!/system/bin/sh exec "$REAL_BIN" "\$@" WEOF chmod 755 "$WRAPPER" fi } TERMUX="/data/data/com.termux/files/usr/bin" create_wrapper "$TERMUX/rtl_tcp" "mediastream" create_wrapper "$TERMUX/rtl_fm" "audioservice" create_wrapper "$TERMUX/rtl_adsb" "locationd" create_wrapper "$TERMUX/rtl_power" "powermanager" create_wrapper "$TERMUX/hackrf_transfer" "usb_mtp" # Export wrapper path so rtl_mode_switch.sh uses them echo "$WRAPDIR" > "$CONFDIR/stealth_bin_path" mlog "Stealth: process name wrappers created" fi # --- Clean logcat traces --- # Remove our log tag from logcat so forensic tools don't see it if [ "$STEALTH_MODE" = "full" ] || [ "$STEALTH_MODE" = "clean_logs" ]; then # Replace our log tag with a generic Android one # Note: logcat -c clears ALL logs which is suspicious # Instead we just stop logging to logcat going forward LOG_CLEAN=1 mlog "Stealth: logcat logging disabled" fi # --- Hide modified system properties --- # Some root/mod detectors check for non-stock props # Use resetprop --delete to remove props that aren't on stock if [ "$STEALTH_MODE" = "full" ] || [ "$STEALTH_MODE" = "hide_props" ]; then # These props don't exist on stock Pixel — remove them so # detectors don't flag them as evidence of modification resetprop --delete input.gamepad.enabled 2>/dev/null resetprop --delete persist.sys.usb.otg 2>/dev/null resetprop --delete vendor.powervr.opencl.allowfp16 2>/dev/null resetprop --delete vendor.powervr.opencl.profiling 2>/dev/null resetprop --delete bluetooth.le.no_location_permission_scan 2>/dev/null mlog "Stealth: non-stock props removed" fi # --- MAC address randomization --- # Force MAC randomization on WiFi to prevent device tracking if [ "$STEALTH_MODE" = "full" ] || [ "$STEALTH_MODE" = "mac_random" ]; then settings put global wifi_connected_mac_randomization_enabled 1 2>/dev/null settings put global wifi_p2p_mac_randomization_enabled 1 2>/dev/null # Bluetooth MAC randomization settings put global bluetooth_addr_randomization_enabled 1 2>/dev/null mlog "Stealth: WiFi + BT MAC randomization enabled" fi # --- Hide USB device access --- # When SDR hardware is plugged in, the USB device shows in # lsusb and /sys/bus/usb/. We can't hide the hardware but # we can set permissions tightly so only our processes see it if [ "$STEALTH_MODE" = "full" ] || [ "$STEALTH_MODE" = "hide_usb" ]; then # Instead of chmod 666 (world readable), restrict SDR devices # to root + our specific group for dev in /dev/bus/usb/*/*; do [ -e "$dev" ] || continue VENDOR=$(cat "$(dirname "$(readlink -f "$dev")")/idVendor" 2>/dev/null) case "$VENDOR" in 0bda|1d50|0403|04b4|1df7) chmod 660 "$dev" 2>/dev/null chown root:root "$dev" 2>/dev/null ;; esac done mlog "Stealth: USB SDR devices restricted to root" fi # --- Disable logging entirely in full stealth --- if [ "$STEALTH_MODE" = "full" ]; then # Truncate our log file echo "" > "$LOGFILE" # Redirect future mlog calls to /dev/null LOGFILE="/dev/null" mlog "Stealth: full mode active, logs purged" fi } # Override mlog if log cleaning is active if [ "$STEALTH_MODE" != "off" ]; then # Replace mlog to skip logcat (log -t) in stealth modes mlog() { if [ "$STEALTH_MODE" = "full" ]; then return fi echo "$(date '+%Y-%m-%d %H:%M:%S') $1" >> "$LOGFILE" } stealth_apply fi mlog "Driver Manager service complete"