Skip to content

Instantly share code, notes, and snippets.

@startergo
Forked from joevt/KextUtil.sh
Created February 5, 2023 14:33
Show Gist options
  • Save startergo/278ae604b88665164ac6fbed2c68a8ae to your computer and use it in GitHub Desktop.
Save startergo/278ae604b88665164ac6fbed2c68a8ae to your computer and use it in GitHub Desktop.
Commands for kexts
#!/bin/bash
# joevt Jan 31, 2023
#10.4 Tiger to 10.13 High Sierra
kextload=kextload
# Later macOS versions
command -v kextutil > /dev/null && kextload=kextutil
getkextidentifier () {
local thekextpath="$1"
if [[ ! -f "$thekextpath/Contents/Info.plist" ]]; then
echo "# Missing Info.plist" 1>&2
return 1
fi
# Mac OS X 10.4 doesn't have PlistBuddy so just use perl
perl -0777 -n -e 'if (m|<key>CFBundleIdentifier</key>\s*<string>(.+)</string>|) { print $1 }' "$thekextpath/Contents/Info.plist"
}
checkkext () {
local thekextpath="$1"
if [[ -d "$thekextpath" ]]; then
if [[ -f "$thekextpath/Contents/Info.plist" ]]; then
local kextname
kextname="$(basename "$thekextpath")"
if grep -q -E "\.kext$" <<< "$kextname"; then
local kextidentifier=""
kextidentifier="$(getkextidentifier "$thekextpath")"
local theerr=$?
if (( theerr == 0 )); then
return 0
else
echo "# Missing CFBundleIdentifier" 1>&2
return 1
fi
else
echo "# That's not a kext" 1>&2
return 1
fi
else
echo "# Missing Info.plist" 1>&2
return 1
fi
else
echo "# Expected a kext folder" 1>&2
return 1
fi
}
unloadkext () {
local thekextpath="$1"
checkkext "$thekextpath" || return 1
local kextname
kextname="$(basename "$thekextpath")"
#local kextsrcdir
#kextsrcdir="$(dirname "$thekextpath")"
local kexttmpdir
kexttmpdir="$(mktemp -d /tmp/KextUtil_XXXXXXX)"
local kextinstalldir="/Library/Extensions"
local kextidentifier
kextidentifier="$(getkextidentifier "$thekextpath")"
echo "# kextname: $kextname"
echo "# kextidentifier: $kextidentifier"
if ( kextstat | grep -q "$kextidentifier" ); then
while ( kextstat | grep -q "$kextidentifier" ); do
echo "# Unloading $kextname"
sleep 1
sudo kextunload -b "$kextidentifier"
done
echo "# $kextname is unloaded"
else
echo "# $kextname is not loaded"
fi
}
fixkextpermission () {
local thekextpath="$1"
checkkext "$thekextpath" || return 1
sudo chown -R root:wheel "$thekextpath"
sudo find "$thekextpath" -type d -exec /bin/chmod 0755 {} \;
sudo find "$thekextpath" -type f -exec /bin/chmod 0644 {} \;
}
loadkext () {
local thekextpath="$1"
checkkext "$thekextpath" || return 1
local kextname
kextname="$(basename "$thekextpath")"
#local kextsrcdir
#kextsrcdir="$(dirname "$thekextpath")"
local kexttmpdir
kexttmpdir="$(mktemp -d /tmp/KextUtil_XXXXXXX)"
sudo cp -R "$thekextpath" "$kexttmpdir/$kextname"
fixkextpermission "$kexttmpdir/$kextname"
unloadkext "$thekextpath"
if ( sudo "$kextload" "$kexttmpdir/$kextname" ); then
echo "# $kextname was loaded"
fi
}
installkext () {
local doload=0
local dosystem=0
while (( $# )); do
if [[ "$1" == "-l" ]]; then
doload=1
elif [[ "$1" == "-s" ]]; then
dosystem=1
else
break
fi
shift 1
done
local thekextpath="$1"
checkkext "$thekextpath" || return 1
local kextname
kextname="$(basename "$thekextpath")"
#local kextsrcdir
#kextsrcdir="$(dirname "$thekextpath")"
local kexttmpdir
kexttmpdir="$(mktemp -d /tmp/KextUtil_XXXXXXX)"
local kextinstalldir="/Library/Extensions"
if ((dosystem)); then
kextinstalldir="/System/Library/Extensions"
fi
local kextidentifier
kextidentifier="$(getkextidentifier "$thekextpath")"
if ((doload)); then
unloadkext "$thekextpath"
else
echo "# kextname: $kextname"
echo "# kextidentifier: $kextidentifier"
fi
sudo cp -R "$thekextpath" "$kexttmpdir/$kextname"
fixkextpermission "$kexttmpdir/$kextname"
if [[ -n "$kextinstalldir" ]]; then
if [[ -d "/System/Library/Extensions/$kextname" ]]; then
mount | grep ' on / ' | grep -q 'read-only' && sudo mount -uw /
sudo rm -R "/System/Library/Extensions/$kextname"
fi
[[ -d "/Library/Extensions/$kextname" ]] && sudo rm -R "/Library/Extensions/$kextname"
sudo mv "$kexttmpdir/$kextname" "$kextinstalldir"
if ((doload)); then
sudo "$kextload" "$kextinstalldir/$kextname"
fi
else
if ((doload)); then
sudo "$kextload" "$kexttmpdir/$kextname"
fi
fi
if ((doload)); then
kextstat | grep "$kextidentifier"
fi
}
removekext () {
local thekextpath="$1"
checkkext "$thekextpath" || return 1
[[ -d "$thekextpath" ]] && sudo rm -R "$thekextpath"
}
rebuildkextcache () {
sudo kextcache -i /
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment