본문 바로가기

Windows/Kernel

FilterReplyMessage 에러 코드 E_INVALIDARG

커널드라이버-앱간 통신을 위해 드라이버에선 FltSendMessage를 호출하고 이에 대한 처리 및 응답을 위해 앱에선 FilterReplyMessage를 호출합니다. 문제는 FilterReplyMessage 호출 후 E_INVALIDARG 라는 에러 코드가 발생되는 것.

 

E_INVALIDARG 는 winerror.h에 다음과 같이 정의되어 있습니다.

#define E_INVALIDARG                     _HRESULT_TYPEDEF_(0x80070057L)

 

여러가지 예제(spy 등등)를 보고 커널 드라이버에서 FltSendMessage를 잘 했음에도 불구하고 앱 단의 FilterReplyMessage 에서 자꾸 E_INVALIDARG 에러가 나온다. 물론 드라이버로 응답 메세지도 가지 않다보니 드라이버의 FltSendMessage에선 STATUS_TIMEOUT 에러가 발생된다. 

 

여러가지 테스트 후 내린 결론은 FilterReplyMessage의 응답 크기로 인한 문제라고 판단 됐습니다.

MSDN ReplySendMessage 설명을 보면 다음과 같은 구절이 있습니다. 

Important  

Due to (system-specific) structure padding requirements, accuracy is required when you set the size of buffers that are associated with FltSendMessage and FilterReplyMessage. As an example, assume data must be sent (via FilterReplyMessage) to a minifilter. The user-mode component might declare the following structure to do so:

C++Copy

 

typedef struct _REPLY_STRUCT { FILTER_REPLY_HEADER Header; MY_STRUCTURE Data; // The structure to be sent to the minifilter. } REPLY_STRUCT, *PREPLY_STRUCT;

Given this structure, it might seem obvious that the caller of FilterReplyMessage would set the dwReplyBufferSize parameter to sizeof(REPLY_STRUCT) and the ReplyLength parameter of FltSendMessage to the same value. However, because of structure padding idiosyncrasies, sizeof(REPLY_STRUCT) might be larger than sizeof(FILTER_REPLY_HEADER) + sizeof(MY_STRUCT). If this is the case, FltSendMessage returns STATUS_BUFFER_OVERFLOW.

Therefore, we recommend that you call FilterReplyMessage and FltSendMessage (leveraging the above example) by setting dwReplyBufferSize and ReplyLength both to sizeof(FILTER_REPLY_HEADER) + sizeof(MY_STRUCT) instead of sizeof(REPLY_STRUCT). This ensures that any extra padding at the end of the REPLY_STRUCT structure is ignored.

 

요는 structure alignment (CPU 처리 속도를 빠르게 하기 위한 크기 정렬) 가 될 수 있어 사이즈를 신경 쓸 것. 단순히 sizeof(구조체) 요렇게 하면 예상하지 못한 크기가 지정될 수 있다. 

 

REPLY_STRUCT

{

  FILTER_REPLY_HEADER header;

  MY_STRUCT

}

 

sizeof(REPLY_STRUCT) 의 값이 sizeof(FILTER_REPLY_HEADER) + sizeof(MY_STRUCT) 와 다를 수 있다는 거죠.

분명 크기를 맞춰 잘 보냈다고 생각하는데도 안되고 있었고 최종적으로 성공한 방법은 단순 했습니다. 

 

#pragma pack(1)

REPLY_STRUCT { }

#pragma pack()

 

이렇게 structure alignment를 막아버렸습니다. 

 

FilterReplyMessage function (fltuser.h) - Win32 apps

The FilterReplyMessage function replies to a message from a kernel-mode minifilter.

docs.microsoft.com

 

'Windows > Kernel' 카테고리의 다른 글

Kernel Callback Functions  (0) 2020.08.01
anti dll injection  (0) 2020.08.01
드라이버 로드 후 파일 삭제하기.  (0) 2020.07.29
kernel 모드에서 PE 파일의 코드사인 여부 확인  (0) 2020.07.28
HAL_INITIALIZATION_FAILED  (0) 2020.06.24