Статья вторая, запрет доступа к файлу...

Сразу скажу что долго мучился и наконец домучился,

в течении всего этого времени я пытался создать драйвер который бы при запуске блокировал бы файл например 123.txt и это скажу я Вам у меня получилось.

Что пришлось сделать, отказаться от ВМ по крайне мере от VirtualBox, вм я хотел ставить для "отглаживания" драйвера, что в принципе не пригодилось, но на это я потратил много времени и ошибку решил присвоить вм, а когда начал делать его на компе, то в голову пришла идея как реализовать его по другому.

Все файлы которые я использовал, можно будет скачать в конце статьи.

Приведу сноски из файла nullFilter.c которые я добавил в файл с прошлой статьи.

Прототипы функций:

DRIVER_INITIALIZE DriverEntry;

NTSTATUS

DriverEntry (

__in PDRIVER_OBJECT DriverObject,

__in PUNICODE_STRING RegistryPath

);

NTSTATUS

NullUnload (

__in FLT_FILTER_UNLOAD_FLAGS Flags

);

NTSTATUS

NullQueryTeardown (

__in PCFLT_RELATED_OBJECTS FltObjects,

__in FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags

);

FLT_PREOP_CALLBACK_STATUS

NullPreCreate (

__inout PFLT_CALLBACK_DATA Data,

__in PCFLT_RELATED_OBJECTS FltObjects,

__deref_out_opt PVOID *CompletionContext

);// Добавили функцию для перехвата операций с файлом

NTSTATUS

NullInstanceSetup (

__in PCFLT_RELATED_OBJECTS FltObjects,

__in FLT_INSTANCE_SETUP_FLAGS Flags,

__in DEVICE_TYPE VolumeDeviceType,

__in FLT_FILESYSTEM_TYPE VolumeFilesystemType

);// Функция для добавления тома устройства

Вспомогательные данные:

typedef struct _NULL_FILTER_DATA {

PDRIVER_OBJECT DriverObject;

PFLT_FILTER FilterHandle;

} NULL_FILTER_DATA, *PNULL_FILTER_DATA;

NULL_FILTER_DATA NullFilterData;

#ifdef ALLOC_PRAGMA

#pragma alloc_text(INIT, DriverEntry)

#pragma alloc_text(PAGE, NullUnload)

#pragma alloc_text(PAGE, NullInstanceSetup)

#pragma alloc_text(PAGE, NullQueryTeardown)

#pragma alloc_text(PAGE, NullPreCreate)

#endif // этими строчками мы говорим драйверу что он будет работать в "подкачиваемой" памяти.

const FLT_OPERATION_REGISTRATION Callbacks[] = {

{ IRP_MJ_CREATE, // За это действие будет отвечать функция NullPreCreate

0,

NullPreCreate,

NULL},

{ IRP_MJ_OPERATION_END}

}; //если мы перехватывали запись, чтение или еще что то нужно было бы добавить сюда функцию

CONST FLT_REGISTRATION FilterRegistration = {

sizeof( FLT_REGISTRATION ), // Size

FLT_REGISTRATION_VERSION, // Version

0, // Flags

NULL, // Context

Callbacks, // Operation callbacks

NullUnload, // FilterUnload

NullInstanceSetup, // InstanceSetup

NullQueryTeardown, // InstanceQueryTeardown

NULL, // InstanceTeardownStart

NULL, // InstanceTeardownComplete

NULL, // GenerateFileName

NULL, // GenerateDestinationFileName

NULL // NormalizeNameComponent

};

NTSTATUS

DriverEntry (

__in PDRIVER_OBJECT DriverObject,

__in PUNICODE_STRING RegistryPath

)

{

NTSTATUS status;

UNREFERENCED_PARAMETER( RegistryPath );

status = FltRegisterFilter( DriverObject,

&FilterRegistration,

&NullFilterData.FilterHandle );

//регистрируем наш фильтр в Filter Manager

ASSERT( NT_SUCCESS( status ) );

if (NT_SUCCESS( status )) {

status = FltStartFiltering( NullFilterData.FilterHandle );

//Запускаем фильтр что приводит к присоединению всех открытых томов

if (!NT_SUCCESS( status )) {

FltUnregisterFilter( NullFilterData.FilterHandle );

}// если не получилось то отменяем регистрацию

}

DbgPrint("Null Filter, DriverEntry");

return status;

}

NTSTATUS

NullInstanceSetup (

__in PCFLT_RELATED_OBJECTS FltObjects,

__in FLT_INSTANCE_SETUP_FLAGS Flags,

__in DEVICE_TYPE VolumeDeviceType,

__in FLT_FILESYSTEM_TYPE VolumeFilesystemType

)

{

UNREFERENCED_PARAMETER( FltObjects );

UNREFERENCED_PARAMETER( Flags );

UNREFERENCED_PARAMETER( VolumeFilesystemType );

PAGED_CODE();

DbgPrint("Null Filter, NullInstanceSetup");

ASSERT( FltObjects->Filter == NullFilterData.FilterHandle );

if (VolumeDeviceType == FILE_DEVICE_NETWORK_FILE_SYSTEM) {

return STATUS_FLT_DO_NOT_ATTACH;

}// Не присоединяем сетевую систему, блокируем только на своем компе.

return STATUS_SUCCESS;

}

NTSTATUS

NullQueryTeardown (

__in PCFLT_RELATED_OBJECTS FltObjects,

__in FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags

)

{

UNREFERENCED_PARAMETER( FltObjects );

UNREFERENCED_PARAMETER( Flags );

PAGED_CODE();

DbgPrint("Null Filter, NullQueryTeardown");

return STATUS_SUCCESS;

}// при внезапно отключении должна вызваться эта функция оставил её на всякий случай, но ни разу не вызывалась

FLT_PREOP_CALLBACK_STATUS //самая главная функция в этой статье

NullPreCreate (

__inout PFLT_CALLBACK_DATA Data, // Приходят данные о файловой операции

__in PCFLT_RELATED_OBJECTS FltObjects, // В это поле приходят данные связанные с функцией, не используется

__deref_out_opt PVOID *CompletionContext // Эту мы тоже не трогаем

)

{

PFLT_FILE_NAME_INFORMATION nameInfo; //Нужна для помещения информации файла

NTSTATUS status; //Вспомогательная переменная для статуса

BOOLEAN scanFile; //Здесь будет храниться условие блокировки файла

UNICODE_STRING filename; //Можно было обойтись без нее, в ней храниться имя блокируемого файла

UNREFERENCED_PARAMETER( FltObjects );

UNREFERENCED_PARAMETER( CompletionContext );

PAGED_CODE();

ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);

status = FltGetFileNameInformation( Data,

FLT_FILE_NAME_NORMALIZED |FLT_FILE_NAME_QUERY_DEFAULT,

&nameInfo ); //Получаем данные о файле

if (!NT_SUCCESS( status )) {

return FLT_PREOP_SUCCESS_WITH_CALLBACK;

}// не получили вышли

status = FltParseFileNameInformation( nameInfo );//разбиваем данные на путь, имя, расширение и т.п.

if (!NT_SUCCESS( status )) {

return FLT_PREOP_SUCCESS_WITH_CALLBACK;

}// нет и не надо

if(nameInfo->FinalComponent.Length>0) // проверяем имеем ли мы имя файла

{// блокировка

RtlInitUnicodeString(&filename,L"123.txt\0");// помещаем в строку 123.txt советую ставить ноль в конце на всяк пожарный

scanFile = RtlEqualUnicodeString(&nameInfo->FinalComponent,&filename,TRUE);// проверяем совпадает ли имя файла с 123.txt

if(scanFile) //если да то пишем статус доступ запрещен

{

Data->IoStatus.Status=STATUS_ACCESS_DENIED;// доступ запрещен

return FLT_PREOP_COMPLETE;// возвращаем что у нас все в поряде и нужно данные взять с Data

}

}

return FLT_PREOP_SUCCESS_WITH_CALLBACK; // если вернуться из функции так то из Data не будут взята инфо и файл не блокируется

// это если мы его в блокировке написали

}

Так как мы взяли пример NullFilter и там просто было включение фильтра и все нам нужно изменить inf файл как в примере scanner в принципе все функции взяты от туда.

В конце inf файла меняем

;Instances specific information.

DefaultInstance = "Null Instance"

Instance1.Name = "Null Instance"

Instance1.Altitude = "370020"

Instance1.Flags = 0x1 ; Suppress automatic attachments

На вот это

;Instances specific information.

DefaultInstance = "Null Instance"

Instance1.Name = "Null Instance"

Instance1.Altitude = "265000"

Instance1.Flags = 0x0 ; Allow all attachments

без этого тома не будут цепляться.

По поводу примера, файлы должны находиться в "C:\MyDir\Filter" чтобы совпадали все пути.

Запускаем x86 Checked Build Environment, затем в появившемся окне любую клавишу,

далее правой кнопкой мыши на inf и установить, затем запускаем DbugView и KmdManager в последнем выбираем наш драйвер и нажимаем Run

пробуем создать файл 123.txt открыть скопировать удалить, пока драйвер работает это не возможно.

Может в коде где закрались ошибки, если кто найдет пишите.

Вот так выглядит все это дело

скопировать не дает открыть тоже.

Скачать пример

В следующий раз попробую сделать связь с программой в user mode.