system_info.table
在源码中相对位置为/specs/system_info.table
table_name("system_info")
description("System information for identification.")
schema([
Column("hostname", TEXT, "Network hostname including domain"),
Column("uuid", TEXT, "Unique ID provided by the system"),
Column("cpu_type", TEXT, "CPU type"),
Column("cpu_subtype", TEXT, "CPU subtype"),
Column("cpu_brand", TEXT, "CPU brand string, contains vendor and model"),
Column("cpu_physical_cores", INTEGER, "Number of physical CPU cores in to the system"),
Column("cpu_logical_cores", INTEGER, "Number of logical CPU cores available to the system"),
Column("cpu_microcode", TEXT, "Microcode version"),
Column("physical_memory", BIGINT, "Total physical memory in bytes"),
Column("hardware_vendor", TEXT, "Hardware vendor"),
Column("hardware_model", TEXT, "Hardware model"),
Column("hardware_version", TEXT, "Hardware version"),
Column("hardware_serial", TEXT, "Device serial number"),
Column("board_vendor", TEXT, "Board vendor"),
Column("board_model", TEXT, "Board model"),
Column("board_version", TEXT, "Board version"),
Column("board_serial", TEXT, "Board serial number"),
Column("computer_name", TEXT, "Friendly computer name (optional)"),
Column("local_hostname", TEXT, "Local hostname (optional)"),
])
implementation("system/system_info@genSystemInfo")
system_info
获取的表项较多,在Windows上通过多种方式进行获取,因此system_info.cpp(Windows)
的代码在后续学习中具有一定指导意义。
QueryData genSystemInfo(QueryContext& context) {
Row r;
//通过WINAPI获取本地计算机的标准主机名。
r["hostname"] = osquery::getFqdn();
r["computer_name"] = osquery::getHostname();
r["local_hostname"] = r["computer_name"];
getHostUUID(r["uuid"]);
auto qd = SQL::selectAllFrom("cpuid");
for (const auto& row : qd) {
if (row.at("feature") == "product_name") {
r["cpu_brand"] = row.at("value");
boost::trim(r["cpu_brand"]);
}
}
//使用WMI获取信息
const WmiRequest wmiSystemReq("select * from Win32_ComputerSystem");
const WmiRequest wmiSystemReqProc("select * from Win32_Processor");
const std::vector<WmiResultItem>& wmiResults = wmiSystemReq.results();
const std::vector<WmiResultItem>& wmiResultsProc = wmiSystemReqProc.results();
if (!wmiResults.empty() && !wmiResultsProc.empty()) {
long numProcs = 0;
wmiResults[0].GetLong("NumberOfLogicalProcessors", numProcs);
r["cpu_logical_cores"] = INTEGER(numProcs);
wmiResultsProc[0].GetLong("NumberOfCores", numProcs);
r["cpu_physical_cores"] = INTEGER(numProcs);
wmiResults[0].GetString("TotalPhysicalMemory", r["physical_memory"]);
wmiResults[0].GetString("Manufacturer", r["hardware_vendor"]);
wmiResults[0].GetString("Model", r["hardware_model"]);
} else {
r["cpu_logical_cores"] = "-1";
r["cpu_physical_cores"] = "-1";
r["physical_memory"] = "-1";
r["hardware_vendor"] = "-1";
r["hardware_model"] = "-1";
}
//通过注册表获取部分信息
QueryData regResults;
queryKey(
"HKEY_LOCAL_MACHINE\\"
"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0\\",
regResults);
for (const auto& key : regResults) {
if (key.at("name") == "Update Revision") {
if (key.at("data").size() >= 16) {
auto revision_exp =
tryTo<unsigned long int>(key.at("data").substr(8, 2), 16);
r["cpu_microcode"] = std::to_string(revision_exp.takeOr(0ul));
}
break;
}
}
//通过WMI查询获取hardware_serial
const WmiRequest wmiBiosReq("select * from Win32_Bios");
const std::vector<WmiResultItem>& wmiBiosResults = wmiBiosReq.results();
if (wmiBiosResults.size() != 0) {
wmiBiosResults[0].GetString("SerialNumber", r["hardware_serial"]);
} else {
r["hardware_serial"] = "-1";
}
//调用WInAPI接口获取cpu_type
SYSTEM_INFO systemInfo;
GetSystemInfo(&systemInfo);
switch (systemInfo.wProcessorArchitecture) {
case PROCESSOR_ARCHITECTURE_AMD64:
r["cpu_type"] = "x86_64";
break;
case PROCESSOR_ARCHITECTURE_ARM:
r["cpu_type"] = "ARM";
break;
case PROCESSOR_ARCHITECTURE_IA64:
r["cpu_type"] = "x64 Itanium";
break;
case PROCESSOR_ARCHITECTURE_INTEL:
r["cpu_type"] = "x86";
break;
case PROCESSOR_ARCHITECTURE_UNKNOWN:
r["cpu_type"] = "Unknown";
default:
break;
}
r["cpu_subtype"] = "-1";
r["hardware_version"] = "-1";
return {r};
}
从上面摘取部分code进行解析,如下,WmiRequest是一个类,创建时传入查询指令,在其私有的results数据结构中会存储查询结果。
//使用WMI获取信息
const WmiRequest wmiSystemReq("select * from Win32_ComputerSystem");
const WmiRequest wmiSystemReqProc("select * from Win32_Processor");
const std::vector<WmiResultItem>& wmiResults = wmiSystemReq.results();
const std::vector<WmiResultItem>& wmiResultsProc = wmiSystemReqProc.results();
if (!wmiResults.empty() && !wmiResultsProc.empty()) {
long numProcs = 0;
wmiResults[0].GetLong("NumberOfLogicalProcessors", numProcs);
r["cpu_logical_cores"] = INTEGER(numProcs);
wmiResultsProc[0].GetLong("NumberOfCores", numProcs);
r["cpu_physical_cores"] = INTEGER(numProcs);
wmiResults[0].GetString("TotalPhysicalMemory", r["physical_memory"]);
wmiResults[0].GetString("Manufacturer", r["hardware_vendor"]);
wmiResults[0].GetString("Model", r["hardware_model"]);
} else {
r["cpu_logical_cores"] = "-1";
r["cpu_physical_cores"] = "-1";
r["physical_memory"] = "-1";
r["hardware_vendor"] = "-1";
r["hardware_model"] = "-1";
}
注册表(Registry)是Microsoft Windows中的一个重要的数据库,用于存储系统和应用程序的设置信息。
query(key,value)
是osquery的一个函数,key
输入的是注册表的路径,value
输出的是该路径中的信息。
//通过注册表获取部分信息
QueryData regResults;
queryKey(
"HKEY_LOCAL_MACHINE\\"
"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0\\",
regResults);
for (const auto& key : regResults) {
if (key.at("name") == "Update Revision") {
if (key.at("data").size() >= 16) {
auto revision_exp =
tryTo<unsigned long int>(key.at("data").substr(8, 2), 16);
r["cpu_microcode"] = std::to_string(revision_exp.takeOr(0ul));
}
break;
}
通过调用WINAPI
提供的GetSystemInfo()
函数获取cpu_type
的值。
//调用WInAPI接口获取cpu_type
SYSTEM_INFO systemInfo;
GetSystemInfo(&systemInfo);
switch (systemInfo.wProcessorArchitecture) {
case PROCESSOR_ARCHITECTURE_AMD64:
r["cpu_type"] = "x86_64";
break;
case PROCESSOR_ARCHITECTURE_ARM:
r["cpu_type"] = "ARM";
break;
case PROCESSOR_ARCHITECTURE_IA64:
r["cpu_type"] = "x64 Itanium";
break;
case PROCESSOR_ARCHITECTURE_INTEL:
r["cpu_type"] = "x86";
break;
case PROCESSOR_ARCHITECTURE_UNKNOWN:
r["cpu_type"] = "Unknown";
default:
break;
}
osquery底层通过各种方式获取系统信息,值得学习。