Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Define UNICODE and _UNICODE preprocessors for windows #6338

Merged
merged 11 commits into from
Jul 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions cmake/flags.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,8 @@ function(setupBuildFlags)
OSQUERY_BUILD_PLATFORM=windows
OSQUERY_BUILD_DISTRO=10
BOOST_CONFIG_SUPPRESS_OUTDATED_MESSAGE=1
UNICODE
_UNICODE
)

set(windows_common_defines
Expand Down
16 changes: 12 additions & 4 deletions osquery/core/windows/wmi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,18 +279,26 @@ Status WmiResultItem::GetUnsignedLongLong(const std::string& name,
Status WmiResultItem::GetString(const std::string& name,
std::string& ret) const {
std::wstring property_name = stringToWstring(name);
std::wstring result;
auto status = GetString(property_name, result);
ret = wstringToString(result);
return status;
}

Status WmiResultItem::GetString(const std::wstring& name,
std::wstring& ret) const {
VARIANT value;
HRESULT hr = result_->Get(property_name.c_str(), 0, &value, nullptr, nullptr);
HRESULT hr = result_->Get(name.c_str(), 0, &value, nullptr, nullptr);
if (hr != S_OK) {
ret = "";
ret = L"";
return Status::failure("Error retrieving data from WMI query.");
}
if (value.vt != VT_BSTR) {
ret = "";
ret = L"";
VariantClear(&value);
return Status::failure("Invalid data type returned.");
}
ret = bstrToString(value.bstrVal);
ret = value.bstrVal;
VariantClear(&value);
return Status::success();
}
Expand Down
8 changes: 8 additions & 0 deletions osquery/core/windows/wmi.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,14 @@ class WmiResultItem {
*/
Status GetString(const std::string& name, std::string& ret) const;

/**
* @brief Windows WMI Helper function to retrieve a String result from a WMI
* query
*
* @returns Status indicating the success of the query
*/
Status GetString(const std::wstring& name, std::wstring& ret) const;

/**
* @brief Windows WMI Helper function to retrieve a vector of String result
* from
Expand Down
2 changes: 1 addition & 1 deletion osquery/filesystem/windows/fileops.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1841,7 +1841,7 @@ fs::path getSystemRoot() {
std::vector<WCHAR> winDirectory(MAX_PATH + 1);
ZeroMemory(winDirectory.data(), MAX_PATH + 1);
GetWindowsDirectoryW(winDirectory.data(), MAX_PATH);
return fs::path(wstringToString(winDirectory.data()));
return fs::path(winDirectory.data());
}

Status platformLstat(const std::string& path, struct stat& d_stat) {
Expand Down
111 changes: 58 additions & 53 deletions osquery/process/windows/process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,13 +158,13 @@ std::shared_ptr<PlatformProcess> PlatformProcess::getLauncherProcess() {

std::shared_ptr<PlatformProcess> PlatformProcess::launchWorker(
const std::string& exec_path, int argc, char** argv) {
::STARTUPINFOA si = {0};
::STARTUPINFO si = {0};
::PROCESS_INFORMATION pi = {nullptr};

si.cb = sizeof(si);

std::stringstream argv_stream;
std::stringstream handle_stream;
std::wstringstream argv_stream;
std::wstringstream handle_stream;

// The HANDLE exposed to the child process is currently limited to only having
// SYNCHRONIZE and PROCESS_QUERY_LIMITED_INFORMATION capabilities. The
Expand Down Expand Up @@ -197,25 +197,25 @@ std::shared_ptr<PlatformProcess> PlatformProcess::launchWorker(
// instead, we off-load the contents of argv into a vector which will have its
// backing memory as modifiable.
for (size_t i = 0; i < argc; i++) {
std::string component(argv[i]);
std::wstring component(stringToWstring(argv[i]));
if (component.find(' ') != std::string::npos) {
boost::replace_all(component, "\"", "\\\"");
argv_stream << "\"" << component << "\" ";
boost::replace_all(component, L"\"", L"\\\"");
argv_stream << L"\"" << component << L"\" ";
} else {
argv_stream << component << " ";
argv_stream << component << L" ";
}
}

auto cmdline = argv_stream.str();
std::vector<char> mutable_argv(cmdline.begin(), cmdline.end());
mutable_argv.push_back('\0');
std::vector<WCHAR> mutable_argv(cmdline.begin(), cmdline.end());
mutable_argv.push_back(L'\0');

LPCH retrievedEnvironment = GetEnvironmentStringsA();
LPTSTR currentEnvironment = (LPTSTR)retrievedEnvironment;
std::stringstream childEnvironment;
LPWCH retrievedEnvironment = GetEnvironmentStrings();
LPCWSTR currentEnvironment = retrievedEnvironment;
std::wstringstream childEnvironment;
while (*currentEnvironment) {
childEnvironment << currentEnvironment;
childEnvironment << '\0';
childEnvironment << L'\0';
currentEnvironment += lstrlen(currentEnvironment) + 1;
}

Expand All @@ -230,21 +230,22 @@ std::shared_ptr<PlatformProcess> PlatformProcess::launchWorker(
// OSQUERY_LAUNCHER. OSQUERY_LAUNCHER stores the string form of a HANDLE to
// the current process. This is mostly used for detecting the death of the
// launcher process in WatcherWatcherRunner::start
childEnvironment << "OSQUERY_WORKER=1" << '\0';
childEnvironment << "OSQUERY_LAUNCHER=" << handle << '\0' << '\0';

std::string environmentString = childEnvironment.str();

auto status = ::CreateProcessA(exec_path.c_str(),
mutable_argv.data(),
nullptr,
nullptr,
TRUE,
IDLE_PRIORITY_CLASS,
&environmentString[0],
nullptr,
&si,
&pi);
childEnvironment << L"OSQUERY_WORKER=1" << L'\0';
childEnvironment << L"OSQUERY_LAUNCHER=" << handle << L'\0' << L'\0';

std::wstring environmentString = childEnvironment.str();

auto status =
::CreateProcess(nullptr,
mutable_argv.data(),
nullptr,
nullptr,
TRUE,
CREATE_UNICODE_ENVIRONMENT | IDLE_PRIORITY_CLASS,
&environmentString[0],
nullptr,
&si,
&pi);
::CloseHandle(hLauncherProcess);

if (!status) {
Expand All @@ -264,29 +265,32 @@ std::shared_ptr<PlatformProcess> PlatformProcess::launchExtension(
const std::string& extensions_timeout,
const std::string& extensions_interval,
bool verbose) {
::STARTUPINFOA si = {0};
::STARTUPINFO si = {0};
::PROCESS_INFORMATION pi = {nullptr};

si.cb = sizeof(si);

std::wstring const wexec_path = stringToWstring(exec_path);

// To prevent errant double quotes from altering the intended arguments for
// argv, we strip them out completely.
std::stringstream argv_stream;
argv_stream << "\"" << boost::replace_all_copy(exec_path, "\"", "") << "\" ";
std::wstringstream argv_stream;
argv_stream << L"\"" << boost::replace_all_copy(wexec_path, L"\"", L"")
<< L"\" ";
if (verbose) {
argv_stream << "--verbose ";
argv_stream << L"--verbose ";
}
argv_stream << "--socket \"" << extensions_socket << "\" ";
argv_stream << "--timeout " << extensions_timeout << " ";
argv_stream << "--interval " << extensions_interval << " ";
argv_stream << L"--socket \"" << stringToWstring(extensions_socket) << L"\" ";
argv_stream << L"--timeout " << stringToWstring(extensions_timeout) << L" ";
argv_stream << L"--interval " << stringToWstring(extensions_interval) << L" ";

// We don't directly use argv.c_str() as the value for lpCommandLine in
// CreateProcess since that argument requires a modifiable buffer. So,
// instead, we off-load the contents of argv into a vector which will have its
// backing memory as modifiable.
auto argv = argv_stream.str();
std::vector<char> mutable_argv(argv.begin(), argv.end());
mutable_argv.push_back('\0');
std::vector<WCHAR> mutable_argv(argv.begin(), argv.end());
mutable_argv.push_back(L'\0');

// In POSIX, this environment variable is set to the child's process ID. But
// that is not easily accomplishable on Windows and provides no value since
Expand All @@ -295,23 +299,24 @@ std::shared_ptr<PlatformProcess> PlatformProcess::launchExtension(
return std::shared_ptr<PlatformProcess>();
}

auto ext_path = fs::path(exec_path);
auto ext_path = fs::path(wexec_path);

// We are autoloading a Python extension, so pass off to our helper
if (ext_path.extension().string() == ".ext") {
return launchTestPythonScript(
std::string(mutable_argv.begin(), mutable_argv.end()));
if (ext_path.extension().wstring() == L".ext") {
return launchTestPythonScript(wstringToString(
std::wstring(mutable_argv.begin(), mutable_argv.end())));
} else {
auto status = ::CreateProcessA(exec_path.c_str(),
mutable_argv.data(),
nullptr,
nullptr,
TRUE,
IDLE_PRIORITY_CLASS,
nullptr,
nullptr,
&si,
&pi);
auto status =
::CreateProcess(nullptr,
mutable_argv.data(),
nullptr,
nullptr,
TRUE,
CREATE_UNICODE_ENVIRONMENT | IDLE_PRIORITY_CLASS,
nullptr,
nullptr,
&si,
&pi);
unsetEnvVar("OSQUERY_EXTENSION");

if (!status) {
Expand All @@ -331,9 +336,9 @@ std::shared_ptr<PlatformProcess> PlatformProcess::launchTestPythonScript(
STARTUPINFOW si = {0};
PROCESS_INFORMATION pi = {nullptr};

auto argv = "python " + args;
auto argv = L"python " + stringToWstring(args);
std::vector<WCHAR> mutable_argv(argv.begin(), argv.end());
mutable_argv.push_back('\0');
mutable_argv.push_back(L'\0');
si.cb = sizeof(si);

const auto pythonEnv = getEnvVar("OSQUERY_PYTHON_INTERPRETER_PATH");
Expand Down
4 changes: 2 additions & 2 deletions osquery/tables/cloud/aws/ec2_instance_tags.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ QueryData genEc2InstanceTags(QueryContext& context) {
for (const auto& it : response.GetTags()) {
Row r;
r["instance_id"] = instance_id;
r["key"] = TEXT(it.GetKey());
r["value"] = TEXT(it.GetValue());
r["key"] = SQL_TEXT(it.GetKey());
r["value"] = SQL_TEXT(it.GetValue());
results.push_back(r);
}

Expand Down
26 changes: 13 additions & 13 deletions osquery/tables/events/windows/ntfs_journal_events.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@
#include <osquery/logger.h>
#include <osquery/registry_factory.h>
#include <osquery/sql.h>
#include <osquery/utils/json/json.h>

#include <osquery/tables/events/windows/ntfs_journal_events.h>
#include <osquery/utils/conversions/windows/strings.h>
#include <osquery/utils/json/json.h>

namespace osquery {
REGISTER(NTFSEventSubscriber, "event_subscriber", "ntfs_journal_events");
Expand Down Expand Up @@ -147,27 +147,27 @@ Row NTFSEventSubscriber::generateRowFromEvent(const NTFSEventRecord& event) {
auto action_description_it = kNTFSEventToStringMap.find(event.type);
assert(action_description_it != kNTFSEventToStringMap.end());

row["action"] = TEXT(action_description_it->second);
row["old_path"] = TEXT(event.old_path);
row["path"] = TEXT(event.path);
row["action"] = SQL_TEXT(action_description_it->second);
row["old_path"] = SQL_TEXT(event.old_path);
row["path"] = SQL_TEXT(event.path);
row["partial"] = INTEGER(event.partial);

// NOTE(woodruffw): These are emitted in decimal, not hex.
// There's no good reason for this, other than that
// boost's mp type doesn't handle std::hex and other
// ios formatting directives correctly.
row["node_ref_number"] = TEXT(event.node_ref_number.str());
row["parent_ref_number"] = TEXT(event.parent_ref_number.str());
row["node_ref_number"] = SQL_TEXT(event.node_ref_number.str());
row["parent_ref_number"] = SQL_TEXT(event.parent_ref_number.str());

{
std::stringstream buffer;
buffer << event.record_timestamp;
row["record_timestamp"] = TEXT(buffer.str());
row["record_timestamp"] = SQL_TEXT(buffer.str());

buffer.str("");
buffer << std::hex << std::setfill('0') << std::setw(16)
<< event.update_sequence_number;
row["record_usn"] = TEXT(buffer.str());
row["record_usn"] = SQL_TEXT(buffer.str());

// NOTE(woodruffw): Maybe comma-separate here? Pipes make it clear
// that these are flags, but CSV is easier to parse and is
Expand All @@ -190,11 +190,11 @@ Row NTFSEventSubscriber::generateRowFromEvent(const NTFSEventRecord& event) {
add_separator = true;
}

row["file_attributes"] = TEXT(buffer.str());
row["file_attributes"] = SQL_TEXT(buffer.str());
}

std::string drive_letter(1, event.drive_letter);
row["drive_letter"] = TEXT(drive_letter);
row["drive_letter"] = SQL_TEXT(drive_letter);

return row;
}
Expand Down Expand Up @@ -270,7 +270,7 @@ Status NTFSEventSubscriber::Callback(const ECRef& ec, const SCRef& sc) {
}

auto row = generateRowFromEvent(event);
row["category"] = TEXT(sc->category);
row["category"] = SQL_TEXT(sc->category);
emitted_row_list.push_back(row);
}

Expand Down Expand Up @@ -310,7 +310,7 @@ void processConfiguration(const NTFSEventSubscriptionContextRef context,
// so we need to pass FILE_FLAG_BACKUP_SEMANTICS rather
// than FILE_ATTRIBUTE_NORMAL.
for (const auto& path : include_paths) {
HANDLE file_hnd = ::CreateFile(path.c_str(),
HANDLE file_hnd = ::CreateFile(stringToWstring(path).c_str(),
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
Expand Down
10 changes: 5 additions & 5 deletions osquery/tables/events/windows/powershell_events.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,15 +108,15 @@ Status PowershellEventSubscriber::generateRow(
}

row["time"] = INTEGER(first_script_message.osquery_time);
row["datetime"] = TEXT(first_script_message.event_time);
row["script_block_id"] = TEXT(first_script_message.script_block_id);
row["datetime"] = SQL_TEXT(first_script_message.event_time);
row["script_block_id"] = SQL_TEXT(first_script_message.script_block_id);

row["script_block_count"] =
INTEGER(first_script_message.expected_message_count);

row["script_text"] = TEXT(std::move(full_script));
row["script_name"] = TEXT(first_script_message.script_name);
row["script_path"] = TEXT(first_script_message.script_path);
row["script_text"] = SQL_TEXT(std::move(full_script));
row["script_name"] = SQL_TEXT(first_script_message.script_name);
row["script_path"] = SQL_TEXT(first_script_message.script_path);
row["cosine_similarity"] = DOUBLE(cosine_similarity);

return Status::success();
Expand Down
12 changes: 6 additions & 6 deletions osquery/tables/events/windows/windows_events.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,14 +247,14 @@ void WindowsEventSubscriber::generateRow(Row& row, const Event& windows_event) {
row = {};

row["time"] = INTEGER(windows_event.osquery_time);
row["datetime"] = TEXT(windows_event.datetime);
row["source"] = TEXT(windows_event.source);
row["provider_name"] = TEXT(windows_event.provider_name);
row["provider_guid"] = TEXT(windows_event.provider_guid);
row["datetime"] = SQL_TEXT(windows_event.datetime);
row["source"] = SQL_TEXT(windows_event.source);
row["provider_name"] = SQL_TEXT(windows_event.provider_name);
row["provider_guid"] = SQL_TEXT(windows_event.provider_guid);
row["eventid"] = INTEGER(windows_event.event_id);
row["task"] = INTEGER(windows_event.task_id);
row["level"] = INTEGER(windows_event.level);
row["keywords"] = TEXT(windows_event.keywords);
row["data"] = TEXT(windows_event.data);
row["keywords"] = SQL_TEXT(windows_event.keywords);
row["data"] = SQL_TEXT(windows_event.data);
}
} // namespace osquery
Loading