【发布时间】:2017-04-14 19:18:58
【问题描述】:
我们正在编写代码以使用 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**.
可能是什么问题? struct的格式是否正确?
P.S - msdn 中没有关于 MPRESOURCE_CLASS 的信息。
我不确定,这行代码是否正确。
mpResourceInfo.Class = IntPtr.Zero;
更新:
快速扫描可以正常使用此代码:
result = MpScanStart(phMpHandle, 1, 0, IntPtr.Zero, IntPtr.Zero, out phScanHandle);
事件查看器中的 Defender 日志 [应用程序和服务日志-Microsoft-Windows-Windows Defender/Operational] 为
Windows Defender 扫描已开始。
扫描ID:{CDC2AC0D-7648-4313-851C-4D8B7B5EB5CD}
扫描类型:反间谍软件
扫描参数:快速扫描
【问题讨论】:
-
神圣的硬编码路径,蝙蝠侠!请不要这样做。如果我的引导驱动器不是驱动器 C 怎么办?如果 Program Files 中没有安装 Windows Defender 怎么办?
-
@CodyGray - 这是一个 POC。但感谢您指出。
-
我看到的第一个错误是 MPSCAN_RESOURCES.pResourceList 成员声明。它是指向数组的指针,而不是 UnmanagedType.ByValArray。您必须将其声明为 IntPtr 并自己编组数组。使用 Pack=1 也是非常错误的。可能有更多的错误,这不是一个简单的api。使用 C++/CLI 来做这件事,你会领先一步,至少你可以依赖 mpclient.h 头文件。
-
@HansPassant 谢谢!我会调查的。
-
最后我放弃了。我们计划使用反恶意软件扫描接口 (AMSI)。但是 AMSI 支持仅在 Windows 10 中可用。我编写了一个示例代码,以防有人需要。 midhunlalg.blogspot.in/2016/12/…
标签: c# windows dllimport antivirus windows-defender