开发人员受众和示例代码

反恶意软件扫描接口是为两组开发人员设计的。

  • 希望从应用中请求反恶意软件产品的应用程序开发人员。
  • 反恶意软件产品的第三方创建者希望其产品为应用程序提供最佳功能。

应用程序开发人员

AMSI 专为打击“无文件恶意软件”而设计。 可以充分利用 AMSI 技术的应用程序类型包括脚本引擎、在使用前需要扫描内存缓冲区的应用程序,以及处理可包含非 PE 可执行代码(如 Microsoft Word 和 Excel 宏或 PDF 文档)的文件的应用程序。 然而,AMSI 技术的实用性并不局限于这些示例。

有两种方法可以在应用程序中与 AMSI 进行交互。

有关介绍如何在 COM 应用程序中使用 AMSI 的示例代码,请参阅 IAmsiStream 接口示例应用程序

反恶意软件产品的第三方创建者

作为反恶意软件产品的创建者,可以选择创建并注册自己的进程内 COM 服务器 (DLL),以充当 AMSI 提供程序。 AMSI 提供程序必须实现 IAntimalwareProvider 接口,并且必须在进程内运行。

请注意:在 Windows 10 版本 1709(2017 年秋季创建者更新)之后,如果 AMSI 提供程序 DLL 依赖于要同时加载的路径中的其他 DLL,则你的 AMSI 提供程序 DLL 可能无法正常工作。 为了防止 DLL 劫持,我们建议提供程序 DLL 使用安全 LoadLibrary 调用或等效方式显式(使用完整路径)加载其依赖项。 我们建议这样做,而不是依赖 LoadLibrary 搜索行为。

以下部分介绍如何注册 AMSI 提供程序。 有关显示如何编写自己的 AMSI 提供程序 DLL 的完整示例代码,请参阅 IAntimalwareProvider 接口示例应用程序

向 AMSI 注册提供程序 DLL

首先,需要确保这些 Windows 注册表项存在。

  • HKLM\SOFTWARE\Microsoft\AMSI\Providers
  • HKLM\SOFTWARE\Classes\CLSID

AMSI 提供程序是进程内 COM 服务器。 因此,它需要向 COM 注册自身。 COM 类在 HKLM\SOFTWARE\Classes\CLSID 中注册。

以下代码示例显示如何注册 AMSI 提供程序,我们将假定其 GUID(在本例中)为 2E5D8A62-77F9-4F7B-A90C-2744820139B2

#include <strsafe.h>
...
HRESULT SetKeyStringValue(_In_ HKEY key, _In_opt_ PCWSTR subkey, _In_opt_ PCWSTR valueName, _In_ PCWSTR stringValue)
{
    LONG status = RegSetKeyValue(key, subkey, valueName, REG_SZ, stringValue, (wcslen(stringValue) + 1) * sizeof(wchar_t));
    return HRESULT_FROM_WIN32(status);
}

STDAPI DllRegisterServer()
{
    wchar_t modulePath[MAX_PATH];
    if (GetModuleFileName(g_currentModule, modulePath, ARRAYSIZE(modulePath)) >= ARRAYSIZE(modulePath))
    {
        return E_UNEXPECTED;
    }

    // Create a standard COM registration for our CLSID.
    // The class must be registered as "Both" threading model,
    // and support multithreaded access.
    wchar_t clsidString[40];
    if (StringFromGUID2(__uuidof(SampleAmsiProvider), clsidString, ARRAYSIZE(clsidString)) == 0)
    {
        return E_UNEXPECTED;
    }

    wchar_t keyPath[200];
    HRESULT hr = StringCchPrintf(keyPath, ARRAYSIZE(keyPath), L"Software\\Classes\\CLSID\\%ls", clsidString);
    if (FAILED(hr)) return hr;

    hr = SetKeyStringValue(HKEY_LOCAL_MACHINE, keyPath, nullptr, L"SampleAmsiProvider");
    if (FAILED(hr)) return hr;

    hr = StringCchPrintf(keyPath, ARRAYSIZE(keyPath), L"Software\\Classes\\CLSID\\%ls\\InProcServer32", clsidString);
    if (FAILED(hr)) return hr;

    hr = SetKeyStringValue(HKEY_LOCAL_MACHINE, keyPath, nullptr, modulePath);
    if (FAILED(hr)) return hr;

    hr = SetKeyStringValue(HKEY_LOCAL_MACHINE, keyPath, L"ThreadingModel", L"Both");
    if (FAILED(hr)) return hr;

    // Register this CLSID as an anti-malware provider.
    hr = StringCchPrintf(keyPath, ARRAYSIZE(keyPath), L"Software\\Microsoft\\AMSI\\Providers\\%ls", clsidString);
    if (FAILED(hr)) return hr;

    hr = SetKeyStringValue(HKEY_LOCAL_MACHINE, keyPath, nullptr, L"SampleAmsiProvider");
    if (FAILED(hr)) return hr;

    return S_OK;
}

如果 DLL 实现 DllRegisterServer 函数,如上例所示,则可以使用 Windows 提供的可执行文件 regsvr32.exe 注册。 从提升的命令提示符中,发出以下形式的命令。

C:>C:\Windows\System32\regsvr32.exe SampleAmsiProvider.dll

在本例中,该命令将创建以下条目。

HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{2E5D8A62-77F9-4F7B-A90C-2744820139B2}

    (默认值)REG_SZ 示例 AMSI 提供程序实现

HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{2E5D8A62-77F9-4F7B-A90C-2744820139B2}\InprocServer32

    (默认值)REG_EXPAND_SZ %ProgramFiles%\TestProvider\SampleAmsiProvider.dll

    ThreadingModel REG_SZ Both

除了常规的 COM 注册,还需要向 AMSI 注册提供程序。 可以通过向以下键添加一个条目来完成此操作。

HKLM\SOFTWARE\Microsoft\AMSI\Providers

例如,

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\AMSI\Providers\{2E5D8A62-77F9-4F7B-A90C-2744820139B2}