2014-08-08 20:59:57 +00:00
|
|
|
// Copyright 2004-present Facebook. All Rights Reserved.
|
|
|
|
|
|
|
|
#include <CoreFoundation/CoreFoundation.h>
|
|
|
|
|
|
|
|
#include <boost/algorithm/string/trim.hpp>
|
|
|
|
#include <boost/lexical_cast.hpp>
|
|
|
|
|
|
|
|
#include <glog/logging.h>
|
|
|
|
|
|
|
|
#include "osquery/core.h"
|
|
|
|
#include "osquery/database.h"
|
|
|
|
|
|
|
|
using namespace osquery::db;
|
|
|
|
|
|
|
|
extern "C" {
|
2014-08-15 07:25:30 +00:00
|
|
|
extern CFDictionaryRef OSKextCopyLoadedKextInfo(CFArrayRef, CFArrayRef);
|
2014-08-08 20:59:57 +00:00
|
|
|
}
|
|
|
|
|
2014-08-15 07:25:30 +00:00
|
|
|
namespace osquery {
|
|
|
|
namespace tables {
|
2014-08-08 20:59:57 +00:00
|
|
|
|
|
|
|
QueryData genKextstat() {
|
|
|
|
QueryData results;
|
|
|
|
CFDictionaryRef dict = OSKextCopyLoadedKextInfo(NULL, NULL);
|
|
|
|
|
|
|
|
CFIndex count = CFDictionaryGetCount(dict);
|
|
|
|
CFIndex i, j;
|
|
|
|
|
|
|
|
void **keys;
|
|
|
|
void **values;
|
|
|
|
|
|
|
|
keys = (void **)malloc(sizeof(void *) * count);
|
|
|
|
values = (void **)malloc(sizeof(void *) * count);
|
|
|
|
|
|
|
|
CFDictionaryGetKeysAndValues(
|
2014-08-15 07:25:30 +00:00
|
|
|
dict, (const void **)keys, (const void **)values);
|
2014-08-08 20:59:57 +00:00
|
|
|
|
|
|
|
for (i = 0; i < count; i++) {
|
|
|
|
for (j = 0; j < count; j++) {
|
|
|
|
int kextTag;
|
|
|
|
int references;
|
|
|
|
unsigned long long load_size;
|
|
|
|
unsigned long long wired_size;
|
|
|
|
|
|
|
|
// name
|
2014-08-26 20:34:08 +00:00
|
|
|
std::string name;
|
|
|
|
CFStringRef nameRef = (CFStringRef)CFDictionaryGetValue(
|
|
|
|
(CFDictionaryRef)(values)[j], CFSTR("CFBundleIdentifier"));
|
|
|
|
CFIndex nameLen = CFStringGetLength(nameRef) + 1;
|
2014-09-09 07:56:27 +00:00
|
|
|
char *nameBuffer = (char *)malloc(nameLen);
|
|
|
|
if (nameBuffer &&
|
|
|
|
CFStringGetCString(
|
|
|
|
nameRef, nameBuffer, nameLen, kCFStringEncodingUTF8)) {
|
2014-08-26 20:34:08 +00:00
|
|
|
name = std::string(nameBuffer);
|
|
|
|
boost::algorithm::trim(name);
|
|
|
|
}
|
|
|
|
if (nameBuffer != 0) {
|
|
|
|
free(nameBuffer);
|
|
|
|
}
|
2014-08-08 20:59:57 +00:00
|
|
|
|
|
|
|
// index
|
|
|
|
CFNumberGetValue(
|
2014-08-15 07:25:30 +00:00
|
|
|
(CFNumberRef)CFDictionaryGetValue((CFDictionaryRef)values[j],
|
|
|
|
CFSTR("OSBundleLoadTag")),
|
|
|
|
kCFNumberSInt32Type,
|
|
|
|
&kextTag);
|
2014-08-08 20:59:57 +00:00
|
|
|
if (kextTag != i) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// refs
|
|
|
|
CFNumberGetValue(
|
2014-08-15 07:25:30 +00:00
|
|
|
(CFNumberRef)CFDictionaryGetValue((CFDictionaryRef)values[j],
|
|
|
|
CFSTR("OSBundleRetainCount")),
|
|
|
|
kCFNumberSInt32Type,
|
|
|
|
&references);
|
2014-08-08 20:59:57 +00:00
|
|
|
|
|
|
|
// size
|
|
|
|
CFNumberGetValue(
|
2014-08-15 07:25:30 +00:00
|
|
|
(CFNumberRef)CFDictionaryGetValue((CFDictionaryRef)values[j],
|
|
|
|
CFSTR("OSBundleLoadSize")),
|
|
|
|
kCFNumberSInt64Type,
|
|
|
|
&load_size);
|
2014-08-08 20:59:57 +00:00
|
|
|
char size_c[256] = "";
|
|
|
|
snprintf(size_c, sizeof(size_c), "0x%-10llx", load_size);
|
|
|
|
std::string size = size_c;
|
|
|
|
boost::algorithm::trim(size);
|
|
|
|
|
|
|
|
// wired
|
|
|
|
CFNumberGetValue(
|
2014-08-15 07:25:30 +00:00
|
|
|
(CFNumberRef)CFDictionaryGetValue((CFDictionaryRef)values[j],
|
|
|
|
CFSTR("OSBundleWiredSize")),
|
|
|
|
kCFNumberSInt64Type,
|
|
|
|
&wired_size);
|
2014-08-08 20:59:57 +00:00
|
|
|
char wired_c[256] = "";
|
|
|
|
snprintf(wired_c, sizeof(wired_c), "0x%-10llx", wired_size);
|
|
|
|
std::string wired = wired_c;
|
|
|
|
boost::algorithm::trim(wired);
|
|
|
|
|
|
|
|
// version
|
2014-08-26 20:34:08 +00:00
|
|
|
std::string version;
|
|
|
|
CFStringRef versionRef = (CFStringRef)CFDictionaryGetValue(
|
|
|
|
(CFDictionaryRef)values[j], CFSTR("CFBundleVersion"));
|
|
|
|
CFIndex versionLen = CFStringGetLength(versionRef) + 1;
|
2014-09-09 07:56:27 +00:00
|
|
|
char *versionBuffer = (char *)malloc(versionLen);
|
|
|
|
if (versionBuffer &&
|
|
|
|
CFStringGetCString(
|
|
|
|
versionRef, versionBuffer, versionLen, kCFStringEncodingUTF8)) {
|
2014-08-26 20:34:08 +00:00
|
|
|
version = std::string(versionBuffer);
|
|
|
|
boost::algorithm::trim(version);
|
|
|
|
}
|
|
|
|
if (versionBuffer != 0) {
|
|
|
|
free(versionBuffer);
|
|
|
|
}
|
2014-08-08 20:59:57 +00:00
|
|
|
|
|
|
|
// linked_against
|
|
|
|
CFArrayRef dependencies = (CFArrayRef)CFDictionaryGetValue(
|
2014-08-15 07:25:30 +00:00
|
|
|
(CFDictionaryRef)values[j], CFSTR("OSBundleDependencies"));
|
2014-08-08 20:59:57 +00:00
|
|
|
char linked_against[512] = "";
|
|
|
|
|
|
|
|
if (dependencies != NULL) {
|
|
|
|
CFIndex linked_count = CFArrayGetCount(dependencies);
|
|
|
|
int linked = 0;
|
|
|
|
|
2014-08-15 07:25:30 +00:00
|
|
|
CFMutableArrayRef marray =
|
|
|
|
CFArrayCreateMutableCopy(NULL, linked_count, dependencies);
|
2014-08-08 20:59:57 +00:00
|
|
|
|
2014-08-15 07:25:30 +00:00
|
|
|
CFArraySortValues(marray,
|
|
|
|
CFRangeMake(0, linked_count),
|
|
|
|
(CFComparatorFunction)CFNumberCompare,
|
|
|
|
NULL);
|
2014-08-08 20:59:57 +00:00
|
|
|
|
|
|
|
if (linked_count > 0) {
|
|
|
|
snprintf(linked_against, sizeof(linked_against), "<");
|
|
|
|
}
|
|
|
|
for (int l = 0; l < linked_count; l++) {
|
2014-08-15 07:25:30 +00:00
|
|
|
CFNumberGetValue((CFNumberRef)CFArrayGetValueAtIndex(marray, l),
|
|
|
|
kCFNumberSInt32Type,
|
|
|
|
&linked);
|
|
|
|
|
|
|
|
if (l) {
|
|
|
|
snprintf(
|
|
|
|
linked_against, sizeof(linked_against), "%s ", linked_against);
|
2014-08-08 20:59:57 +00:00
|
|
|
}
|
2014-08-15 07:25:30 +00:00
|
|
|
snprintf(linked_against,
|
|
|
|
sizeof(linked_against),
|
|
|
|
"%s%d",
|
|
|
|
linked_against,
|
|
|
|
linked);
|
2014-08-08 20:59:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CFRelease(marray);
|
|
|
|
|
|
|
|
if (linked_count > 0) {
|
2014-08-15 07:25:30 +00:00
|
|
|
snprintf(
|
|
|
|
linked_against, sizeof(linked_against), "%s>", linked_against);
|
2014-08-08 20:59:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
std::string linked_against_string = linked_against;
|
|
|
|
boost::algorithm::trim(linked_against_string);
|
|
|
|
|
|
|
|
Row r;
|
|
|
|
r["idx"] = boost::lexical_cast<std::string>(kextTag);
|
|
|
|
r["refs"] = boost::lexical_cast<std::string>(references);
|
|
|
|
r["size"] = size;
|
|
|
|
r["wired"] = wired;
|
|
|
|
r["name"] = name;
|
|
|
|
r["version"] = version;
|
|
|
|
r["linked_against"] = linked_against_string;
|
|
|
|
results.push_back(r);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
CFRelease(dict);
|
|
|
|
free(keys);
|
|
|
|
free(values);
|
|
|
|
return results;
|
|
|
|
}
|
2014-08-15 07:25:30 +00:00
|
|
|
}
|
|
|
|
}
|