基于C# .NET Core 3.1实现未签名EXE/DLL更新下载前的杀毒软件拦截预检测方案问询
我来给你几个实际可行的思路,都是围绕你“不完整下载就能预检测”的核心需求来设计的,结合你的.NET Core 3.1环境也能快速落地:
1. 针对主流杀软,基于文件哈希做威胁库查询
虽然客户端杀软种类多,但大部分用户用的还是Windows Defender(系统自带)或者国内几款主流杀软。你可以先获取待更新文件的SHA256哈希,然后调用对应杀软的命令行或API查询这个哈希是否被标记为恶意,完全不需要下载文件。
以Windows Defender为例,你可以在C#里通过调用PowerShell命令来查询:
using System.Diagnostics; public static bool IsHashMarkedAsThreat(string targetFileSha256) { var processStartInfo = new ProcessStartInfo { FileName = "powershell.exe", Arguments = $"Get-MpThreat -Hash {targetFileSha256}", RedirectStandardOutput = true, UseShellExecute = false, CreateNoWindow = true, WorkingDirectory = Environment.SystemDirectory }; using var psProcess = Process.Start(processStartInfo); if (psProcess == null) return false; var output = psProcess.StandardOutput.ReadToEnd(); psProcess.WaitForExit(); // 解析输出:如果返回了威胁信息,说明哈希被标记 return !string.IsNullOrEmpty(output) && output.Contains("ThreatId"); }
- 优点:零下载,只需要文件哈希就能检测;针对Windows Defender的准确性很高,覆盖绝大多数Windows用户。
- 缺点:需要针对其他杀软单独适配(比如360有自己的命令行扫描工具),但可以优先做系统自带的Defender,再逐步扩展。
2. 轻量模拟下载:只下载文件头部做扫描
如果哈希查询的结果不够准确(比如杀软是基于文件内容+下载来源联合检测),你可以尝试只下载文件的前100-500KB(远小于完整文件),保存到临时目录,然后触发杀软的实时扫描或者主动扫描,看是否会被拦截。
这个方式很接近真实下载场景,而且不会触发复杂的完整下载流程:
using System.IO; using System.Net.Http; public static async Task<bool> IsSmallSampleBlocked(string updateFileUrl) { var tempPath = Path.GetTempFileName(); try { using var httpClient = new HttpClient(); // 只请求前500KB的内容 using var request = new HttpRequestMessage(HttpMethod.Get, updateFileUrl); request.Headers.Range = new System.Net.Http.Headers.RangeHeaderValue(0, 512000); using var response = await httpClient.SendAsync(request); response.EnsureSuccessStatusCode(); using var fileStream = new FileStream(tempPath, FileMode.Create); await response.Content.CopyToAsync(fileStream); // 调用Windows Defender扫描这个临时文件 var scanResult = await ScanFileWithDefender(tempPath); return scanResult.IsThreatDetected; } finally { if (File.Exists(tempPath)) File.Delete(tempPath); } } // 封装调用Defender扫描单个文件的方法 private static async Task<(bool IsThreatDetected, string ThreatInfo)> ScanFileWithDefender(string filePath) { var processStartInfo = new ProcessStartInfo { FileName = "powershell.exe", Arguments = $"Start-MpScan -ScanPath {filePath} -ScanType QuickScan", RedirectStandardOutput = true, UseShellExecute = false, CreateNoWindow = true }; using var psProcess = Process.Start(processStartInfo); if (psProcess == null) return (false, string.Empty); var output = await psProcess.StandardOutput.ReadToEndAsync(); await psProcess.WaitForExitAsync(); // 解析扫描结果,判断是否有威胁 var isThreat = output.Contains("detected") || output.Contains("threat"); return (isThreat, output); }
- 优点:模拟真实下载场景,检测结果更贴近实际情况;实现简单,不需要复杂的API适配。
- 缺点:会下载少量文件内容,但远小于完整更新包,符合你“不执行完整下载流程”的要求。
3. 调用Windows Defender原生扫描API(最高准确性)
你之前尝试过AMSI,但AMSI主要针对脚本和内存恶意代码,和下载时的文件系统扫描不是同一套规则。你可以直接调用Windows Defender的mpclient.dll里的原生扫描函数,这套函数和杀软实时防护用的是同一套规则,准确性最高。
通过P/Invoke在C#里调用MpScanFile函数:
using System; using System.Runtime.InteropServices; using System.IO; public static class DefenderNativeApi { [DllImport("mpclient.dll", CharSet = CharSet.Unicode, SetLastError = true)] private static extern uint MpManagerOpen(out IntPtr phMpHandle); [DllImport("mpclient.dll", CharSet = CharSet.Unicode, SetLastError = true)] private static extern uint MpScanFile( IntPtr hMpHandle, string pszFilePath, uint dwScanOptions, IntPtr pScanResources, out IntPtr ppScanResult); [DllImport("mpclient.dll", SetLastError = true)] private static extern uint MpScanResultCleanup(IntPtr pScanResult); [DllImport("mpclient.dll", SetLastError = true)] private static extern uint MpManagerClose(IntPtr hMpHandle); public static bool ScanFileForThreats(string filePath) { if (!File.Exists(filePath)) return false; uint result = MpManagerOpen(out var mpHandle); if (result != 0) return false; try { // 0x00000002 代表快速扫描模式 result = MpScanFile(mpHandle, filePath, 0x00000002, IntPtr.Zero, out var scanResult); if (result != 0) return false; try { // 简化判断:如果扫描结果非空且返回值正常,说明可能存在威胁 return scanResult != IntPtr.Zero; } finally { MpScanResultCleanup(scanResult); } } finally { MpManagerClose(mpHandle); } } }
- 优点:直接调用杀软核心扫描逻辑,检测结果和实时防护完全一致;不需要依赖PowerShell,性能更好。
- 缺点:只适用于Windows Defender;需要处理P/Invoke的细节,如需详细威胁信息还需解析对应结构体。
4. 服务器端预先查询文件信誉
如果客户端适配太麻烦,你可以把检测逻辑放到服务器端:预先用VirusTotal、微软威胁情报API等服务查询待更新文件的哈希,把“是否会被拦截”的标记和更新包一起返回给客户端。客户端只需要读取这个标记就能提前判断。
这种方式客户端几乎不需要做任何适配,所有复杂的查询逻辑都在服务器端完成,而且可以覆盖全球主流杀软的检测结果。
内容的提问来源于stack exchange,提问作者filippocurati

