QueryData genKextstat(QueryContext &context) { QueryData results; // Populate dict of kernel extensions. CFDictionaryRef dict = OSKextCopyLoadedKextInfo(NULL, NULL); CFIndex count = CFDictionaryGetCount(dict); // Allocate memory for each extension parse. auto values = (void **)malloc(sizeof(void *) * count); CFDictionaryGetKeysAndValues(dict, nullptr, (const void **)values); for (CFIndex j = 0; j < count; j++) { // name auto name = getKextString(values[j], CFSTR("CFBundleIdentifier")); auto kextTag = getKextInt(values[j], CFSTR("OSBundleLoadTag")); // Possibly limit expensive lookups. if (!context.constraints["name"].matches(name)) { continue; } if (!context.constraints["idx"].matches<int>(kextTag)) { continue; } auto references = getKextInt(values[j], CFSTR("OSBundleRetainCount")); // size auto load_size = getKextBigInt(values[j], CFSTR("OSBundleLoadSize")); auto wired_size = getKextBigInt(values[j], CFSTR("OSBundleWiredSize")); auto version = getKextString(values[j], CFSTR("CFBundleVersion")); // linked_against auto linked = getKextLinked(values[j], CFSTR("OSBundleDependencies")); Row r; r["idx"] = INTEGER(kextTag); r["refs"] = INTEGER(references); r["size"] = BIGINT(load_size); r["wired"] = BIGINT(wired_size); r["name"] = name; r["version"] = version; r["linked_against"] = linked; results.push_back(r); } CFRelease(dict); free(values); return results; }
ExitStatus main(int argc, char * const * argv) { ExitStatus result = EX_OK; KextstatArgs toolArgs; CFDictionaryRef * kextInfoList = NULL; // must free CFIndex count, i; if (argv[0]) { progname = argv[0]; } /* Set the OSKext log callback right away. */ OSKextSetLogOutputFunction(&tool_log); result = readArgs(argc, argv, &toolArgs); if (result != EX_OK) { if (result == kKextstatExitHelp) { result = EX_OK; } goto finish; } toolArgs.runningKernelArch = OSKextGetRunningKernelArchitecture(); if (!toolArgs.runningKernelArch) { result = EX_OSERR; goto finish; } toolArgs.loadedKextInfo = OSKextCopyLoadedKextInfo(toolArgs.bundleIDs, NULL /* all info */); if (!toolArgs.loadedKextInfo) { OSKextLog(/* kext */ NULL, kOSKextLogErrorLevel | kOSKextLogGeneralFlag | kOSKextLogIPCFlag, "Couldn't get list of loaded kexts from kernel."); result = EX_OSERR; goto finish; } if (!toolArgs.flagListOnly) { printf("Index Refs Address "); if (toolArgs.runningKernelArch->cputype & CPU_ARCH_ABI64) { printf(" "); } printf("Size Wired "); if (toolArgs.flagShowArchitecture) { printf("Architecture "); } printf("Name (Version) <Linked Against>\n"); } count = CFDictionaryGetCount(toolArgs.loadedKextInfo); if (!count) { goto finish; } kextInfoList = (CFDictionaryRef *)malloc(count * sizeof(CFDictionaryRef)); if (!kextInfoList) { OSKextLogMemError(); result = EX_OSERR; goto finish; } CFDictionaryGetKeysAndValues(toolArgs.loadedKextInfo, /* keys */ NULL, (const void **)kextInfoList); qsort(kextInfoList, count, sizeof(CFDictionaryRef), &compareKextInfo); for (i = 0; i < count; i++) { printKextInfo(kextInfoList[i], &toolArgs); } finish: exit(result); SAFE_FREE(kextInfoList); return result; }