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:
228
scripts/ko_manager.sh
Normal file
228
scripts/ko_manager.sh
Normal file
@@ -0,0 +1,228 @@
|
||||
#!/system/bin/sh
|
||||
# Driver Manager v2 - Kernel Module (.ko) Manager
|
||||
# Load, unload, and manage kernel modules
|
||||
|
||||
MODDIR=${MODDIR:-/data/adb/modules/driver-manager}
|
||||
. "$MODDIR/scripts/core.sh"
|
||||
log_init "$LOGDIR/ko.log"
|
||||
|
||||
MODULESDIR="$MODDIR/modules"
|
||||
AUTOLOAD="$CONFIGDIR/autoload.conf"
|
||||
KERNEL_VER=$(uname -r 2>/dev/null)
|
||||
|
||||
# --- List available .ko files and their status ---
|
||||
list_modules() {
|
||||
echo '{"modules":['
|
||||
local first=true
|
||||
|
||||
# List .ko files in our modules directory
|
||||
for ko in "$MODULESDIR"/*.ko; do
|
||||
[ -f "$ko" ] || continue
|
||||
local name=$(basename "$ko" .ko)
|
||||
local modname=$(modinfo -F name "$ko" 2>/dev/null || echo "$name")
|
||||
local desc=$(modinfo -F description "$ko" 2>/dev/null || echo "")
|
||||
local ver=$(modinfo -F version "$ko" 2>/dev/null || echo "")
|
||||
local author=$(modinfo -F author "$ko" 2>/dev/null || echo "")
|
||||
local depends=$(modinfo -F depends "$ko" 2>/dev/null || echo "")
|
||||
local vermagic=$(modinfo -F vermagic "$ko" 2>/dev/null || echo "")
|
||||
local sz=$(file_size "$ko")
|
||||
|
||||
# Check if loaded
|
||||
local loaded="false"
|
||||
lsmod 2>/dev/null | grep -q "^${modname} " && loaded="true"
|
||||
|
||||
# Check if in autoload
|
||||
local autoload="false"
|
||||
grep -qx "$name.ko" "$AUTOLOAD" 2>/dev/null && autoload="true"
|
||||
|
||||
# Check kernel version compatibility
|
||||
local compatible="unknown"
|
||||
if [ -n "$vermagic" ]; then
|
||||
local mod_kver=$(echo "$vermagic" | awk '{print $1}')
|
||||
[ "$mod_kver" = "$KERNEL_VER" ] && compatible="true" || compatible="false"
|
||||
fi
|
||||
|
||||
[ "$first" = true ] && first=false || echo ","
|
||||
cat << ENTRY
|
||||
{
|
||||
"filename": "$(basename "$ko")",
|
||||
"name": "$modname",
|
||||
"description": "$desc",
|
||||
"version": "$ver",
|
||||
"author": "$author",
|
||||
"depends": "$depends",
|
||||
"vermagic": "$vermagic",
|
||||
"size": $sz,
|
||||
"loaded": $loaded,
|
||||
"autoload": $autoload,
|
||||
"compatible": $compatible
|
||||
}
|
||||
ENTRY
|
||||
done
|
||||
|
||||
echo ']}'
|
||||
}
|
||||
|
||||
# --- Load a kernel module ---
|
||||
load_module() {
|
||||
local ko="$1"
|
||||
local params="$2"
|
||||
|
||||
# Accept either filename or path
|
||||
if [ ! -f "$ko" ]; then
|
||||
ko="$MODULESDIR/$ko"
|
||||
fi
|
||||
if [ ! -f "$ko" ]; then
|
||||
echo '{"status": "error", "message": "Module file not found"}'
|
||||
return 1
|
||||
fi
|
||||
|
||||
local name=$(basename "$ko" .ko)
|
||||
local modname=$(modinfo -F name "$ko" 2>/dev/null || echo "$name")
|
||||
|
||||
# Check if already loaded
|
||||
if lsmod 2>/dev/null | grep -q "^${modname} "; then
|
||||
echo "{\"status\": \"already_loaded\", \"module\": \"$modname\"}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Check kernel version
|
||||
local vermagic=$(modinfo -F vermagic "$ko" 2>/dev/null)
|
||||
if [ -n "$vermagic" ]; then
|
||||
local mod_kver=$(echo "$vermagic" | awk '{print $1}')
|
||||
if [ "$mod_kver" != "$KERNEL_VER" ]; then
|
||||
log_error "Kernel mismatch: module=$mod_kver running=$KERNEL_VER"
|
||||
echo "{\"status\": \"error\", \"message\": \"Kernel version mismatch: module built for $mod_kver, running $KERNEL_VER\"}"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Load dependencies first
|
||||
local depends=$(modinfo -F depends "$ko" 2>/dev/null)
|
||||
if [ -n "$depends" ]; then
|
||||
local IFS=','
|
||||
for dep in $depends; do
|
||||
if ! lsmod 2>/dev/null | grep -q "^${dep} "; then
|
||||
local dep_ko="$MODULESDIR/${dep}.ko"
|
||||
if [ -f "$dep_ko" ]; then
|
||||
log "Loading dependency: $dep"
|
||||
insmod "$dep_ko" 2>> "$LOGDIR/ko.log"
|
||||
else
|
||||
log "Dependency $dep not in modules dir, trying modprobe"
|
||||
modprobe "$dep" 2>> "$LOGDIR/ko.log"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Load the module
|
||||
log "Loading module: $ko $params"
|
||||
local output
|
||||
output=$(insmod "$ko" $params 2>&1)
|
||||
if [ $? -eq 0 ]; then
|
||||
log "Loaded: $modname"
|
||||
# Capture relevant dmesg
|
||||
local dmesg_out=$(dmesg | tail -5 2>/dev/null)
|
||||
echo "{\"status\": \"ok\", \"module\": \"$modname\", \"dmesg\": \"$(echo "$dmesg_out" | tr '\n' '|' | sed 's/"/\\"/g')\"}"
|
||||
else
|
||||
log_error "Failed to load $modname: $output"
|
||||
echo "{\"status\": \"error\", \"module\": \"$modname\", \"message\": \"$(echo "$output" | tr '\n' ' ' | sed 's/"/\\"/g')\"}"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# --- Unload a kernel module ---
|
||||
unload_module() {
|
||||
local name="$1"
|
||||
name=$(echo "$name" | sed 's/\.ko$//')
|
||||
|
||||
if ! lsmod 2>/dev/null | grep -q "^${name} "; then
|
||||
echo "{\"status\": \"not_loaded\", \"module\": \"$name\"}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
log "Unloading module: $name"
|
||||
local output
|
||||
output=$(rmmod "$name" 2>&1)
|
||||
if [ $? -eq 0 ]; then
|
||||
log "Unloaded: $name"
|
||||
echo "{\"status\": \"ok\", \"module\": \"$name\"}"
|
||||
else
|
||||
log_error "Failed to unload $name: $output"
|
||||
echo "{\"status\": \"error\", \"module\": \"$name\", \"message\": \"$(echo "$output" | tr '\n' ' ' | sed 's/"/\\"/g')\"}"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# --- Unload all managed modules ---
|
||||
unload_all() {
|
||||
log "Unloading all managed modules"
|
||||
for ko in "$MODULESDIR"/*.ko; do
|
||||
[ -f "$ko" ] || continue
|
||||
local name=$(basename "$ko" .ko)
|
||||
local modname=$(modinfo -F name "$ko" 2>/dev/null || echo "$name")
|
||||
if lsmod 2>/dev/null | grep -q "^${modname} "; then
|
||||
rmmod "$modname" 2>/dev/null
|
||||
log "Unloaded: $modname"
|
||||
fi
|
||||
done
|
||||
echo '{"status": "ok"}'
|
||||
}
|
||||
|
||||
# --- Get detailed info for a module ---
|
||||
info_module() {
|
||||
local ko="$1"
|
||||
if [ ! -f "$ko" ]; then
|
||||
ko="$MODULESDIR/$ko"
|
||||
fi
|
||||
[ ! -f "$ko" ] && { echo '{"error": "not found"}'; return 1; }
|
||||
|
||||
modinfo "$ko" 2>/dev/null
|
||||
}
|
||||
|
||||
# --- Toggle autoload for a module ---
|
||||
set_autoload() {
|
||||
local ko_filename="$1"
|
||||
local enabled="$2"
|
||||
|
||||
if [ "$enabled" = "true" ] || [ "$enabled" = "1" ]; then
|
||||
if ! grep -qx "$ko_filename" "$AUTOLOAD" 2>/dev/null; then
|
||||
echo "$ko_filename" >> "$AUTOLOAD"
|
||||
log "Autoload enabled: $ko_filename"
|
||||
fi
|
||||
echo "{\"status\": \"ok\", \"autoload\": true, \"module\": \"$ko_filename\"}"
|
||||
else
|
||||
sed -i "/^${ko_filename}$/d" "$AUTOLOAD" 2>/dev/null
|
||||
log "Autoload disabled: $ko_filename"
|
||||
echo "{\"status\": \"ok\", \"autoload\": false, \"module\": \"$ko_filename\"}"
|
||||
fi
|
||||
}
|
||||
|
||||
# --- Load all autoload modules ---
|
||||
autoload_modules() {
|
||||
[ ! -f "$AUTOLOAD" ] && return 0
|
||||
log "Loading autoload modules"
|
||||
|
||||
while IFS= read -r ko; do
|
||||
[ -z "$ko" ] && continue
|
||||
[ "${ko#\#}" != "$ko" ] && continue
|
||||
local kofile="$MODULESDIR/$ko"
|
||||
if [ -f "$kofile" ]; then
|
||||
load_module "$kofile" >/dev/null 2>&1
|
||||
else
|
||||
log_error "Autoload module not found: $ko"
|
||||
fi
|
||||
done < "$AUTOLOAD"
|
||||
}
|
||||
|
||||
# --- Main ---
|
||||
case "$1" in
|
||||
list) list_modules ;;
|
||||
load) load_module "$2" "$3" ;;
|
||||
unload) unload_module "$2" ;;
|
||||
unload_all) unload_all ;;
|
||||
info) info_module "$2" ;;
|
||||
autoload) autoload_modules ;;
|
||||
set_autoload) set_autoload "$2" "$3" ;;
|
||||
*) echo "Usage: ko_manager.sh {list|load|unload|unload_all|info|autoload|set_autoload} [args]" ;;
|
||||
esac
|
||||
Reference in New Issue
Block a user