Private/Threat.Amsi.ps1

function Initialize-OIAmsiInterop {
    [CmdletBinding()]
    param()

    if (-not (Test-OIIsWindows)) {
        throw 'AMSI is available only on Windows.'
    }

    if ('OffsetInspect.Interop.AmsiSession' -as [type]) {
        return
    }

    $source = @'
using System;
using System.Runtime.InteropServices;

namespace OffsetInspect.Interop
{
    public sealed class AmsiScanResponse
    {
        public int HResult { get; private set; }
        public int Result { get; private set; }

        public AmsiScanResponse(int hResult, int result)
        {
            HResult = hResult;
            Result = result;
        }
    }

    public sealed class AmsiSession : IDisposable
    {
        private IntPtr _context;
        private IntPtr _session;
        private bool _disposed;

        [DllImport("amsi.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Winapi)]
        private static extern int AmsiInitialize(string appName, out IntPtr amsiContext);

        [DllImport("amsi.dll", CallingConvention = CallingConvention.Winapi)]
        private static extern int AmsiOpenSession(IntPtr amsiContext, out IntPtr amsiSession);

        [DllImport("amsi.dll", CallingConvention = CallingConvention.Winapi)]
        private static extern void AmsiCloseSession(IntPtr amsiContext, IntPtr amsiSession);

        [DllImport("amsi.dll", CallingConvention = CallingConvention.Winapi)]
        private static extern void AmsiUninitialize(IntPtr amsiContext);

        [DllImport("amsi.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Winapi)]
        private static extern int AmsiScanBuffer(
            IntPtr amsiContext,
            byte[] buffer,
            uint length,
            string contentName,
            IntPtr amsiSession,
            out int result);

        [DllImport("amsi.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Winapi)]
        private static extern int AmsiScanString(
            IntPtr amsiContext,
            string content,
            string contentName,
            IntPtr amsiSession,
            out int result);

        public AmsiSession(string appName)
        {
            int hr = AmsiInitialize(appName, out _context);
            if (hr < 0)
            {
                Marshal.ThrowExceptionForHR(hr);
            }

            hr = AmsiOpenSession(_context, out _session);
            if (hr < 0)
            {
                AmsiUninitialize(_context);
                _context = IntPtr.Zero;
                Marshal.ThrowExceptionForHR(hr);
            }
        }

        public AmsiScanResponse ScanBytes(byte[] buffer, string contentName)
        {
            return ScanBytePrefix(buffer, buffer == null ? 0 : buffer.Length, contentName);
        }

        public AmsiScanResponse ScanBytePrefix(byte[] buffer, int length, string contentName)
        {
            if (_disposed)
            {
                throw new ObjectDisposedException("AmsiSession");
            }

            if (buffer == null)
            {
                buffer = new byte[0];
            }

            if (length < 0 || length > buffer.Length)
            {
                throw new ArgumentOutOfRangeException("length");
            }

            int result;
            int hr = AmsiScanBuffer(_context, buffer, (uint)length, contentName, _session, out result);
            return new AmsiScanResponse(hr, result);
        }

        public AmsiScanResponse ScanString(string content, string contentName)
        {
            if (_disposed)
            {
                throw new ObjectDisposedException("AmsiSession");
            }

            if (content == null)
            {
                content = String.Empty;
            }

            int result;
            int hr = AmsiScanString(_context, content, contentName, _session, out result);
            return new AmsiScanResponse(hr, result);
        }

        public void Dispose()
        {
            if (_disposed)
            {
                return;
            }

            if (_session != IntPtr.Zero && _context != IntPtr.Zero)
            {
                AmsiCloseSession(_context, _session);
                _session = IntPtr.Zero;
            }

            if (_context != IntPtr.Zero)
            {
                AmsiUninitialize(_context);
                _context = IntPtr.Zero;
            }

            _disposed = true;
            GC.SuppressFinalize(this);
        }

        ~AmsiSession()
        {
            Dispose();
        }
    }
}
'@


    Add-Type -TypeDefinition $source -Language CSharp -ErrorAction Stop
}

function ConvertFrom-OIAmsiResponse {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true)]
        [object]$Response
    )

    $hresult = [int]$Response.HResult
    $providerResult = [int]$Response.Result

    if ($hresult -lt 0) {
        $unsignedHResult = [BitConverter]::ToUInt32([BitConverter]::GetBytes($hresult), 0)
        $hresultText = '0x{0:X8}' -f $unsignedHResult
        return [pscustomobject]@{
            Status         = 'Error'
            ProviderResult = $providerResult
            HResult        = $hresultText
            SignatureName  = $null
            Message        = "AMSI returned HRESULT $hresultText."
            RawOutput      = $null
        }
    }

    if ($providerResult -ge 32768) {
        $status = 'Detected'
    }
    elseif ($providerResult -ge 16384 -and $providerResult -le 20479) {
        $status = 'Blocked'
    }
    elseif ($providerResult -eq 0) {
        $status = 'Clean'
    }
    else {
        $status = 'NotDetected'
    }

    return [pscustomobject]@{
        Status         = $status
        ProviderResult = $providerResult
        HResult        = '0x00000000'
        SignatureName  = $null
        Message        = $null
        RawOutput      = $null
    }
}

function Get-OIAmsiProviderMetadata {
    [CmdletBinding()]
    param()

    $metadata = [ordered]@{
        Provider = 'AMSI'
        Platform = 'Windows'
        MetadataNote = 'Defender status fields are supplemental and do not prove which AMSI provider handled the scan.'
    }

    $command = Get-Command Get-MpComputerStatus -ErrorAction SilentlyContinue
    if ($null -ne $command) {
        try {
            $status = Get-MpComputerStatus -ErrorAction Stop
            $metadata.DefenderAntivirusEnabled = $status.AntivirusEnabled
            $metadata.DefenderRealTimeProtectionEnabled = $status.RealTimeProtectionEnabled
            $metadata.DefenderSignatureVersion = $status.AntivirusSignatureVersion
            $metadata.DefenderEngineVersion = $status.AMEngineVersion
            $metadata.DefenderProductVersion = $status.AMProductVersion
        }
        catch {
            $metadata.MetadataWarning = $_.Exception.Message
        }
    }

    return [pscustomobject]$metadata
}