1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
13 // https://docs.microsoft.com/en-us/windows/desktop/api/amsi/
14 DECLARE_HANDLE(HAMSICONTEXT);
15 DECLARE_HANDLE(HAMSISESSION);
19 AMSI_RESULT_CLEAN = 0,
20 AMSI_RESULT_NOT_DETECTED = 1,
21 AMSI_RESULT_BLOCKED_BY_ADMIN_START = 0x4000,
22 AMSI_RESULT_BLOCKED_BY_ADMIN_END = 0x4fff,
23 AMSI_RESULT_DETECTED = 0x8000
26 bool AmsiResultIsMalware(DWORD result)
28 return result >= AMSI_RESULT_DETECTED;
31 bool AmsiResultIsBlockedByAdmin(DWORD result)
33 return result >= AMSI_RESULT_BLOCKED_BY_ADMIN_START
34 && result <= AMSI_RESULT_BLOCKED_BY_ADMIN_END;
37 using PAMSI_AMSISCANBUFFER_API = HRESULT(WINAPI *)(
38 _In_ HAMSICONTEXT amsiContext,
41 _In_ LPCWSTR contentName,
42 _In_opt_ HAMSISESSION session,
45 using PAMSI_AMSIINITIALIZE_API = HRESULT(WINAPI *)(
47 _Out_ HAMSICONTEXT *amsiContext);
49 PAMSI_AMSISCANBUFFER_API AmsiScanBuffer;
50 HAMSICONTEXT s_amsiContext;
51 CRITSEC_COOKIE s_csAmsi;
55 if (s_csAmsi != nullptr)
58 CRITSEC_COOKIE lock = ClrCreateCriticalSection(CrstLeafLock, CRST_REENTRANCY);
62 if (InterlockedCompareExchangeT<CRITSEC_COOKIE>(&s_csAmsi, lock, nullptr) != nullptr)
63 ClrDeleteCriticalSection(lock);
69 // Here we will invoke into AmsiScanBuffer, a centralized area for non-OS
70 // programs to report into Defender (and potentially other anti-malware tools).
71 // This should only run on in memory loads, Assembly.Load(byte[]) for example.
72 // Loads from disk are already instrumented by Defender, so calling AmsiScanBuffer
73 // wouldn't do anything.
74 bool Amsi::IsBlockedByAmsiScan(PVOID flatImageBytes, COUNT_T size)
78 if (!InitializeLock())
81 // Lazily initialize AMSI because it is very expensive
83 CRITSEC_Holder csh(s_csAmsi);
85 // Cache that we failed if this didn't work so we don't keep trying to reinitialize
86 static bool amsiInitializationAttempted = false;
87 if (s_amsiContext == nullptr && !amsiInitializationAttempted)
89 HMODULE amsi = CLRLoadLibraryEx(W("amsi.dll"), nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
92 PAMSI_AMSIINITIALIZE_API AmsiInitialize = (PAMSI_AMSIINITIALIZE_API)GetProcAddress(amsi, "AmsiInitialize");
93 if (AmsiInitialize != nullptr)
95 HAMSICONTEXT amsiContext = nullptr;
96 if (AmsiInitialize(W("coreclr"), &amsiContext) == S_OK)
98 AmsiScanBuffer = (PAMSI_AMSISCANBUFFER_API)GetProcAddress(amsi, "AmsiScanBuffer");
99 if (AmsiScanBuffer != nullptr)
101 s_amsiContext = amsiContext;
107 amsiInitializationAttempted = true;
111 if (s_amsiContext == nullptr || AmsiScanBuffer == nullptr)
115 HRESULT hr = AmsiScanBuffer(s_amsiContext, flatImageBytes, size, nullptr, nullptr, &result);
116 if (hr == S_OK && (AmsiResultIsMalware(result) || AmsiResultIsBlockedByAdmin(result)))