【解決方法】ミニフィルターはユーザーモードアプリケーションから定数値を受け取ります


おい、

応答を期待する FltSendMessage を使用してカーネル モードからユーザー モードにメッセージを送信するときに問題が発生しています。渡される構造体には、0 または 1 に設定された int が含まれています。ユーザー モードは、このフラグを設定することで応答します。そして FilterReplyMessage を呼び出します。 ただし、メッセージがカーネルによって受信されるとき、その値は常に 56 です。ユーザー モードでフラグをどのような数値に設定しても関係ありません。 カーネルは常に値 56 を受け取ります。どこにエラーがあるのか​​混乱しています。 passFlag のデータ型を int から他の型 (USHORT など) に変更しようとしましたが、おそらく違いはないとわかっていましたが、試してみる価値はありました。

カーネル メッセージは正常に応答されているため (ユーザー モードの HRESULT をチェックしてもエラーは返されず、タイムアウトもないため、応答が受信されないとシステムがハングしますが、実際にはハングしません)、エラーは渡されるバッファにあるはずであることがわかります。ユーザーモードとカーネルモードの間。 passFlag がカーネルモードで正しく解釈されない理由が見つからないようです。

私の質問を検討するために時間を割いてくださった皆様に感謝します。
乾杯!

共有構造:

C++
typedef struct _REPLY_MESSAGE_STRUCT {

	// Message header.
	FILTER_REPLY_HEADER header;

	// Flag to be set 
    // by user mode.
	int passFlag;

}REPLY_MESSAGE_STRUCT, *PREPLY_MESSAGE_STRUCT;

カーネルコード:

C++
DbgPrint("Sending Message...\n");

replyBuffer.passFlag = 0;
ULONG replySize = ((ULONG)sizeof(replyBuffer.header)) + ((ULONG)sizeof(replyBuffer));
REPLY_MESSAGE_STRUCT replyBuffer;

// Note: Try-catch statement has been omitted in this question to save time.
// In the actual code there is a try-catch statement surrounding FltSendMessage.
status = FltSendMessage(imageFilterData.filterHandle,
			            &imageFilterData.clientPort,
				        (PVOID)&sendingBuffer.messageBuffer,
						sizeof(sendingBuffer.messageBuffer),
						(PVOID)&replyBuffer,
					    &replySize,
					    0
					    );
// Always returns 56
// When a reply has been received.
DbgPrint("Message received: %i\n", replyBuffer.passFlag);

ユーザーコード:

C++
// User-mode buffer is the same size as kernel-mode buffer.
ULONG replySize = ((ULONG)sizeof(replyBuffer.header)) + ((ULONG)sizeof(replyBuffer));
replyMessage.header.MessageId = messageFromKernel.header.MessageId;
REPLY_MESSAGE_STRUCT replyMessage;

// User-mode setting flag.
replyMessage.passFlag = 1;

// Flag is changed to 1 successfully.
printf("Test: %i\n", replyMessage.passFlag);

// Reply is sent successfully, but flag value on kernel end is always 56
hResult = FilterReplyMessage(port,
		&replyMessage.header,
		replySize);

_com_error err2(hResult);

errorMessage = err2.ErrorMessage();

// No errors.
printf("Result: %s\n", errorMessage);

私が試したこと:

passFlagのデータ型を変更します。

FltSendMessage および FilterReply メッセージの前後のすべてのステップを調べて、カーネルに送り返される前に値が変更されているかどうかを確認します。

解決策 1

投稿されたコードは意味がなく、コンパイルすることさえできません。 REPLY_MESSAGE_STRUCT 両側で宣言される前の変数。

コンポーネントのサイズではなく応答構造全体のサイズを追加しているため、サイズの計算も間違っています。

ULONG replySize = ((ULONG)sizeof(replyBuffer.header)) + ((ULONG)sizeof(replyBuffer));

それは違いない

ULONG replySize = sizeof(replyBuffer.header) + sizeof(replyBuffer.passFlag);

または

ULONG replySize = sizeof(FILTER_REPLY_HEADER) + sizeof(int);

また、構造体の必須フィールドをすべて常に初期化する必要があります。

// This is missing in your code.
// When not clearing Status here it may contain any random value.
replyMessage.header.Status = 0; 
// Set other members
replyMessage.header.MessageId = messageFromKernel.header.MessageId;
replyMessage.passFlag = 1;

これでも問題は解決しないかもしれませんが、少なくとも後で発生する他の問題は回避できます。

私はこれまでそのようなフィルターを使用したことがありません。 だから、これ以上お手伝いすることはできません。 ただし、これらのフィルターと使用される関数については、Microsoft のドキュメントを読む必要があります。 Web でコード例を検索して、他の人がどのように実行しているかを確認することも役立つかもしれません。

コメント

タイトルとURLをコピーしました