Consume Antimalware Scan Interface (AMSI) from C#

AMSI Protection Provider
Windows 10 have a new mechanism that will allow software developers to integrate their applications with the antimalware programs exist on users’ computers.

The goal of the new Antimalware Scan Interface (AMSI) is to let applications send content to the locally installed antivirus product to be checked for malware.

C# sample code is not available in msdn. Here is the sample C# code to communicate with antimalware product installed in your machine. I have Windows Defender installed in my machine and this code communicates to windows defender internally to get the job done.

  public enum AMSI_RESULT   
 3:   {   
 4:    AMSI_RESULT_CLEAN = 0,   
 5:    AMSI_RESULT_NOT_DETECTED = 1,   
 6:    AMSI_RESULT_DETECTED = 32768   
 7:   }   
 8:    
 9:   [DllImport("Amsi.dll", EntryPoint = "AmsiInitialize", CallingConvention = CallingConvention.StdCall)]   
 10:   public static extern int AmsiInitialize([MarshalAs(UnmanagedType.LPWStr)]string appName, out IntPtr amsiContext);   
 11:    
 12:   [DllImport("Amsi.dll", EntryPoint = "AmsiUninitialize", CallingConvention = CallingConvention.StdCall)]   
 13:   public static extern void AmsiUninitialize(IntPtr amsiContext);   
 14:    
 15:   [DllImport("Amsi.dll", EntryPoint = "AmsiOpenSession", CallingConvention = CallingConvention.StdCall)]   
 16:   public static extern int AmsiOpenSession(IntPtr amsiContext, out IntPtr session);   
 17:    
 18:   [DllImport("Amsi.dll", EntryPoint = "AmsiCloseSession", CallingConvention = CallingConvention.StdCall)]   
 19:   public static extern void AmsiCloseSession(IntPtr amsiContext, IntPtr session);   
 20:    
 21:   [DllImport("Amsi.dll", EntryPoint = "AmsiScanString", CallingConvention = CallingConvention.StdCall)]   
 22:   public static extern int AmsiScanString(IntPtr amsiContext, [InAttribute()] [MarshalAsAttribute(UnmanagedType.LPWStr)]string @string, [InAttribute()] [MarshalAsAttribute(UnmanagedType.LPWStr)]string contentName, IntPtr session, out AMSI_RESULT result);   
 23:   [DllImport("Amsi.dll", EntryPoint = "AmsiScanBuffer", CallingConvention = CallingConvention.StdCall)]   
 24:   public static extern int AmsiScanBuffer(IntPtr amsiContext, byte[] buffer, ulong length, string contentName, IntPtr session, out AMSI_RESULT result);   
 25:    
 26:   //This method apparently exists on MSDN but not in AMSI.dll (version 4.9.10586.0)   
 27:   [DllImport("Amsi.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]   
 28:   public static extern bool AmsiResultIsMalware(AMSI_RESULT result);   
 29:    
 30:   private void CallAntimalwareScanInterface()   
 31:   {   
 32:    IntPtr amsiContext;   
 33:    IntPtr session;   
 34:    AMSI_RESULT result = 0;   
 35:    int returnValue;   
 36:    
 37:    returnValue = AmsiInitialize("VirusScanAPI", out amsiContext); //appName is the name of the application consuming the Amsi.dll. Here my project name is VirusScanAPI.   
 38:    returnValue = AmsiOpenSession(amsiContext, out session);   
 39:    returnValue = AmsiScanString(amsiContext, @"X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*", "EICAR", session, out result); //I've used EICAR test string.   
 40:    AmsiCloseSession(amsiContext, session);   
 41:    AmsiUninitialize(amsiContext);   
 42:   }   

DLLImport entry for Amsi.dll win32 APIs can be found here.

Happy coding!

Comments

  1. I am using "AmsiScanBuffer" method. This is working file for unzipped files. But not working if i am scanning a stream of a zip file which contains EICAR sample virus file. Please suggest if need to handle zip files differently.

    ReplyDelete
    Replies
    1. Not sure about this, Probably you could use opensource ClamAV antivirus scan service.

      Delete
  2. The postings on your site are always excellent. Thanks for the great share and keep up this great work!
    Get Free anti malware tool.

    ReplyDelete
  3. AmsiResultIsMalware is a macro, not a function, which evaluates to:

    r >= AMSI_RESULT_DETECTED

    ReplyDelete
  4. Could somebody tell me about this.
    AMSI_RESULT_CLEAN = 0,
    AMSI_RESULT_NOT_DETECTED = 1,
    AMSI_RESULT_DETECTED = 32768 .On What basis this values are predefined?

    ReplyDelete
  5. Please refer msdn link, https://docs.microsoft.com/en-us/windows/desktop/api/amsi/ne-amsi-amsi_result

    "The antimalware provider may return a result between 1 and 32767, inclusive, as an estimated risk level. "

    "Any return result equal to or larger than 32768 is considered malware, and the content should be blocked."

    ReplyDelete
    Replies
    1. 32768 is file length in bytes?

      Delete
    2. nope. It's the Int32 limit. Oops I see , I'm replying after a long time .

      Delete
  6. Can use this method in .net core 2.2?

    ReplyDelete
  7. Any sample c# code for working with IAmsiStream?

    ReplyDelete
  8. I test this but it's indicate that the result is "AMSI_RESULT_CLEAN" for the Eicar string.
    What are the prerequisites for the AMSI to work properly ?

    ReplyDelete
    Replies
    1. Windows Defender is required in the machine or any antivirus .

      Delete
  9. this codebase may help

    https://github.com/two06/AMSI_Handler

    ReplyDelete

Post a Comment

Popular posts from this blog

Munnar Diaries [Part 1] - Backpacking to Munnar and spectacular Vattavada village

Missing her badly. Need to date her once more at least.. ;)