Driver Manager v2.0.0 - LSPosed-style rewrite
Complete rewrite with: - Per-app driver scoping via mount namespace isolation (LSPosed-style) - System-wide driver mode selection - .ko kernel module manager with autoload and dependency tracking - Driver integrity protection (monitor/enforce modes) - Driver registry with auto-discovery and SHA256 hashing - LSPosed-style dark WebUI with 6 tabs: Dashboard, Drivers, Apps, Modules, Protection, Logs - RESTful API handler for WebUI communication - Zygote process monitor for auto-applying scopes to new app launches Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
309
scripts/driver_registry.sh
Normal file
309
scripts/driver_registry.sh
Normal file
@@ -0,0 +1,309 @@
|
||||
#!/system/bin/sh
|
||||
# Driver Manager v2 - Driver Registry
|
||||
# Discovers, catalogs, and manages system drivers
|
||||
|
||||
MODDIR=${MODDIR:-/data/adb/modules/driver-manager}
|
||||
. "$MODDIR/scripts/core.sh"
|
||||
log_init "$LOGDIR/registry.log"
|
||||
|
||||
REGISTRY="$CONFIGDIR/drivers.json"
|
||||
|
||||
# --- Driver discovery paths by category ---
|
||||
scan_drivers() {
|
||||
log "Starting driver scan"
|
||||
local tmp="$CONFIGDIR/.drivers_tmp.json"
|
||||
|
||||
cat > "$tmp" << 'HEADER'
|
||||
{"drivers":[
|
||||
HEADER
|
||||
|
||||
local first=true
|
||||
|
||||
# GPU drivers
|
||||
for path in /vendor/lib64/egl /vendor/lib/egl /system/lib64/egl; do
|
||||
[ -d "$path" ] || continue
|
||||
for f in "$path"/lib*.so; do
|
||||
[ -f "$f" ] || continue
|
||||
local name=$(basename "$f" .so)
|
||||
local hash=$(sha256 "$f")
|
||||
local ctx=$(get_selinux_context "$f")
|
||||
local sz=$(file_size "$f")
|
||||
[ "$first" = true ] && first=false || echo "," >> "$tmp"
|
||||
cat >> "$tmp" << ENTRY
|
||||
{
|
||||
"id": "gpu-$name",
|
||||
"name": "$name",
|
||||
"category": "gpu",
|
||||
"path": "$f",
|
||||
"hash": "$hash",
|
||||
"selinux": "$ctx",
|
||||
"size": $sz,
|
||||
"protected": true,
|
||||
"variants": [{"name": "stock", "path": "$f", "hash": "$hash", "active": true}]
|
||||
}
|
||||
ENTRY
|
||||
done
|
||||
done
|
||||
|
||||
# Vulkan ICD
|
||||
for path in /vendor/lib64/hw /vendor/lib/hw; do
|
||||
[ -d "$path" ] || continue
|
||||
for f in "$path"/vulkan.*.so; do
|
||||
[ -f "$f" ] || continue
|
||||
local name=$(basename "$f" .so)
|
||||
local hash=$(sha256 "$f")
|
||||
local ctx=$(get_selinux_context "$f")
|
||||
local sz=$(file_size "$f")
|
||||
[ "$first" = true ] && first=false || echo "," >> "$tmp"
|
||||
cat >> "$tmp" << ENTRY
|
||||
{
|
||||
"id": "vulkan-$name",
|
||||
"name": "$name",
|
||||
"category": "gpu",
|
||||
"path": "$f",
|
||||
"hash": "$hash",
|
||||
"selinux": "$ctx",
|
||||
"size": $sz,
|
||||
"protected": true,
|
||||
"variants": [{"name": "stock", "path": "$f", "hash": "$hash", "active": true}]
|
||||
}
|
||||
ENTRY
|
||||
done
|
||||
done
|
||||
|
||||
# WiFi firmware
|
||||
for path in /vendor/firmware /vendor/etc/wifi /lib/firmware; do
|
||||
[ -d "$path" ] || continue
|
||||
for f in "$path"/fw_bcm*.bin "$path"/fw_wcn*.bin "$path"/wlan_*.bin; do
|
||||
[ -f "$f" ] || continue
|
||||
local name=$(basename "$f")
|
||||
local hash=$(sha256 "$f")
|
||||
local ctx=$(get_selinux_context "$f")
|
||||
local sz=$(file_size "$f")
|
||||
[ "$first" = true ] && first=false || echo "," >> "$tmp"
|
||||
cat >> "$tmp" << ENTRY
|
||||
{
|
||||
"id": "wifi-$name",
|
||||
"name": "$name",
|
||||
"category": "wifi",
|
||||
"path": "$f",
|
||||
"hash": "$hash",
|
||||
"selinux": "$ctx",
|
||||
"size": $sz,
|
||||
"protected": true,
|
||||
"variants": [{"name": "stock", "path": "$f", "hash": "$hash", "active": true}]
|
||||
}
|
||||
ENTRY
|
||||
done
|
||||
done
|
||||
|
||||
# Bluetooth firmware
|
||||
for path in /vendor/firmware /vendor/etc/bluetooth /lib/firmware; do
|
||||
[ -d "$path" ] || continue
|
||||
for f in "$path"/*.hcd "$path"/bt_fw*.bin "$path"/BCM*.hcd; do
|
||||
[ -f "$f" ] || continue
|
||||
local name=$(basename "$f")
|
||||
local hash=$(sha256 "$f")
|
||||
local ctx=$(get_selinux_context "$f")
|
||||
local sz=$(file_size "$f")
|
||||
[ "$first" = true ] && first=false || echo "," >> "$tmp"
|
||||
cat >> "$tmp" << ENTRY
|
||||
{
|
||||
"id": "bt-$name",
|
||||
"name": "$name",
|
||||
"category": "bluetooth",
|
||||
"path": "$f",
|
||||
"hash": "$hash",
|
||||
"selinux": "$ctx",
|
||||
"size": $sz,
|
||||
"protected": true,
|
||||
"variants": [{"name": "stock", "path": "$f", "hash": "$hash", "active": true}]
|
||||
}
|
||||
ENTRY
|
||||
done
|
||||
done
|
||||
|
||||
# Audio HAL
|
||||
for path in /vendor/lib64/hw /vendor/lib/hw; do
|
||||
[ -d "$path" ] || continue
|
||||
for f in "$path"/audio*.so; do
|
||||
[ -f "$f" ] || continue
|
||||
local name=$(basename "$f" .so)
|
||||
local hash=$(sha256 "$f")
|
||||
local ctx=$(get_selinux_context "$f")
|
||||
local sz=$(file_size "$f")
|
||||
[ "$first" = true ] && first=false || echo "," >> "$tmp"
|
||||
cat >> "$tmp" << ENTRY
|
||||
{
|
||||
"id": "audio-$name",
|
||||
"name": "$name",
|
||||
"category": "audio",
|
||||
"path": "$f",
|
||||
"hash": "$hash",
|
||||
"selinux": "$ctx",
|
||||
"size": $sz,
|
||||
"protected": true,
|
||||
"variants": [{"name": "stock", "path": "$f", "hash": "$hash", "active": true}]
|
||||
}
|
||||
ENTRY
|
||||
done
|
||||
done
|
||||
|
||||
# Camera HAL
|
||||
for path in /vendor/lib64/hw /vendor/lib/hw; do
|
||||
[ -d "$path" ] || continue
|
||||
for f in "$path"/camera*.so; do
|
||||
[ -f "$f" ] || continue
|
||||
local name=$(basename "$f" .so)
|
||||
local hash=$(sha256 "$f")
|
||||
local ctx=$(get_selinux_context "$f")
|
||||
local sz=$(file_size "$f")
|
||||
[ "$first" = true ] && first=false || echo "," >> "$tmp"
|
||||
cat >> "$tmp" << ENTRY
|
||||
{
|
||||
"id": "camera-$name",
|
||||
"name": "$name",
|
||||
"category": "camera",
|
||||
"path": "$f",
|
||||
"hash": "$hash",
|
||||
"selinux": "$ctx",
|
||||
"size": $sz,
|
||||
"protected": false,
|
||||
"variants": [{"name": "stock", "path": "$f", "hash": "$hash", "active": true}]
|
||||
}
|
||||
ENTRY
|
||||
done
|
||||
done
|
||||
|
||||
# Sensor HAL
|
||||
for path in /vendor/lib64/hw /vendor/lib/hw; do
|
||||
[ -d "$path" ] || continue
|
||||
for f in "$path"/sensors*.so; do
|
||||
[ -f "$f" ] || continue
|
||||
local name=$(basename "$f" .so)
|
||||
local hash=$(sha256 "$f")
|
||||
local ctx=$(get_selinux_context "$f")
|
||||
local sz=$(file_size "$f")
|
||||
[ "$first" = true ] && first=false || echo "," >> "$tmp"
|
||||
cat >> "$tmp" << ENTRY
|
||||
{
|
||||
"id": "sensor-$name",
|
||||
"name": "$name",
|
||||
"category": "sensor",
|
||||
"path": "$f",
|
||||
"hash": "$hash",
|
||||
"selinux": "$ctx",
|
||||
"size": $sz,
|
||||
"protected": false,
|
||||
"variants": [{"name": "stock", "path": "$f", "hash": "$hash", "active": true}]
|
||||
}
|
||||
ENTRY
|
||||
done
|
||||
done
|
||||
|
||||
# Kernel modules currently loaded
|
||||
if [ -f /proc/modules ]; then
|
||||
while read -r name rest; do
|
||||
[ "$first" = true ] && first=false || echo "," >> "$tmp"
|
||||
cat >> "$tmp" << ENTRY
|
||||
{
|
||||
"id": "kmod-$name",
|
||||
"name": "$name",
|
||||
"category": "kernel",
|
||||
"path": "/proc/modules",
|
||||
"hash": "",
|
||||
"selinux": "",
|
||||
"size": 0,
|
||||
"protected": false,
|
||||
"variants": [{"name": "loaded", "path": "", "hash": "", "active": true}]
|
||||
}
|
||||
ENTRY
|
||||
done < /proc/modules
|
||||
fi
|
||||
|
||||
echo "" >> "$tmp"
|
||||
echo "]}" >> "$tmp"
|
||||
|
||||
mv "$tmp" "$REGISTRY"
|
||||
log "Driver scan complete"
|
||||
}
|
||||
|
||||
# --- Count drivers ---
|
||||
count_drivers() {
|
||||
if [ -f "$REGISTRY" ]; then
|
||||
grep -c '"id"' "$REGISTRY" 2>/dev/null || echo "0"
|
||||
else
|
||||
echo "0"
|
||||
fi
|
||||
}
|
||||
|
||||
# --- List drivers as JSON ---
|
||||
list_drivers() {
|
||||
[ -f "$REGISTRY" ] && cat "$REGISTRY" || echo '{"drivers":[]}'
|
||||
}
|
||||
|
||||
# --- Get single driver info ---
|
||||
get_driver() {
|
||||
local id="$1"
|
||||
if [ -f "$REGISTRY" ]; then
|
||||
# Extract the driver block matching the id
|
||||
awk -v id="$id" '
|
||||
/"id".*:.*"/ { found = ($0 ~ "\"" id "\"") }
|
||||
found && /\{/ { depth++ }
|
||||
found && depth > 0 { print }
|
||||
found && /\}/ { depth--; if (depth == 0) { found=0 } }
|
||||
' "$REGISTRY"
|
||||
fi
|
||||
}
|
||||
|
||||
# --- Add a custom variant to a driver ---
|
||||
add_variant() {
|
||||
local driver_id="$1"
|
||||
local variant_name="$2"
|
||||
local variant_path="$3"
|
||||
|
||||
if [ ! -f "$variant_path" ]; then
|
||||
echo '{"error": "Variant file not found"}'
|
||||
return 1
|
||||
fi
|
||||
|
||||
local hash=$(sha256 "$variant_path")
|
||||
log "Adding variant '$variant_name' to driver '$driver_id': $variant_path (hash: $hash)"
|
||||
|
||||
# Copy variant to drivers directory
|
||||
local dest="$MODDIR/drivers/${driver_id}_${variant_name}_$(basename "$variant_path")"
|
||||
cp "$variant_path" "$dest"
|
||||
chmod 644 "$dest"
|
||||
|
||||
echo "{\"status\": \"ok\", \"driver\": \"$driver_id\", \"variant\": \"$variant_name\", \"path\": \"$dest\", \"hash\": \"$hash\"}"
|
||||
}
|
||||
|
||||
# --- Verify a driver's current hash matches registry ---
|
||||
verify_driver() {
|
||||
local id="$1"
|
||||
local reg_path=$(grep -A5 "\"$id\"" "$REGISTRY" 2>/dev/null | grep '"path"' | head -1 | sed 's/.*: *"\([^"]*\)".*/\1/')
|
||||
local reg_hash=$(grep -A5 "\"$id\"" "$REGISTRY" 2>/dev/null | grep '"hash"' | head -1 | sed 's/.*: *"\([^"]*\)".*/\1/')
|
||||
|
||||
if [ -z "$reg_path" ] || [ -z "$reg_hash" ]; then
|
||||
echo '{"status": "unknown", "reason": "driver not in registry"}'
|
||||
return 1
|
||||
fi
|
||||
|
||||
local cur_hash=$(sha256 "$reg_path")
|
||||
if [ "$cur_hash" = "$reg_hash" ]; then
|
||||
echo "{\"status\": \"ok\", \"driver\": \"$id\", \"hash\": \"$cur_hash\"}"
|
||||
else
|
||||
echo "{\"status\": \"changed\", \"driver\": \"$id\", \"expected\": \"$reg_hash\", \"actual\": \"$cur_hash\"}"
|
||||
fi
|
||||
}
|
||||
|
||||
# --- Main ---
|
||||
case "$1" in
|
||||
scan) scan_drivers ;;
|
||||
count) count_drivers ;;
|
||||
list) list_drivers ;;
|
||||
get) get_driver "$2" ;;
|
||||
add_variant) add_variant "$2" "$3" "$4" ;;
|
||||
verify) verify_driver "$2" ;;
|
||||
*) echo "Usage: driver_registry.sh {scan|count|list|get|add_variant|verify} [args]" ;;
|
||||
esac
|
||||
Reference in New Issue
Block a user