WindowsのAMSI(マルウェア対策スキャンインターフェイス)プロバイダーのCLSIDと表示名を取得するコードです。AMSIについてはMicrosoftの公式ドキュメントを参照ください。
#include <string> #include <vector> #define STRICT #define NOMINMAX #define WIN32_LEAN_AND_MEAN #include <Windows.h> #include <amsi.h> #include "wil/com.h" // レジストリキーのサブキーの名前をすべて取得します。 // 取得中にエラーが発生した場合は無視します。 std::vector<std::wstring> GetRegistrySubKeyNames(HKEY hkey) { DWORD subKeyCount, maxSubKeyLen; DWORD err = ::RegQueryInfoKeyW(hkey, nullptr, nullptr, nullptr, &subKeyCount, &maxSubKeyLen, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); if (err != ERROR_SUCCESS) return {}; std::vector<std::wstring> names; std::wstring buffer(maxSubKeyLen, L'\0'); for (DWORD i = 0; i < subKeyCount; i++) { DWORD size = maxSubKeyLen + 1; err = ::RegEnumKeyExW(hkey, i, buffer.data(), &size, nullptr, nullptr, nullptr, nullptr); if (err != ERROR_SUCCESS) continue; names.emplace_back(buffer.data(), size); } return names; } // CLSIDを{...}形式の文字列に変換します。 std::wstring CLSIDToStlWString(const CLSID& clsid) { std::wstring s(38, L'\0'); ::StringFromGUID2(clsid, s.data(), 39); return s; } // AMSIプロバイダーのCLSIDが登録されたレジストリキーを開きます。 wil::unique_hkey OpenAMSIProviderRegistryKey(DWORD options = 0, DWORD desired = KEY_READ) { wil::unique_hkey hkey; DWORD err = ::RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\AMSI\\Providers", options, desired, hkey.put()); return hkey; } // レジストリに登録されたAMSIプロバイダーのCLSIDをすべて取得します。 std::vector<CLSID> GetAMSIProviderCLSIDs(DWORD regOptions = 0, DWORD regDesired = 0) { auto hkey = OpenAMSIProviderRegistryKey(regOptions, KEY_READ | regDesired); auto clsidStrs = GetRegistrySubKeyNames(hkey.get()); std::vector<GUID> clsids; clsids.reserve(clsidStrs.size()); for (size_t i = 0, l = clsidStrs.size(); i < l; i++) { CLSID clsid; if (::CLSIDFromString(clsidStrs[i].data(), &clsid) != NOERROR) continue; clsids.emplace_back(clsid); } clsids.shrink_to_fit(); return clsids; } #include <format> #include <iostream> // 登録されたAMSIプロバイダーのCLSIDと表示名を表示します。 int main() { std::wcout.imbue(std::locale("", std::locale::ctype)); auto coinit = wil::CoInitializeEx(COINIT_APARTMENTTHREADED); for (auto amsiProviderCLSID : GetAMSIProviderCLSIDs()) { auto antimalwareProvider = wil::CoCreateInstance<IAntimalwareProvider>( amsiProviderCLSID, CLSCTX_INPROC_SERVER); // 書式化したCLSIDと表示名の取得 auto clsidStr = CLSIDToStlWString(amsiProviderCLSID); wil::unique_cotaskmem_string displayName; antimalwareProvider->DisplayName(displayName.put()); std::wcout << std::format(L"{}: {}", clsidStr.data(), wil::string_get_not_null(displayName)) << std::endl; } return 0; }