C++ 迷你过滤器从用户模式应用程序接收常量值

C++ 迷你过滤器从用户模式应用程序接收常量值,c++,c,windows,driver,minifilter,C++,C,Windows,Driver,Minifilter,我遇到了一个问题,我使用需要回复的FltSendMessage从内核模式向用户模式发送消息。正在传递的结构包含设置为0或1的int。用户模式通过设置此标志并调用FilterReplyMessage进行响应。但是,当内核接收到消息时,其值始终为56。无论在用户模式下我将标志设置为什么数字,内核总是接收值56。我不知道我的错误在哪里 我曾尝试将passFlag的数据类型从int改为其他类型(USHORT等),我知道这可能不会有什么不同,但值得一试 由于内核消息被成功回复(检查用户模式HRESULT不

我遇到了一个问题,我使用需要回复的FltSendMessage从内核模式向用户模式发送消息。正在传递的结构包含设置为0或1的int。用户模式通过设置此标志并调用FilterReplyMessage进行响应。但是,当内核接收到消息时,其值始终为56。无论在用户模式下我将标志设置为什么数字,内核总是接收值56。我不知道我的错误在哪里

我曾尝试将passFlag的数据类型从int改为其他类型(USHORT等),我知道这可能不会有什么不同,但值得一试

由于内核消息被成功回复(检查用户模式HRESULT不会返回任何错误,并且没有超时,因此如果没有收到回复,系统将挂起,而事实并非如此),因此我知道错误一定是由于缓冲区在用户模式和内核模式之间传递。我似乎找不到在内核模式下不能正确解释passFlag的原因

有人能帮忙吗

共享结构:

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; 
内核代码:

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);
用户代码:

// 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消息之前和之后的每个步骤,以确定在将值发送回内核之前是否正在更改该值


您正在通话中使用错误数据:


ReplyBuffer是指向用户定义数据的指针。它不能从
FILTER\u REPLY\u头开始
SenderBuffer是指向用户定义数据的指针。它不能从
FILTER\u MESSAGE\u头开始

首先,您需要在内核和用户模式之间共享消息和回复。比如说

struct SCANNER_NOTIFICATION {
    // any custom data
    int someData;

};

struct SCANNER_REPLY {
    // any custom data
    int passFlag;
};
在内核模式下,您可以按原样直接使用它:

SCANNER_NOTIFICATION send;
SCANNER_REPLY reply;
ULONG ReplyLength = sizeof(reply);

FltSendMessage(*, *, &send, sizeof(send), &reply, &ReplyLength, *);
在用户模式下,您可以使用2个附加结构:

struct SCANNER_MESSAGE : public FILTER_MESSAGE_HEADER, public SCANNER_NOTIFICATION {};

struct SCANNER_REPLY_MESSAGE : public FILTER_REPLY_HEADER, public SCANNER_REPLY {};

(我在这里使用C++样式,当使用C样式时) 在用户模式下,我们需要使用next,例如:

SCANNER_MESSAGE* mesage;
FilterGetMessage(*, mesage, sizeof(SCANNER_MESSAGE), *);


与您的问题无关,但以下划线开头,后跟大写字母的符号(如
\u REPLY\u MESSAGE\u STRUCT
)保留在所有范围内。有关更多详细信息,请参见,例如。此外,请不要使用多语言标记,除非它实际上与您使用多种语言或询问多种语言之间的差异相关。如果你在C中编程,那么只使用C标签。谢谢你的回复,但是你知道用户模式是C++的,内核模式在C.,因此需要C++和C标签。由于我不知道错误可能在哪里,无论是在用户模式应用程序还是内核模式筛选器中,但是,感谢您的建议。
filter\u REPLY\u HEADER
仅适用于用户模式
FilterReplyMessage
FilterGetMessage
。内核模式缓冲区不能从
过滤器\u回复\u头开始
-您在内核模式下使用的缓冲区无效。删除
FILTER\u REPLY\u标题从内核模式definition@Someprogrammerdude-这可能令人惊讶,但windows标头本身永久使用此符号。例如,非常感谢你,你是一个传奇!我完全误解了文件。再次感谢。
    SCANNER_REPLY_MESSAGE reply;
    reply.MessageId = mesage->MessageId;
    FilterReplyMessage(*, &reply, sizeof(reply));