我將從最終目標開始。 我希望我的系統上的每個文檔(doc,docx,pdf,txt等)都有一個固定的(並且對用戶來說是transperent)頭。 例如,字符串「abcde」將被添加到每個文檔中。Minifilter驅動程序,內存映射和記事本
爲了做到這一點,我寫一個微過濾器驅動程序,執行以下操作:
IRP_MJ_WRITE
- 如果頭存在變化偏移到文件的開始。
IRP_MJ_READ
- 如果標題存在,則將偏移量更改爲文件起始位置。
IRP_MJ_QUERY_INFORMATION
- 如果標題存在,則更改文件的返回大小。
IRP_MJ_DIRECTORY_CONTROL
- 如果標題存在,則更改文件的返回大小。
IRP_MJ_CREATE
- 如果頭文件不存在prepened頭文件。
這個效果很好,MS Word 2003文檔(doc,xls,ppt)和記事本除外。 我只是似乎沒有抓住一些讀寫操作,記事本顯示標題以及文件。
我已經閱讀了很多http://www.osronline.com/,並且每個詢問那裏的人都被要求閱讀一些Nagar書籍或看他們的檔案(這是搜索的災難)。我想我已經閱讀了與我的問題有關的一切。
看來記事本使用內存映射文件,快速IO,分頁IO和上帝知道還有什麼。 我試圖掛鉤NtMapViewOfSection
,MapViewOfFile
和MapViewOfFileEx
與mHook,但當我打開記事本中的某個文件,並試圖找到映射的數據我沒有運氣(但我發現其他每個字節映射到內存)。
然後我讀到,我試圖完成的是不可能與一個鉤子,只有微過濾器驅動程序,並從我想我想念一些標誌設置。
如果有人能夠告訴我該怎麼做才能抓住記事本的操作,我會真正appriciate它。
這裏的一些代碼示例讀:
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
檢查文件名和請求過程。 (某些應用程序可能會看到標題)
如果有人可以告訴我該怎麼做才能捕獲記事本的操作,那麼我真的會認真對待它。
謝謝。
爲什麼你不攔截'Parameters.Read.MdlAddress!= NULL'的調用?這似乎是錯誤的。 –
你是對的!我會檢查出來的。 Thnaks。 – assafmo