我正在尝试从托管代码,特别是C#中使用Windows反恶意软件服务接口的
AmsiScanBuffer
函数。当尝试调用该方法时,只要提供非零缓冲区长度,程序就会在调用时挂起。如果提供0长度的缓冲区,则该方法立即返回HResult E_INVALIDARG。AMSI公开的其他方法都按预期工作,因此我认为我的dllimport对于此函数来说非常接近,但可能不完全正确。除了这里表示的数组复制方法之外,我还尝试过固定数组,结果行为相同。
C原型
HRESULT WINAPI AmsiScanBuffer(
_In_ HAMSICONTEXT amsiContext,
_In_ PVOID buffer,
_In_ ULONG length,
_In_ LPCWSTR contentName,
_In_opt_ HAMSISESSION session,
_Out_ AMSI_RESULT *result
);
托管代码
[DllImport("Amsi.dll", EntryPoint = "AmsiScanBuffer", CallingConvention = CallingConvention.StdCall)]
public static extern int ScanBuffer(IntPtr amsiContext, IntPtr ptr, ulong length, string contentName, IntPtr session, out int result);
var virus = "X5O!P%@AP[4\\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*";
var bytes = Encoding.UTF8.GetBytes(virus);
int sizet = Marshal.SizeOf(typeof(byte)) * bytes.Length;
var ptr = Marshal.AllocHGlobal(sizet);
try
{
Marshal.Copy(bytes, 0, ptr, bytes.Length);
int hr = Amsi.ScanBuffer(context, ptr, (ulong)sizet, "Unknown Data", session, out result);
}
finally
{
Marshal.FreeHGlobal(ptr);
}
ulong
和uint
的问题犯过同样的错误。我决定在对AmsiInitialize
和AmsiScanBuffer
返回值的HRESULT
进行错误检查时,发现一些本应该正常工作的调用返回了非零结果。我注意到这些结果是 64 位值,高 32 位有垃圾值,低 32 位全是零。果然,我错误地将返回值声明为ulong
。现在已经修复了! - Michael Geary