Example #1
0
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;
}