Developer audience, and sample code

The Antimalware Scan Interface is designed for use by two groups of developers.

  • Application developers who want to make requests to antimalware products from within their apps.
  • Third-party creators of antimalware products who want their products to offer the best features to applications.

Application developers

AMSI is designed in particular to combat "fileless malware". Application types that can optimally leverage AMSI technology include script engines, applications that need memory buffers to be scanned before using them, and applications that process files that can contain non-PE executable code (such as Microsoft Word and Excel macros, or PDF documents). However, the usefulness of AMSI technology is not limited to those examples.

There are two ways in which you can interface with AMSI in your application.

For sample code showing how to consume AMSI within your COM application, see the IAmsiStream interface sample application.

Third-party creators of antimalware products

As a creator of antimalware products, you can choose to author and register your own in-process COM server (a DLL) to function as an AMSI provider. That AMSI provider must implement the IAntimalwareProvider interface, and it must run in-process.

Note that, after Windows 10, version 1709 (the Fall 2017 Creators' Update), your AMSI provider DLL may not work if it depends upon other DLLs in its path to be loaded at the same time. To prevent DLL hijacking, we recommend that your provider DLL load its dependencies explicitly (with a full path) using secure LoadLibrary calls, or equivalent. We recommend this instead of relying on the LoadLibrary search behavior.

The section below shows how to register your AMSI provider. For full sample code showing how to author your own AMSI provider DLL, see the IAntimalwareProvider interface sample application.

Register your provider DLL with AMSI

To begin with, you need to ensure that these Windows Registry keys exist.

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

An AMSI provider is an in-process COM server. Consequently, it needs to register itself with COM. COM classes are registered in HKLM\SOFTWARE\Classes\CLSID.

The code below shows how to register an AMSI provider, whose GUID (for this example) we will assume is 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;
}

If your DLL implements the DllRegisterServer function, as the example above does, then you can register it by using the Windows-supplied executable regsvr32.exe. From an elevated command prompt, issue a command of this form.

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

In this example, the command creates the following entries.

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

    (Default)    REG_SZ    Sample AMSI Provider implementation

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

    (Default)    REG_EXPAND_SZ    %ProgramFiles%\TestProvider\SampleAmsiProvider.dll

    ThreadingModel    REG_SZ    Both

In addition to regular COM registration, you also need to enroll the provider with AMSI. You do that by adding an entry to the following key.

HKLM\SOFTWARE\Microsoft\AMSI\Providers

For example,

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

Known issues

If you have a non-Microsoft antimalware service that's Windows Protected Process Light (PPL) or Antimalware Protected Process Light (Anti-malware PPL) that tries to load in an AMSI provider, you might see the following information in the Code Integrity event log:

 
Log Name: Microsoft-Windows-CodeIntegrity/Operational 

Source: Microsoft-Windows-CodeIntegrity 

Event ID: 3033 

Description: 

Code Integrity determined that a process (\Device\HarddiskVolume3\<Folder>\<Folder w/ the ISV name>\<Folder w/ the product name>\<ProcessName>.exe) attempted to load \Device\HarddiskVolume3\<Folder>\<Folder w/ the ISV name>\<Folder w/ the product name>\<Your Amsi Provider>.dll that did not meet the Custom 3 / Antimalware signing level requirements. 

To view the Code Integrity event log, follow these steps:

  1. Open Event Viewer.

  2. In the navigation pane, expand Applications and Services Logs > Microsoft > Windows > Code Integrity, and then select Operational.

Or if you have System Audit Integrity auditing enabled, look for this:

  • Log Name: Security
  • Source: Microsoft Windows Security
  • Event ID: 5038