Статья вторая, запрет доступа к файлу...
Сразу скажу что долго мучился и наконец домучился,
в течении всего этого времени я пытался создать драйвер который бы при запуске блокировал бы файл например 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.