I'm building a kernel extension and having a .kext directory for it. From another library API, I'm using KextManager APIs to load this kext into kernel.
Everything looks fine, here is the code piece that I'm loading the kext with:
CFStringRef path = CFStringCreateWithCString(kCFAllocatorDefault, "awesome.kext", kCFStringEncodingUTF8);
CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, path, kCFURLPOSIXPathStyle, true);
OSReturn result = KextManagerLoadKextWithURL(url, NULL);
It works great, however I need to know my bundle identifier to have control socket connection, and maybe unload the kext with KextManagerUnloadKextWithIdentifier(kextId)
API later.
So I'm aware of XXX.kext/Contents/Info.plist
which contains CFBundleIdentifier
key with bundle identifier but I need some way of getting it programmatically (some API?) instead of reading Info.plist
file and parsing it.
I also tried to replace CFBundleIdentifier
string value with something else and load into kernel, it still works fine, so it looks like Info.plist
is not reliable anyway.
Is there anything related? Any suggestions? Thanks! :)
I discovered 2 useful approaches recently, both based on KextManagerCopyLoadedKextInfo API.
void handle_kext(const void* key, const void* value, void* context)
{
// OSBundlePath - CFString (this is merely a hint stored in the kernel; the kext is not guaranteed to be at this path)
CFStringRef bundle_path_key = CFStringCreateWithCString(kCFAllocatorDefault, "OSBundlePath", kCFStringEncodingUTF8);
const char* bundle_id_cstring = CFStringGetCStringPtr(key, kCFStringEncodingUTF8);
const char* bundle_path_cstring = CFStringGetCStringPtr(CFDictionaryGetValue(value, bundle_path_key, kCFStringEncodingUTF8);
// #1 Approach: Compare your 'I-Want-This-BundleID' with loaded kext path
// #2 Approach: Compare your 'I-Want-This-BundlePath' with loaded kext ID
}
void some_func()
{
CFDictionaryRef loaded_kexts = KextManagerCopyLoadedKextInfo(NULL, NULL);
CFDictionaryApplyFunction(loaded_kexts, handle_kext, NULL);
}