diff --git a/IPA.Loader/AntiMalware/_HideInNet3/WinAPI/Constants.cs b/IPA.Loader/AntiMalware/AmsiConstants.cs similarity index 64% rename from IPA.Loader/AntiMalware/_HideInNet3/WinAPI/Constants.cs rename to IPA.Loader/AntiMalware/AmsiConstants.cs index 65dc96cc..de310955 100644 --- a/IPA.Loader/AntiMalware/_HideInNet3/WinAPI/Constants.cs +++ b/IPA.Loader/AntiMalware/AmsiConstants.cs @@ -1,11 +1,7 @@ #nullable enable using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -namespace IPA.AntiMalware.WinAPI +namespace IPA.AntiMalware { internal static class AmsiConstants { diff --git a/IPA.Loader/AntiMalware/AntiMalwareEngine.cs b/IPA.Loader/AntiMalware/AntiMalwareEngine.cs index 3c70c09f..fcf9484d 100644 --- a/IPA.Loader/AntiMalware/AntiMalwareEngine.cs +++ b/IPA.Loader/AntiMalware/AntiMalwareEngine.cs @@ -23,7 +23,7 @@ namespace IPA.AntiMalware { IAntiMalware? engine = null; #if !NET35 - engine = WindowsAntiMalware.TryInitialize(); + engine = WindowsCOMAntiMalware.TryInitialize(); #endif engine ??= new NoopAntiMalware(); diff --git a/IPA.Loader/AntiMalware/WindowsWin32AntiMalware.cs b/IPA.Loader/AntiMalware/WindowsWin32AntiMalware.cs new file mode 100644 index 00000000..aef3c1a4 --- /dev/null +++ b/IPA.Loader/AntiMalware/WindowsWin32AntiMalware.cs @@ -0,0 +1,104 @@ +#nullable enable +using IPA.AntiMalware.ComAPI; +using IPA.Logging; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace IPA.AntiMalware +{ + internal class WindowsWin32AntiMalware : IAntiMalware, IDisposable + { + internal static WindowsWin32AntiMalware? TryInitialize() + { + try + { + return new(); + } + catch (Exception e) + { + Logger.AntiMalware.Warn("Could not initialize antimalware engine:"); + Logger.AntiMalware.Warn(e); + return null; + } + } + + private readonly IntPtr handle; + private bool disposedValue; + + private WindowsWin32AntiMalware() + { + AmsiInitialize(AmsiConstants.AppName, out handle); + } + + private static ScanResult ScanResultFromAmsiResult(AmsiResult result) + => result switch + { + AmsiResult.Clean => ScanResult.KnownSafe, + AmsiResult.NotDetected => ScanResult.NotDetected, + AmsiResult.Detected => ScanResult.Detected, + _ => ScanResult.MaybeMalware + }; + + public ScanResult ScanFile(FileInfo file) + { + var data = File.ReadAllBytes(file.FullName); + return ScanData(data, file.FullName); + } + + public ScanResult ScanData(byte[] data, string? contentName = null) + { + contentName ??= $"unknown_data_{Guid.NewGuid()}"; + + + + Logger.AntiMalware.Debug($"Scanned data named '{contentName}' with {provider.DisplayName()}, and got '{result}'"); + return ScanResultFromAmsiResult(result); + } + + protected virtual void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + // we have no disposable managed state + } + + AmsiUninitialize(handle); + disposedValue = true; + } + } + + ~WindowsWin32AntiMalware() + { + // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + Dispose(disposing: false); + } + + public void Dispose() + { + // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + + [DllImport("amsi", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Unicode, ExactSpelling = true)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + private static extern void AmsiInitialize([MarshalAs(UnmanagedType.LPWStr)] string appName, [Out] out IntPtr handle); + + [DllImport("amsi", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Unicode, ExactSpelling = true)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + private static extern void AmsiUninitialize(IntPtr handle); + + [DllImport("amsi", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Unicode, ExactSpelling = true)] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + private static extern void AmsiScanBuffer(IntPtr context, + [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] buffer, uint length, + [MarshalAs(UnmanagedType.LPWStr)] string contentName, IntPtr session, [Out] out AmsiResult result); + } +} diff --git a/IPA.Loader/AntiMalware/_HideInNet3/WinAPI/AmsiFileStream.cs b/IPA.Loader/AntiMalware/_HideInNet3/ComAPI/AmsiFileStream.cs similarity index 96% rename from IPA.Loader/AntiMalware/_HideInNet3/WinAPI/AmsiFileStream.cs rename to IPA.Loader/AntiMalware/_HideInNet3/ComAPI/AmsiFileStream.cs index a14653ca..be0d383f 100644 --- a/IPA.Loader/AntiMalware/_HideInNet3/WinAPI/AmsiFileStream.cs +++ b/IPA.Loader/AntiMalware/_HideInNet3/ComAPI/AmsiFileStream.cs @@ -7,7 +7,7 @@ using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; -namespace IPA.AntiMalware.WinAPI +namespace IPA.AntiMalware.ComAPI { internal class AmsiFileStream : IAmsiStream, IDisposable { diff --git a/IPA.Loader/AntiMalware/_HideInNet3/WinAPI/AmsiMemoryStream.cs b/IPA.Loader/AntiMalware/_HideInNet3/ComAPI/AmsiMemoryStream.cs similarity index 96% rename from IPA.Loader/AntiMalware/_HideInNet3/WinAPI/AmsiMemoryStream.cs rename to IPA.Loader/AntiMalware/_HideInNet3/ComAPI/AmsiMemoryStream.cs index 8aabd050..a611fa7a 100644 --- a/IPA.Loader/AntiMalware/_HideInNet3/WinAPI/AmsiMemoryStream.cs +++ b/IPA.Loader/AntiMalware/_HideInNet3/ComAPI/AmsiMemoryStream.cs @@ -7,7 +7,7 @@ using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; -namespace IPA.AntiMalware.WinAPI +namespace IPA.AntiMalware.ComAPI { internal class AmsiMemoryStream : IAmsiStream, IDisposable { diff --git a/IPA.Loader/AntiMalware/_HideInNet3/WinAPI/IAntimalware.cs b/IPA.Loader/AntiMalware/_HideInNet3/ComAPI/IAntimalware.cs similarity index 100% rename from IPA.Loader/AntiMalware/_HideInNet3/WinAPI/IAntimalware.cs rename to IPA.Loader/AntiMalware/_HideInNet3/ComAPI/IAntimalware.cs diff --git a/IPA.Loader/AntiMalware/_HideInNet3/WindowsAntiMalware.cs b/IPA.Loader/AntiMalware/_HideInNet3/WindowsCOMAntiMalware.cs similarity index 88% rename from IPA.Loader/AntiMalware/_HideInNet3/WindowsAntiMalware.cs rename to IPA.Loader/AntiMalware/_HideInNet3/WindowsCOMAntiMalware.cs index 048dca96..1a71d371 100644 --- a/IPA.Loader/AntiMalware/_HideInNet3/WindowsAntiMalware.cs +++ b/IPA.Loader/AntiMalware/_HideInNet3/WindowsCOMAntiMalware.cs @@ -1,5 +1,5 @@ #nullable enable -using IPA.AntiMalware.WinAPI; +using IPA.AntiMalware.ComAPI; using IPA.Logging; using System; using System.Collections.Generic; @@ -10,9 +10,9 @@ using System.Threading.Tasks; namespace IPA.AntiMalware { - internal class WindowsAntiMalware : IAntiMalware + internal class WindowsCOMAntiMalware : IAntiMalware { - internal static WindowsAntiMalware? TryInitialize() + internal static WindowsCOMAntiMalware? TryInitialize() { try { @@ -28,7 +28,7 @@ namespace IPA.AntiMalware private readonly IAntimalware amInterface; - private WindowsAntiMalware() + private WindowsCOMAntiMalware() { var amType = Type.GetTypeFromCLSID(AmsiConstants.CAntimalwareGuid, true); amInterface = (IAntimalware)Activator.CreateInstance(amType);