現在、カーネル フィルターを取得して C# アプリケーションと通信しようとしています。カーネルアプリは、私の構造で、ファイルへのパスを含む UNICODE_STRING を送信します。他のすべての変数は正常に見え、バッファの場所はユーザー アプリとカーネル アプリで同じように見えますが、ToString メソッドを呼び出すと、
usermodeFilter.MinifilterWrapper+NativeMethods+COMMAND_MESSAGE
私のC#コードは次のようになります
private NativeMethods.USERCOMMAND_MESSAGE data = new NativeMethods.USERCOMMAND_MESSAGE();
[SecurityPermission(SecurityAction.Demand)]
public void FilterGetMessage()
{
UInt32 result = NativeMethods.FilterGetMessage(_handle, ref data, (UInt32)Marshal.SizeOf(typeof(NativeMethods.USERCOMMAND_MESSAGE)), IntPtr.Zero);
if (result == NativeMethods.S_OK)
{
Console.WriteLine("message recived");
Console.WriteLine(this.getProcessNameFromId((int)this.data.cmdMessage.procesID));
Console.WriteLine(this.data.cmdMessage.ToString());
}
else
{
throw new InvalidOperationException("Unknown error, number " +result);
}
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct COMMAND_MESSAGE {
public UInt32 procesID;
public UNICODE_STRING fileName;
}
[StructLayout(LayoutKind.Sequential)]
public struct UNICODE_STRING : IDisposable
{
public ushort Length;
public ushort MaximumLength;
private IntPtr buffer;
public UNICODE_STRING(string s)
{
Length = (ushort)(s.Length * 2);
MaximumLength = (ushort)(Length + 2);
buffer = Marshal.StringToHGlobalUni(s);
}
public void Dispose()
{
Marshal.FreeHGlobal(buffer);
buffer = IntPtr.Zero;
}
public override string ToString()
{
return Marshal.PtrToStringUni(buffer);
}
}
コードの C++ 部分の外観
WCHAR parametersKeyBuffer[255];
gCmdMessageSend.name.Buffer = parametersKeyBuffer;
gCmdMessageSend.name.MaximumLength = sizeof(parametersKeyBuffer);
gCmdMessageSend.name.Length = 0;
RtlCopyUnicodeString(&gCmdMessageSend.name, &fileInfo->Name);
if (FsClientPort)
{
ulReplayLength = sizeof(gCmdMessageSend);
status = FltSendMessage(gFilterHandle, &FsClientPort, &gCmdMessageSend, sizeof(gCmdMessageSend), NULL, &ulReplayLength, &timeout);
}
ところで、メモリの場所への無効なアクセスも取得しています。Marshal.FreeHGlobal(buffer) のときのエラー。だから私は何か間違ったことをしていると推測しています