У меня возникла проблема, когда я отправляю сообщение в пользовательский режим из режима ядра, используя FltSendMessage, который ожидает ответа. Передаваемая структура содержит целое число, для которого установлено значение 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, чтобы определить, изменяется ли значение перед отправкой обратно в ядро.
_REPLY_MESSAGE_STRUCT
), зарезервированы во всех областях. См., например. этот старый ответ для более подробной информации. - person Some programmer dude   schedule 15.05.2018FILTER_REPLY_HEADER
предназначен только для пользовательского режимаFilterReplyMessage
иFilterGetMessage
. буфер режима ядра не должен начинаться сFILTER_REPLY_HEADER
- вы не можете использовать буфер в режиме ядра. удалитьFILTER_REPLY_HEADER header;
из определения режима ядра - person RbMm   schedule 15.05.2018_FILTER_REPLY_HEADER
- person RbMm   schedule 15.05.2018FILTER_REPLY_HEADER
иFILTER_MESSAGE_HEADER
используются только в пользовательском режиме. не по ядру. вы должны определить отдельные структуры для сообщения и ответа. и режим ядра используют его напрямую, пользовательский режим - используют другие структуры - наследуют отFILTER_MESSAGE_HEADER
(илиFILTER_REPLY_HEADER
) и пользовательских структур - person RbMm   schedule 15.05.2018