MalwareMultiScan/MalwareMultiScan.Backends/Backends/Abstracts/AbstractLocalProcessScanBackend.cs

73 lines
2.6 KiB
C#
Raw Normal View History

2020-10-20 16:20:38 +03:00
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
namespace MalwareMultiScan.Backends.Backends.Abstracts
{
public abstract class AbstractLocalProcessScanBackend : AbstractScanBackend
{
private readonly ILogger _logger;
protected AbstractLocalProcessScanBackend(ILogger logger)
{
_logger = logger;
}
2020-10-26 17:06:29 +02:00
protected abstract Regex MatchRegex { get; }
protected abstract string BackendPath { get; }
2020-10-20 16:20:38 +03:00
protected virtual bool ParseStdErr { get; }
protected virtual bool ThrowOnNonZeroExitCode { get; } = true;
2020-10-20 16:20:38 +03:00
2020-10-26 17:06:29 +02:00
protected abstract string GetBackendArguments(string path);
2020-10-20 16:20:38 +03:00
public override async Task<string[]> ScanAsync(string path, CancellationToken cancellationToken)
{
var process = new Process
{
StartInfo = new ProcessStartInfo(BackendPath, GetBackendArguments(path))
{
RedirectStandardError = true,
RedirectStandardOutput = true,
WorkingDirectory = Path.GetDirectoryName(BackendPath) ?? Directory.GetCurrentDirectory()
}
};
2020-10-20 16:20:38 +03:00
_logger.LogInformation(
$"Starting process {process.StartInfo.FileName} " +
$"with arguments {process.StartInfo.Arguments} " +
$"in working directory {process.StartInfo.WorkingDirectory}");
2020-10-20 16:20:38 +03:00
process.Start();
cancellationToken.Register(() =>
{
if (!process.HasExited)
process.Kill(true);
});
2020-10-20 16:20:38 +03:00
process.WaitForExit();
_logger.LogInformation($"Process has exited with code {process.ExitCode}");
2020-10-20 16:20:38 +03:00
var standardOutput = await process.StandardOutput.ReadToEndAsync();
var standardError = await process.StandardError.ReadToEndAsync();
2020-10-20 16:20:38 +03:00
_logger.LogDebug($"Process standard output: {standardOutput}");
_logger.LogDebug($"Process standard error: {standardError}");
if (ThrowOnNonZeroExitCode && process.ExitCode != 0)
throw new ApplicationException($"Process has terminated with an exit code {process.ExitCode}");
2020-10-20 16:20:38 +03:00
return MatchRegex
.Matches(ParseStdErr ? standardError : standardOutput)
.Where(x => x.Success)
.Select(x => x.Groups["threat"].Value)
.ToArray();
}
}
}