2020-07-15 03:04:31 +00:00
|
|
|
|
using System.IO;
|
2020-07-15 22:41:49 +00:00
|
|
|
|
using System.Linq;
|
2020-07-15 04:20:56 +00:00
|
|
|
|
using System.Threading;
|
2020-07-15 03:04:31 +00:00
|
|
|
|
using System.Threading.Tasks;
|
2020-07-15 04:20:56 +00:00
|
|
|
|
using Org.BouncyCastle.Bcpg;
|
2020-07-15 03:04:31 +00:00
|
|
|
|
using Wabbajack.Common;
|
2020-07-15 04:20:56 +00:00
|
|
|
|
using Wabbajack.Common.FileSignatures;
|
2020-07-15 03:04:31 +00:00
|
|
|
|
|
|
|
|
|
namespace Wabbajack.Lib
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Wrapper around Windows Defender's commandline tool
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class VirusScanner
|
|
|
|
|
{
|
|
|
|
|
public enum Result : int
|
|
|
|
|
{
|
|
|
|
|
NotMalware = 0,
|
|
|
|
|
Malware = 2
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-15 22:41:49 +00:00
|
|
|
|
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");
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-15 04:20:56 +00:00
|
|
|
|
public static async Task<(Hash, Result)> ScanStream(Stream stream)
|
2020-07-15 03:04:31 +00:00
|
|
|
|
{
|
2020-07-15 04:20:56 +00:00
|
|
|
|
var ms = new MemoryStream();
|
|
|
|
|
await stream.CopyToAsync(ms);
|
|
|
|
|
ms.Position = 0;
|
|
|
|
|
|
|
|
|
|
var hash = await ms.xxHashAsync();
|
|
|
|
|
ms.Position = 0;
|
|
|
|
|
|
2020-07-15 03:04:31 +00:00
|
|
|
|
await using var file = new TempFile();
|
2020-07-15 04:20:56 +00:00
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-07-15 03:04:31 +00:00
|
|
|
|
|
2020-07-15 04:20:56 +00:00
|
|
|
|
var process = new ProcessHelper
|
2020-07-15 03:04:31 +00:00
|
|
|
|
{
|
2020-07-15 22:41:49 +00:00
|
|
|
|
Path = ScannerPath(),
|
2020-07-15 03:04:31 +00:00
|
|
|
|
Arguments = new object[] {"-Scan", "-ScanType", "3", "-DisableRemediation", "-File", file.Path},
|
|
|
|
|
};
|
|
|
|
|
|
2020-07-15 04:20:56 +00:00
|
|
|
|
return (hash, (Result)await process.Start());
|
2020-07-15 03:04:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-07-15 04:20:56 +00:00
|
|
|
|
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<bool> ShouldScan(AbsolutePath path)
|
2020-07-15 03:04:31 +00:00
|
|
|
|
{
|
2020-07-15 04:20:56 +00:00
|
|
|
|
return await ExecutableChecker.MatchesAsync(path) != null;
|
2020-07-15 03:04:31 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|