Forked from erikng/kextsthatwillmakeanadmincry.py
Last active
December 15, 2020 20:53
-
-
Save prantlf/23bafe218e8a2def8085772ebe9bda62 to your computer and use it in GitHub Desktop.
Prints kernel extensions on OSX
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# Credit to frogor for the objc | |
from Foundation import NSBundle | |
import json | |
import objc | |
import os | |
import plistlib | |
import subprocess | |
import sys | |
def help(): | |
print ("Usage: kextsthatwillmakeanadmincry.py [--help|--all|--loaded]\n" | |
"\n" | |
" --help prints this usage information and exists\n" | |
" --all prints all registered kernel extensions\n" | |
" --loaded prints all loaded kernel extensions") | |
sys.exit(1) | |
if len(sys.argv) == 1: | |
help() | |
allexts = True | |
arg = sys.argv[1] | |
if arg == '--help': | |
help() | |
elif arg == '--all': | |
allexts = True | |
elif arg == '--loaded': | |
allexts = False | |
else: | |
print 'invalid argument:', arg, '(use --help for help)' | |
sys.exit(1) | |
IOKit = NSBundle.bundleWithIdentifier_('com.apple.framework.IOKit') | |
functions = [('KextManagerCopyLoadedKextInfo', '@@@'), ] | |
objc.loadBundleFunctions(IOKit, globals(), functions) | |
kernel_dict = KextManagerCopyLoadedKextInfo(None, None) | |
folderpaths = ['/Applications', '/Users', '/System/Library/Extensions', | |
'/Library'] | |
unidentifiedKexts = [] | |
# This just finds all of the currently loaded kexts. | |
identifiedKexts = \ | |
[ | |
{ | |
'Identifier': kernel_dict[kext]['CFBundleIdentifier'], | |
'KextPath': kernel_dict[kext]['OSBundlePath'], | |
'Version': kernel_dict[kext]['CFBundleVersion'], | |
} | |
for kext in kernel_dict.keys() | |
if not kext.startswith(('__kernel', 'com.apple')) | |
] | |
# This checks common folder paths for any unloaded Kexts and attempts to give | |
# the same type of info as above. This can take a really long time to finish, | |
# and could really piss people off if you run this more than once. | |
# More notes: | |
# mdfind by default doesn't search hidden paths or application bundles | |
# | |
# kextfind can't traverse folders | |
# | |
# locate takes just as long as os.walk if not longer since we are skipping some | |
# of the folders. If we use locate, the db could also be out of date. | |
if allexts: | |
for path in folderpaths: | |
for root, dirnames, filesnames in os.walk(path): | |
if root.endswith('.kext'): | |
infoplist = os.path.join(root, 'Contents/Info.plist') | |
if os.path.isfile(infoplist): | |
kextplistpath = plistlib.readPlist(infoplist) | |
if 'apple' in kextplistpath['CFBundleIdentifier']: | |
continue | |
else: | |
kextinfo = { | |
'Identifier': kextplistpath['CFBundleIdentifier'], | |
'KextPath': root, | |
'Version': kextplistpath['CFBundleVersion'], | |
} | |
identifiedKexts.append(kextinfo) | |
else: | |
unidentifiedKexts.append(root) | |
kextsThatWillMakeAnAdminCry = {'IdentifiedKexts': identifiedKexts, | |
'UnidentifiedKexts': unidentifiedKexts} | |
print json.dumps(kextsThatWillMakeAnAdminCry, indent=2, sort_keys=True) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment