From a70bc778693c96ffad58dc90023b3c1266e11997 Mon Sep 17 00:00:00 2001 From: Anairkoen Schno Date: Wed, 28 Apr 2021 01:09:11 -0500 Subject: [PATCH] Attempt to make COM anti-malware work, find out that Mono is utterly broken --- IPA.Loader/AntiMalware/AmsiConstants.cs | 3 ++ .../_HideInNet3/ComAPI/IAntimalware.cs | 15 +++++---- .../_HideInNet3/WindowsCOMAntiMalware.cs | 31 +++++++++++++++++-- 3 files changed, 40 insertions(+), 9 deletions(-) diff --git a/IPA.Loader/AntiMalware/AmsiConstants.cs b/IPA.Loader/AntiMalware/AmsiConstants.cs index de310955..d77aa55c 100644 --- a/IPA.Loader/AntiMalware/AmsiConstants.cs +++ b/IPA.Loader/AntiMalware/AmsiConstants.cs @@ -6,6 +6,9 @@ namespace IPA.AntiMalware internal static class AmsiConstants { public const string AppName = "BSIPA/" + Config.SelfConfig.IPAVersion; + public const string IAntimalwareGuidStr = "82d29c2e-f062-44e6-b5c9-3d9a2f24a2df"; + public static readonly Guid IAntimalwareGuid = new(IAntimalwareGuidStr); public static readonly Guid CAntimalwareGuid = new("fdb00e52-a214-4aa1-8fba-4357bb0072ec"); + public static readonly Guid IUnknownGuid = new("00000000-0000-0000-C000-000000000046"); } } diff --git a/IPA.Loader/AntiMalware/_HideInNet3/ComAPI/IAntimalware.cs b/IPA.Loader/AntiMalware/_HideInNet3/ComAPI/IAntimalware.cs index 53547f96..109fce79 100644 --- a/IPA.Loader/AntiMalware/_HideInNet3/ComAPI/IAntimalware.cs +++ b/IPA.Loader/AntiMalware/_HideInNet3/ComAPI/IAntimalware.cs @@ -8,24 +8,27 @@ using System.Threading.Tasks; namespace IPA.AntiMalware.ComAPI { - [Guid("82d29c2e-f062-44e6-b5c9-3d9a2f24a2df")] - [ComVisible(true)] + [ComImport] + [Guid(AmsiConstants.IAntimalwareGuidStr)] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface IAntimalware { void Scan([In] IAmsiStream stream, [Out] out AmsiResult result, [Out] out IAntimalwareProvider provider); void CloseSession([In] ulong session); } + [ComImport] [Guid("3e47f2e5-81d4-4d3b-897f-545096770373")] - [ComVisible(true)] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface IAmsiStream { - unsafe void GetAttribute([In] AmsiAttribute attribute, [In] uint dataSize, [Out] byte* buffer, out uint writtenData); - unsafe void Read([In] ulong position, [In] uint dataSize, [Out] byte* buffer, out uint readSize); + unsafe void GetAttribute([In] AmsiAttribute attribute, [In] uint dataSize, [Out] byte* buffer, [Out] out uint writtenData); + unsafe void Read([In] ulong position, [In] uint dataSize, [Out] byte* buffer, [Out] out uint readSize); } + [ComImport] [Guid("b2cabfe3-fe04-42b1-a5df-08d483d4d125")] - [ComVisible(true)] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface IAntimalwareProvider { [return: MarshalAs(UnmanagedType.LPWStr)] string DisplayName(); diff --git a/IPA.Loader/AntiMalware/_HideInNet3/WindowsCOMAntiMalware.cs b/IPA.Loader/AntiMalware/_HideInNet3/WindowsCOMAntiMalware.cs index 236efcf0..70868bd2 100644 --- a/IPA.Loader/AntiMalware/_HideInNet3/WindowsCOMAntiMalware.cs +++ b/IPA.Loader/AntiMalware/_HideInNet3/WindowsCOMAntiMalware.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; @@ -14,6 +15,9 @@ namespace IPA.AntiMalware { internal static WindowsCOMAntiMalware? TryInitialize() { + // Mono's COM interop *fundamentally doesn't work.* + // End of story. +#if false try { return new(); @@ -22,18 +26,39 @@ namespace IPA.AntiMalware { Logger.AntiMalware.Warn("Could not initialize COM-based antimalware engine:"); Logger.AntiMalware.Warn(e); - return null; } +#endif + return null; } private readonly IAntimalware amInterface; private WindowsCOMAntiMalware() { - var amType = Type.GetTypeFromCLSID(AmsiConstants.CAntimalwareGuid, true); - amInterface = (IAntimalware)Activator.CreateInstance(amType); + var hr = CoCreateInstanceAM(AmsiConstants.CAntimalwareGuid, + null, + 0x1 | 0x4 /* inproc server, local server */, + AmsiConstants.IAntimalwareGuid, + out var antimalware); + Marshal.ThrowExceptionForHR(hr); + + amInterface = antimalware; } + [DllImport("ole32", + CallingConvention = CallingConvention.Winapi, + ExactSpelling = true, + PreserveSig = false, + EntryPoint = "CoCreateInstance")] + [DefaultDllImportSearchPaths(DllImportSearchPath.System32)] + private static extern int CoCreateInstanceAM( + [In] in Guid clsid, + [In, MarshalAs(UnmanagedType.Interface)] object? unkOuter, + [In] int dwClsContext, + [In] in Guid iid, + [Out, MarshalAs(UnmanagedType.Interface)] out IAntimalware @interface); + + private static ScanResult ScanResultFromAmsiResult(AmsiResult result) => result switch {