You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

63 lines
2.2 KiB

  1. #nullable enable
  2. using IPA.AntiMalware.ComAPI;
  3. using IPA.Logging;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.IO;
  7. using System.Linq;
  8. using System.Text;
  9. using System.Threading.Tasks;
  10. namespace IPA.AntiMalware
  11. {
  12. internal class WindowsCOMAntiMalware : IAntiMalware
  13. {
  14. internal static WindowsCOMAntiMalware? TryInitialize()
  15. {
  16. try
  17. {
  18. return new();
  19. }
  20. catch (Exception e)
  21. {
  22. Logger.AntiMalware.Warn("Could not initialize COM-based antimalware engine:");
  23. Logger.AntiMalware.Warn(e);
  24. return null;
  25. }
  26. }
  27. private readonly IAntimalware amInterface;
  28. private WindowsCOMAntiMalware()
  29. {
  30. var amType = Type.GetTypeFromCLSID(AmsiConstants.CAntimalwareGuid, true);
  31. amInterface = (IAntimalware)Activator.CreateInstance(amType);
  32. }
  33. private static ScanResult ScanResultFromAmsiResult(AmsiResult result)
  34. => result switch
  35. {
  36. AmsiResult.Clean => ScanResult.KnownSafe,
  37. AmsiResult.NotDetected => ScanResult.NotDetected,
  38. AmsiResult.Detected => ScanResult.Detected,
  39. _ => ScanResult.MaybeMalware
  40. };
  41. public ScanResult ScanFile(FileInfo file)
  42. {
  43. using var stream = new AmsiFileStream(file, IntPtr.Zero);
  44. amInterface.Scan(stream, out var result, out var provider);
  45. Logger.AntiMalware.Trace($"Scanned file '{file}' with {provider.DisplayName()}, and got '{result}'");
  46. return ScanResultFromAmsiResult(result);
  47. }
  48. public ScanResult ScanData(byte[] data, string? contentName = null)
  49. {
  50. contentName ??= $"unknown_data_{Guid.NewGuid()}";
  51. using var stream = new AmsiMemoryStream(contentName, data, IntPtr.Zero);
  52. amInterface.Scan(stream, out var result, out var provider);
  53. Logger.AntiMalware.Trace($"Scanned data named '{contentName}' with {provider.DisplayName()}, and got '{result}'");
  54. return ScanResultFromAmsiResult(result);
  55. }
  56. }
  57. }