4

최종 목표부터 시작하겠습니다. 내 시스템의 모든 문서 (doc, docx, pdf, txt 등)에 고정 된 헤더가 있어야합니다. 예를 들어 "abcde"문자열이 모든 문서 앞에 추가됩니다.미니 필터 드라이버, 메모리 맵 및 메모장

IRP_MJ_WRITE - 헤더 파일의 시작 오프셋 변화가있는 경우 : 수행하기 위해

그래서 나는 다음을 수행하는 미니 필터 드라이버를 썼다.

IRP_MJ_READ - 헤더가있는 경우 파일 시작으로 오프셋을 변경하십시오.

IRP_MJ_QUERY_INFORMATION - 헤더가있는 경우 파일의 크기가 반환됩니다.

IRP_MJ_DIRECTORY_CONTROL - 헤더가있는 경우 파일의 크기가 반환됩니다.

IRP_MJ_CREATE - 헤더가없는 경우 미리 준비된 헤더를 파일에 추가합니다.

MS 워드 2003 문서 (doc, xls, ppt) 및 메모장을 제외하고 잘 작동합니다. 난 그냥 읽고 쓰기 작업의 일부를 잡을 수없는 것 메모장과 파일뿐만 아니라 헤더를 보여줍니다.

나는 http://www.osronline.com/에 많은 것을 읽었으며 모든 Nagar 책을 읽거나 기록 보관소 (검색 할 재앙)를 보도록 요청하는 모든 사람에게 묻습니다. 내 문제와 관련된 모든 것을 읽은 것 같습니다.

메모리 맵핑 된 파일, 빠른 IO, Pagged IO 및 신이 사용하는 메모 패드가 무엇인지 알 것 같습니다. 012H과 MapViewOfFileEx을 mHook과 연결하려고 시도했지만 메모장에 파일을 열었을 때 매핑 된 데이터를 찾으려고했지만 행운이 없었습니다 (그러나 메모리에 매핑 된 다른 모든 바이트를 찾았습니다).

그런 다음 내가 뭘 하려는지는 미니 필터 드라이버에서만 가능하다는 것을 알았고, 내가 설정 한 플래그가 누락되었습니다.

누군가 메모장의 작업을 파악하기 위해 무엇을 해야할지 말할 수만 있다면 정말 만족할 것입니다.

여기에 읽기에 대한 몇 가지 코드 예제 : 파일 이름 및 요청 프로세스에 대한

CONST FLT_OPERATION_REGISTRATION Callbacks[] = { 
    { IRP_MJ_WRITE, 
    0, 
    PreWrite, 
    PostWrite }, 

    { IRP_MJ_READ, 
    0, 
    PreRead, 
    PostRead }, 

    { IRP_MJ_QUERY_INFORMATION, 
    0, 
    NULL, 
    PostQueryInfo }, 

    { IRP_MJ_DIRECTORY_CONTROL, 
    0, 
    NULL, 
    PostQueryDir }, 

    { IRP_MJ_CREATE, 
    0, 
    NULL, 
    PostCreate }, 

    { IRP_MJ_OPERATION_END } 
}; 

FLT_PREOP_CALLBACK_STATUS 
    PreRead (
    _Inout_ PFLT_CALLBACK_DATA Data, 
    _In_ PCFLT_RELATED_OBJECTS FltObjects, 
    _Flt_CompletionContext_Outptr_ PVOID *CompletionContext 
    ) 
{ 
    NTSTATUS status = 0; 
    ULONG bytesRead; 
    PVOID readBuffer; 
    LARGE_INTEGER zero; 
    zero.QuadPart = 0; 

    UNREFERENCED_PARAMETER(FltObjects); 
    UNREFERENCED_PARAMETER(Data); 
    UNREFERENCED_PARAMETER(CompletionContext); 

    if(Data->Iopb->Parameters.Read.MdlAddress != NULL){ 
     return FLT_PREOP_SUCCESS_NO_CALLBACK; 
    } 

    if(!IsFileNeedProccessing(&FltObjects->FileObject->FileName, Data)){ 
     return FLT_PREOP_SUCCESS_NO_CALLBACK; 
    } 


    readBuffer = ExAllocatePool(
     NonPagedPool, 
     prefixSize); 
    if(readBuffer == NULL) 
    { 
     return FLT_PREOP_SUCCESS_NO_CALLBACK; 
    } 

    status = FltReadFile(
     FltObjects->Instance, 
     FltObjects->FileObject, 
     &zero, 
     (ULONG)prefixSize, 
     readBuffer, 
     FLTFL_IO_OPERATION_DO_NOT_UPDATE_BYTE_OFFSET, 
     &bytesRead, 
     NULL, 
     NULL); 

    if(NT_SUCCESS(status)) 
    { 
     if(IsBuffAPrefixOfBuffB(prefix, readBuffer, prefixSize, (SIZE_T)bytesRead)) 
     { 
      Data->Iopb->Parameters.Read.ByteOffset.QuadPart += prefixSize; 
      FltSetCallbackDataDirty(Data); 
     } 
    } 
    ExFreePool(readBuffer); 

    return FLT_PREOP_SUCCESS_WITH_CALLBACK; 
} 

FLT_POSTOP_CALLBACK_STATUS 
    PostRead (
    _Inout_ PFLT_CALLBACK_DATA Data, 
    _In_ PCFLT_RELATED_OBJECTS FltObjects, 
    _In_opt_ PVOID CompletionContext, 
    _In_ FLT_POST_OPERATION_FLAGS Flags 
    ) 
{ 
    NTSTATUS status; 
    ULONG bytesRead; 
    PVOID readBuffer; 
    FILE_STANDARD_INFORMATION info; 
    LONGLONG* currOffset = &Data->Iopb->TargetFileObject->CurrentByteOffset.QuadPart; 
    LARGE_INTEGER zero; 
    zero.QuadPart = 0; 

    UNREFERENCED_PARAMETER(CompletionContext); 
    UNREFERENCED_PARAMETER(Flags); 
    UNREFERENCED_PARAMETER(Data); 
    UNREFERENCED_PARAMETER(FltObjects); 

    if(Data->Iopb->Parameters.Read.MdlAddress != NULL) 
    { 
     return FLT_POSTOP_FINISHED_PROCESSING; 
    } 

    if(!IsFileNeedProccessing(&FltObjects->FileObject->FileName, Data)) 
    { 
     return FLT_POSTOP_FINISHED_PROCESSING; 
    } 

    status = FltQueryInformationFile(
     FltObjects->Instance, 
     FltObjects->FileObject, 
     &info, 
     sizeof(info), 
     FileStandardInformation, 
     NULL); 

    if(NT_SUCCESS(status) 
     && info.EndOfFile.QuadPart != *currOffset 
     && *currOffset >= (LONGLONG)prefixSize) 
    { 
     readBuffer = ExAllocatePool(NonPagedPool, 
      prefixSize); 
     if(readBuffer == NULL) 
     { 
      return FLT_POSTOP_FINISHED_PROCESSING; 
     } 

     status = FltReadFile(
      FltObjects->Instance, 
      FltObjects->FileObject, 
      &zero, 
      (ULONG)prefixSize, 
      readBuffer, 
      FLTFL_IO_OPERATION_DO_NOT_UPDATE_BYTE_OFFSET, 
      &bytesRead, 
      NULL, 
      NULL); 

     if(NT_SUCCESS(status)) 
     { 
      if(IsBuffAPrefixOfBuffB(prefix, readBuffer, prefixSize, (SIZE_T)bytesRead)) 
      { 
       *currOffset -= prefixSize; 
       FltSetCallbackDataDirty(Data); 
      } 
     } 
     ExFreePool(readBuffer); 
    } 

    return FLT_POSTOP_FINISHED_PROCESSING; 
} 

IsFileNeedProccessing 확인합니다. (일부 응용 프로그램은 헤더를 볼 수 있습니다)

누군가가 메모장의 작업을 파악하기 위해 무엇을 해야할지 말할 수만 있다면 정말 만족할 것입니다.

감사합니다.

+1

왜 'Parameters.Read.MdlAddress! = NULL' 인 곳에서 전화를 가로 채지 않습니까? 그것은 틀린 것처럼 보인다. –

+0

당신이 옳습니다! 나는 그것을 조사 할 것이다. Thnaks. – assafmo

답변

2

마찬가지로 @Harry jonhston은 MdlAddress == NULL을 사용하여 IRP를 가로채는 것만의 검사가 올바르지 않다고 지적했습니다.

if(Data->Iopb->Parameters.Read.MdlAddress != NULL) 
{ 
    return FLT_POSTOP_FINISHED_PROCESSING; 
} 

아마도 메모장과 MS Office 응용 프로그램이 실패 할 가능성이 높습니다.

몇 가지 포인트 이상 :

  • 당신은 적절하게 페이징 IO를 처리해야합니다.
  • FltReadFile은 IRQL PASSIVE_LEVEL이라고해야합니다.
  • 더 중요한 것은 파일 크기를 변경하고 파일 시스템과 사용자에게 투명하게 유지한다는 것입니다. 그렇게하지 않는 것이 좋습니다.
  • 파일에 대한 특수 데이터를 추가하려면 alternate data stream을 사용하는 것이 좋습니다.
+0

입력 해 주셔서 감사합니다. IsFileNeedProccessing는 또한'IRQL == PASSIVE_LEVEL'을 검사한다. 페이징 IO를 어떻게 적절하게 처리 할 것을 제안합니까? – assafmo

+1

@gfgqtmakia 그 동안 파일 이름을 얻지 못해서 페이징 IO를 건너 뛰어야한다고 생각합니다. 나는 당신이 정확히 무엇을해야하는지에 대해 몇 가지 조사를 해보라고 제안한다. – Rohan

+0

'FileObject'와'IoQueryFileDosDeviceName'에서 파일 이름을 얻을 수 있습니다. 페이징 IO는 MDL입니까? 이걸 좀 더 설명해 주시겠습니까? – assafmo