Мини-фильтр получает постоянное значение из приложения пользовательского режима - PullRequest
0 голосов
/ 15 мая 2018

У меня проблема с отправкой сообщения в пользовательский режим из режима ядра с использованием FltSendMessage, которое ожидает ответа.Передаваемая структура содержит int, для которого установлено значение 0 или 1. Пользовательский режим отвечает, устанавливая этот флаг и вызывая 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, чтобы определить, изменяется ли значение перед отправкой обратно в ядро.

1 Ответ

0 голосов
/ 15 мая 2018

вы используете данные об ошибке в вызове FltSendMessage:

ReplyBuffer - указатель на пользовательские определенные пользователем данные. оно не должно начинаться с FILTER_REPLY_HEADER SenderBuffer - указатель на пользовательские данные, определенные пользователем. оно не должно начинаться с FILTER_MESSAGE_HEADER

прежде всего вам нужно определить структуры , которые совместно используются ядром и режимом пользователя, для сообщения и ответа. например

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 стиль) а в пользовательском режиме нам нужно использовать следующее, например:

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

и

    SCANNER_REPLY_MESSAGE reply;
    reply.MessageId = mesage->MessageId;
    FilterReplyMessage(*, &reply, sizeof(reply));
...