using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Org.BouncyCastle.Bcpg;
using Wabbajack.Common;
using Wabbajack.Common.FileSignatures;
namespace Wabbajack.Lib
{
///
/// Wrapper around Windows Defender's commandline tool
///
public class VirusScanner
{
public enum Result : int
{
NotMalware = 0,
Malware = 2
}
private static AbsolutePath ScannerPath()
{
return ((AbsolutePath)@"C:\ProgramData\Microsoft\Windows Defender\Platform")
.EnumerateDirectories(recursive:false)
.OrderByDescending(f => f.FileName)
.First()
.EnumerateFiles(recursive:true)
.First(f => f.FileName == (RelativePath)"MpCmdRun.exe");
}
public static async Task<(Hash, Result)> ScanStream(Stream stream)
{
var ms = new MemoryStream();
await stream.CopyToAsync(ms);
ms.Position = 0;
var hash = await ms.xxHashAsync();
ms.Position = 0;
await using var file = new TempFile();
try
{
await file.Path.WriteAllAsync(ms);
}
catch (IOException ex)
{
// Was caught before we could fully scan the file due to real-time virus scans
if (ex.Message.ToLowerInvariant().Contains("malware"))
{
return (hash, Result.Malware);
}
}
var process = new ProcessHelper
{
Path = ScannerPath(),
Arguments = new object[] {"-Scan", "-ScanType", "3", "-DisableRemediation", "-File", file.Path},
};
return (hash, (Result)await process.Start());
}
private static SignatureChecker ExecutableChecker = new SignatureChecker(Definitions.FileType.DLL,
Definitions.FileType.EXE,
Definitions.FileType.PIF,
Definitions.FileType.QXD,
Definitions.FileType.QTX,
Definitions.FileType.DRV,
Definitions.FileType.SYS,
Definitions.FileType.COM);
public static async Task ShouldScan(AbsolutePath path)
{
return await ExecutableChecker.MatchesAsync(path) != null;
}
}
}