我们正在编写一个代码,使用Windows Defender API按需扫描来自C#的文件。
[DllImport(@"C:\Program Files\Windows Defender\MpClient.dll")] public static extern int WDStatus(out bool pfEnabled); [DllImport(@"C:\Program Files\Windows Defender\MpClient.dll")] public static extern int MpManagerOpen(uint dwReserved, out IntPtr phMpHandle); [DllImport(@"C:\Program Files\Windows Defender\MpClient.dll")] public static extern int MpScanStart(IntPtr hMpHandle, uint ScanType, uint dwScanOptions, IntPtr pScanResources, IntPtr pCallbackInfo, out IntPtr phScanHandle); [DllImport(@"C:\Program Files\Windows Defender\MpClient.dll")] public static extern int MpHandleClose(IntPtr hMpHandle); private void DoDefenderScan_Click(object sender, EventArgs e) { try { bool pfEnabled; int result = WDStatus(out pfEnabled); //Returns the defender status - It's working properly. ErrorHandler.ThrowOnFailure(result, VSConstants.S_OK); IntPtr phMpHandle; uint dwReserved = 0; IntPtr phScanHandle; MpManagerOpen(dwReserved, out phMpHandle); //Opens Defender and returns the handle in phMpHandle. tagMPRESOURCE_INFO mpResourceInfo = new tagMPRESOURCE_INFO(); mpResourceInfo.Path = "eicar.com"; mpResourceInfo.Scheme = "file"; mpResourceInfo.Class = IntPtr.Zero; tagMPRESOURCE_INFO[] pResourceList = new tagMPRESOURCE_INFO[1]; pResourceList.SetValue(mpResourceInfo, 0); tagMPSCAN_RESOURCES scanResource = new tagMPSCAN_RESOURCES(); scanResource.dwResourceCount = 1; scanResource.pResourceList = pResourceList; IntPtr resourcePointer = StructToPtr(scanResource); result = MpScanStart(phMpHandle, 3, 0, resourcePointer, IntPtr.Zero, out phScanHandle); **//Getting Access violation exception here**. MpHandleClose(phMpHandle); MpHandleClose(phScanHandle); Marshal.FreeHGlobal(resourcePointer); } catch (Exception) { } }
这里定义了结构。
[StructLayout(LayoutKind.Sequential, Pack = 1)] public struct tagMPSCAN_RESOURCES { public uint dwResourceCount; [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 1)] public tagMPRESOURCE_INFO[] pResourceList; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct tagMPRESOURCE_INFO { [MarshalAs(UnmanagedType.LPWStr)] public String Scheme; [MarshalAs(UnmanagedType.LPWStr)] public String Path; public IntPtr Class; } public class MPRESOURCE_CLASS { public uint Value; } private static IntPtr StructToPtr(object obj) { var ptr = Marshal.AllocHGlobal(Marshal.SizeOf(obj)); Marshal.StructureToPtr(obj, ptr, false); return ptr; }
代码是基于可用的文档编写的
https://msdn.microsoft.com/en-us/library/vs/alm/dn920144(v=vs.85).aspx
我们正在得到这个例外
尝试读取或写入受保护的内存。 这通常表示其他内存已损坏。
在
result = MpScanStart(phMpHandle, 3, 0, resourcePointer, IntPtr.Zero, out phScanHandle); **//Getting Access violation exception here**.
可能是什么问题呢? 结构的格式是正确的吗?
PS – 没有关于MPRESOURCE_CLASS的信息在msdn中可用。
我不确定,这行代码是否正确。
mpResourceInfo.Class = IntPtr.Zero;
更新:
快速扫描与此代码正常工作:
result = MpScanStart(phMpHandle, 1, 0, IntPtr.Zero, IntPtr.Zero, out phScanHandle);
Defenderlogin事件查看器[Applications and Services Logs-Microsoft-Windows-Windows Defender / Operational] as
Windows Defender扫描已经开始。
扫描编号:{CDC2AC0D-7648-4313-851C-4D8B7B5EB5CD}
扫描types:反间谍软件
扫描参数:快速扫描
我一直在寻找问题,我已经读到这是可能的原因之一:
“经常看到调试和发布版本之间的差异,因为调试版本包含额外的元数据来协助调试。”
这里: https : //social.msdn.microsoft.com/Forums/vstudio/en-US/4f48c152-68cd-45ec-a11e-baa7de7f79c3/attempted-to-read-or-write-protected-memory?forum=csharpgeneral
你也应该检查这个答案 “是否有可能在.NET中捕获访问冲突异常? 以及MSDN杂志“ 处理破坏的状态异常 ”一文中解释的更多细节
…
所以,根据这个答案和文章,我会尝试:
第一次检查所有非托管代码的双重签名和COM互操作,以验证它们是否正确。
第二步设置Visual Studio调试器绕过这个异常:工具菜单 – >选项 – >调试 – >常规 – >取消选中此选项“取消模块加载JIT优化”
第三次尝试 – 捕捉异常
(注意:如果您使用的是.Net 4,那么在App.config中,在标记修改运行时内包含legacyCorruptedStateExceptionsPolicy enabled =“true”,如:
<runtime> <legacyCorruptedStateExceptionsPolicy enabled="true"/> </runtime>
)
另外, 在这里 ,我发现一些.net框架版本(最新的评论指向4.6.1的答案的评论之一)有一个与这个异常相关的错误,并且解决方案在过去一直在升级框架。 另外,在我读到的答案之一中:
嗨有两个可能的原因。
1.我们有未托管的代码,我们从托管代码调用它。 这是防止运行此代码。 尝试运行这些命令并重新启动您的电脑
cmd:netsh winsock重置
打开cmd.exe并运行命令“netsh winsock reset catalog”2.防病毒正在考虑将不受管理的代码视为有害和限制运行此代码禁用防病毒,然后检查
我想知道这些方法是否能帮助您解决您的问题。
我真的希望这有助于。
KR,
胡安
我在这里找不到问题。 所以我最终从Windows 10开始提供了反恶意软件扫描接口 (AMSI)。
我在这里写了一个示例C#代码。
我发现的一件事是AMSI需要打开Windows Defender /任何杀毒软件来验证传递给API的文件。 但是,通过MpClient.dll
触发扫描将触发防御者扫描,即使防卫者被关闭。
public enum AMSI_RESULT { AMSI_RESULT_CLEAN = 0, AMSI_RESULT_NOT_DETECTED = 1, AMSI_RESULT_DETECTED = 32768 } [DllImport("Amsi.dll", EntryPoint = "AmsiInitialize", CallingConvention = CallingConvention.StdCall)] public static extern int AmsiInitialize([MarshalAs(UnmanagedType.LPWStr)]string appName, out IntPtr amsiContext); [DllImport("Amsi.dll", EntryPoint = "AmsiUninitialize", CallingConvention = CallingConvention.StdCall)] public static extern void AmsiUninitialize(IntPtr amsiContext); [DllImport("Amsi.dll", EntryPoint = "AmsiOpenSession", CallingConvention = CallingConvention.StdCall)] public static extern int AmsiOpenSession(IntPtr amsiContext, out IntPtr session); [DllImport("Amsi.dll", EntryPoint = "AmsiCloseSession", CallingConvention = CallingConvention.StdCall)] public static extern void AmsiCloseSession(IntPtr amsiContext, IntPtr session); [DllImport("Amsi.dll", EntryPoint = "AmsiScanString", CallingConvention = CallingConvention.StdCall)] public static extern int AmsiScanString(IntPtr amsiContext, [InAttribute()] [MarshalAsAttribute(UnmanagedType.LPWStr)]string @string, [InAttribute()] [MarshalAsAttribute(UnmanagedType.LPWStr)]string contentName, IntPtr session, out AMSI_RESULT result); [DllImport("Amsi.dll", EntryPoint = "AmsiScanBuffer", CallingConvention = CallingConvention.StdCall)] public static extern int AmsiScanBuffer(IntPtr amsiContext, byte[] buffer, ulong length, string contentName, IntPtr session, out AMSI_RESULT result); //This method apparently exists on MSDN but not in AMSI.dll (version 4.9.10586.0) [DllImport("Amsi.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)] public static extern bool AmsiResultIsMalware(AMSI_RESULT result); private void CallAntimalwareScanInterface() { IntPtr amsiContext; IntPtr session; AMSI_RESULT result = 0; int returnValue; returnValue = AmsiInitialize("VirusScanAPI", out amsiContext); //appName is the name of the application consuming the Amsi.dll. Here my project name is VirusScanAPI. returnValue = AmsiOpenSession(amsiContext, out session); returnValue = AmsiScanString(amsiContext, @"X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*", "EICAR", session, out result); //I've used EICAR test string. AmsiCloseSession(amsiContext, session); AmsiUninitialize(amsiContext); }
您可以使用反恶意软件扫描界面来检查文件是否存在恶意软件。
反恶意软件扫描接口(AMSI)是一种通用接口标准,允许应用程序和服务与机器上的任何反恶意软件产品集成。 它为用户及其数据,应用程序和工作负载提供增强的恶意软件保护。
它从Windows 10开始可用。