Using IAmsiStream from .Net leads to AccessViolationException
See the question and my original answer on StackOverflowYou need to tell .NET that the arrays are Out parameters in IAnsiStream, like this:
[Guid("3e47f2e5-81d4-4d3b-897f-545096770373"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IAmsiStream
{
[PreserveSig]
int GetAttribute(AMSI_ATTRIBUTE attribute, int dataSize, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] data, out int retData);
[PreserveSig]
int Read(long position, int size, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] buffer, out int readSize);
}
Also note I use PreserveSig to explicitely define methods return value as HRESULT.
And here is a sample implementation for the GetAttribute method:
public int GetAttribute(AMSI_ATTRIBUTE attribute, int dataSize, byte[] data, out int retData)
{
const int E_NOT_SUFFICIENT_BUFFER = unchecked((int)0x8007007A);
switch (attribute)
{
case AMSI_ATTRIBUTE.AMSI_ATTRIBUTE_APP_NAME:
const string appName = "My App Name";
var bytes = Encoding.Unicode.GetBytes(appName + "\0"); // force terminating zero
retData = bytes.Length;
if (dataSize < bytes.Length)
return E_NOT_SUFFICIENT_BUFFER;
Array.Copy(bytes, data, bytes.Length);
return 0;
// TODO: implement what's needed
default:
retData = 0;
const int E_NOTIMPL = unchecked((int)0x80004001);
return E_NOTIMPL;
}
}