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.

64 lines
2.3 KiB

  1. #nullable enable
  2. using IPA.AntiMalware.WinAPI;
  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 WindowsAntiMalware : IAntiMalware
  13. {
  14. internal static WindowsAntiMalware? TryInitialize()
  15. {
  16. try
  17. {
  18. return new();
  19. }
  20. catch (Exception e)
  21. {
  22. Logger.AntiMalware.Warn("Could not initialize antimalware engine:");
  23. Logger.AntiMalware.Warn(e);
  24. return null;
  25. }
  26. }
  27. private readonly IAntimalware amInterface;
  28. private WindowsAntiMalware()
  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. var a when a is >= AmsiResult.BlockedByAdminStart and <= AmsiResult.BlockedByAdminEnd => ScanResult.BlockedByPolicy,
  40. _ => ScanResult.NotDetected,
  41. };
  42. public ScanResult ScanFile(FileInfo file)
  43. {
  44. using var stream = new AmsiFileStream(file, IntPtr.Zero);
  45. amInterface.Scan(stream, out var result, out var provider);
  46. Logger.AntiMalware.Debug($"Scanned file '{file}' with {provider.DisplayName()}, and got '{result}'");
  47. return ScanResultFromAmsiResult(result);
  48. }
  49. public ScanResult ScanData(byte[] data, string? contentName = null)
  50. {
  51. contentName ??= $"unknown_data_{Guid.NewGuid()}";
  52. using var stream = new AmsiMemoryStream(contentName, data, IntPtr.Zero);
  53. amInterface.Scan(stream, out var result, out var provider);
  54. Logger.AntiMalware.Debug($"Scanned data named '{contentName}' with {provider.DisplayName()}, and got '{result}'");
  55. return ScanResultFromAmsiResult(result);
  56. }
  57. }
  58. }