Что нового

Определение доступа к заблокированному файлу

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,487
Используется вот такой скрипт (пример):

Код:
#include <WinAPIEx.au3>

$sFile = @DesktopDir & '\~Test'
DirCreate($sFile)

$hBlock = _BlockFile($sFile)

ShellExecute($sFile)
MsgBox(262144+64, @ScriptName, 'Trying to open file:' & @CRLF & @CRLF & $sFile & @CRLF & @CRLF & '...')

_UnBlockFile($hBlock)

DirRemove($sFile)

Func _BlockFile($sFile, $iShowErrMsg = 1)
	If Not FileExists($sFile) Then
		Return SetError(1, 0, -1)
	EndIf
	
	Local $hFile = _WinAPI_CreateFileEx($sFile, $OPEN_EXISTING, BitOR($GENERIC_READ, $GENERIC_WRITE), 0, _WinAPI_PathIsDirectory($sFile) ? $FILE_FLAG_BACKUP_SEMANTICS : 0)
	
	If @error Or $hFile = -1 Then
		If $iShowErrMsg Then
			If _WinAPI_PathIsDirectory($sFile) Then
				MsgBox(48, 'Error', 'Unable To Block The Folder')
			Else
				MsgBox(48, 'Error', 'Unable To Block The File')
			EndIf
		EndIf
		
		Local $iFileInUse = 0
		
		If _WinAPI_GetLastError() = 32 Then ; ERROR_SHARING_VIOLATION
			$iFileInUse = 1
		EndIf
		
		Return SetError(1, $iFileInUse, $hFile)
	EndIf
	
	Return $hFile
EndFunc

Func _UnBlockFile($hBlock)
	_WinAPI_CloseHandle($hBlock)
EndFunc


Мне нужно уметь определять когда была сделана попытка открыть заблокированный файл.
Соответственно вывести сообщение с указанием пути к этому файлу, а в идеале, запретить вывод системного сообщения о блокировке файла.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,487
*Up*
:whistle:
 

asdf8

Скриптер
Сообщения
564
Репутация
152
CreatoR [?]
Мне нужно уметь определять когда была сделана попытка открыть заблокированный файл.
Имеется в виду из сторонней программы?
На AutoIt максимум что можно сделать - отслеживание действий пользователя в проводнике Windows с перехватом событий клавиатуры и мыши.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,487
asdf8 [?]
Имеется в виду из сторонней программы?
Да, т.е действие пользователя.

На AutoIt максимум что можно сделать - отслеживание действий пользователя в проводнике Windows с перехватом событий клавиатуры и мыши.
Мышь и клавиатура не вариант.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,487
asdf8 [?]
можно менять расширение файла на расширение ассоциированное со своей программой
А что если это папка? :whistle:
 

asdf8

Скриптер
Сообщения
564
Репутация
152
CreatoR [?]
А что если это папка?
В общем случае - хз.
В большинстве случаев в Windows проводник не показывает скрытые и системные файлы и папки, если, конечно, юзер не поменял данную настройку.
В этом случае можно было бы защищаемые файлы/папки делать скрытыми и рядом с ними делать ярлык на свою программу с названием защищаемого файла, у этого метода плюс в том, что на ярлык можно навесить любую желаемую иконку и задать параметры запуска.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,487
Не, ярлыки и ассоциации это всё не то, мне нужно более корректно и изящно это сделать, костыли не нужны.
Неужели нет системного события при доступе к файлам? :scratch:
 

Prog

Продвинутый
Сообщения
640
Репутация
80
Нужно перехватить функции CreateFileA и CreateFileW. Но для этого нужно написать DLL.

CreatoR [?]
Неужели нет системного события при доступе к файлам?
Можно попробовать применить ReadDirectoryChangesW. Может что-то получится.
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,487
Prog [?]
Нужно перехватить функции CreateFileA и CreateFileW. Но для этого нужно написать DLL.
Можете написать? буду признателен...

Можно попробовать применить ReadDirectoryChangesW.
Пробовал, не может получить доступ т.к файл/каталог заблокирован.
 

firex

AutoIT Гуру
Сообщения
943
Репутация
208
CreatoR [?]
Мне нужно уметь определять когда была сделана попытка открыть заблокированный файл.Соответственно вывести сообщение с указанием пути к этому файлу, а в идеале, запретить вывод системного сообщения о блокировке файла.
Есть два известных мне варианта:
1) Написать DLL, которая будет подгружаться во все процессы. Реализовать в ней перехват Nt* функций (работающие с файлами).
2) Написать драйвер:
2-1) Интересный метод: http://www.adlice.com/kernelmode-rootkits-part-2-irp-hooks/
2-2) Документированные методы (File System Mini-Filter Driver): https://msdn.microsoft.com/en-us/library/windows/hardware/ff540402(v=vs.85).aspx
2-3) Еще один руткит: Реализовать перехват функций в ядре, которые отвечают за работу с файлами. В теорию вдаваться не стану, если заинтересует - сможете найти много информации в интернете(к примеру wasm.ru). Удобство тут в том(в отличии от ring3), что перехватываете вы функцию в оригинальном образе модуля(ntdll), который промаплен во все процессы.

P.S. Описал все довольно сжато, даже более... Если что заинтересует конкретно - готов помочь, но скажу сразу: имею практический опыт только с 1, 2-1, 2-3.
 

СН3СН2ОН

Знающий
Сообщения
78
Репутация
12
Помочь кодом не могу. Но.
Зачем что-то писать, есть же встроенный в виндовс аудит файлов, настраивается в три клика.
Вот что пишет микрософт
Включение аудита доступа пользователей к файлам, папкам и принтерам
Информационные записи системного аудита заносятся в журнал событий "Безопасность". Для включения системного аудита выполните следующие действия:

В меню "Пуск" выберите пункт "Панель управления", щелкните по ссылке "Производительность и обслуживание" и откройте группу программ "Администрирование".
Откройте элемент "Локальная политика безопасности".
Разверните элемент "Локальные политики".
Выберите папку "Политика аудита".
Двойным щелчком мыши откройте параметр "Аудит доступа к объектам".
Для отслеживания удачных попыток доступа к файлам, папкам и принтерам установите флажок "Успех".
Для отслеживания неудачных попыток доступа к файлам, папкам и принтерам установите флажок "Отказ".
Для отслеживания всех попыток доступа к объектам аудита установите оба флажка.
Нажмите кнопку "ОК".


Указание файлов, папок и принтеров в качестве объектов аудита
После включения аудита доступа к объектам Вы можете указать, для каких файлов, папок и принтеров необходимо проводить отслеживание доступа. Для этого выполните следующие действия:

В Проводнике выберите файл или папку, которую необходимо отслеживать. Для аудита принтера перейдите в системную папку "Принтеры и факсы", выбрав соответствующий пункт в меню "Пуск".
Щелкните правой кнопкой мыши по выбранному объекту и запустите команду "Свойства".
Перейдите на вкладку "Безопасность" и нажмите кнопку "Дополнительно".
Перейдите на вкладку "Аудит" и нажмите кнопку "Добавить".
В поле "Введите имена выбираемых объектов" укажите имя пользователя или группы, которую необходимо отслеживать при доступе к данному объекту. Вы можете проверить вводимое имя на наличие в списке пользователей компьютера, нажав кнопку "Дополнительно", а затем кнопку "Поиск" в окне "Выбор: Пользователь, Компьютер или Группа".
После ввода имен нажмите кнопку "ОК".
Установите требуемые флажки для отслеживания успешных и неудачных попыток при выполнении соответствующих действий и нажмите кнопку "ОК".
Дважды нажмите кнопки "ОК" в соответствующих окнах.


Возможные проблемы

Для получения возможности аудита доступа к файлам и папкам данные объекты должны располагаться на разделе с файловой системой NTFS.
Если Ваш компьютер является членом домена, и на уровне домена применены собственные политики аудита, данные политики имеют более высокий приоритет по сравнению с настройками локальной политики.
Скрипты в интернете есть, но на автоите не нашел. Спасибо.
p.s. Завтра попробую, может получится переделать на AutoIt.

Велосипеды. (WinXP)
Что найдено:
1. Google Win32_LogicalFileSecuritySetting+autoit
1.1 Тема Set Auditing for Files and Folders using WMI
Из нее делаем шаблон для теста
Код:
#include <WinAPIEx.au3>
#include <Constants.au3>
#include <GUIConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>
#include <String.au3>
#include <file.au3>
#include <Array.au3>

$s_ACLtool = "SetACL.exe"

$sFile = @DesktopDir & '\~Test'
$sFile_ = '"' & $sFile & '"'
DirCreate($sFile)
$s_cmd =  $s_ACLtool & ' -on '& $sFile_ &' -ot file -actn ace -ace "n:ПОЛЬЗОВАТЕЛЬ;p:full;m:aud_succ;i:so,np;w:sacl;s:y"'
RunWait(@ComSpec & " /c " & $s_cmd, "")
MsgBox(48, '123', '13')

$hBlock = _BlockFile($sFile)

ShellExecute($sFile)
MsgBox(262144+64, @ScriptName, 'Trying to open file:' & @CRLF & @CRLF & $sFile & @CRLF & @CRLF & '...')

_UnBlockFile($hBlock)

DirRemove($sFile)

Func _BlockFile($sFile, $iShowErrMsg = 1)
    If Not FileExists($sFile) Then
        Return SetError(1, 0, -1)
    EndIf

    Local $hFile = _WinAPI_CreateFileEx($sFile, $OPEN_EXISTING, BitOR($GENERIC_READ, $GENERIC_WRITE), 0, _WinAPI_PathIsDirectory($sFile) ? $FILE_FLAG_BACKUP_SEMANTICS : 0)

    If @error Or $hFile = -1 Then
        If $iShowErrMsg Then
            If _WinAPI_PathIsDirectory($sFile) Then
                MsgBox(48, 'Error', 'Unable To Block The Folder')
            Else
                MsgBox(48, 'Error', 'Unable To Block The File')
            EndIf
        EndIf

        Local $iFileInUse = 0

        If _WinAPI_GetLastError() = 32 Then ; ERROR_SHARING_VIOLATION
            $iFileInUse = 1
        EndIf

        Return SetError(1, $iFileInUse, $hFile)
    EndIf

    Return $hFile
EndFunc

Func _UnBlockFile($hBlock)
    _WinAPI_CloseHandle($hBlock)
EndFunc
Также нам пригодится(необходима) программа SetACL: Windows ACL management
Теперь мы умеем одной строчкой указать на почти ЛЮБОЙ объект в системе который мы можем мониторить.
2. Как распарсить журнал отчетов.(В процессе)
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,487
firex [?]
Если что заинтересует конкретно - готов помочь, но скажу сразу: имею практический опыт только с 1, 2-1, 2-3.
Мне любой метод подойдёт, главное чтобы работал :laugh:.
Ну и желательно чтобы можно было подавлять системное сообщение о попытке доступа.
 

СН3СН2ОН

Знающий
Сообщения
78
Репутация
12
Случайно проверил тему, думал вы посмеялись над моим вариантом.
Хранятся в WinXP
Код:
C:\WINDOWS\system32\config\*.evt
Можно поменять расположение в реестре
Код:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog
Завтра попробую их распарсить. Если надо.
 

firex

AutoIT Гуру
Сообщения
943
Репутация
208
CreatoR [?]
Ну и желательно чтобы можно было подавлять системное сообщение о попытке доступа.
О каком конкретно сообщении идет речь? Explorer'a?

Мне любой метод подойдёт, главное чтобы работал
Ну так или иначе вам желательно самому разобраться, одним драйвером естественно тут не обойтись. Как минимум необходим UserMode интерфейс.
Возможно в свободное время я напишу подобную UDF в связке с полноценным драйвером, в целом там работы мало.

Дабы прогреть память навертел за считанные минуты, как и ранее все работает без проблем: (в данном случае без контроля доступа, только его логирование)
Код:
	UNICODE_STRING FltDevice;
	PFILE_OBJECT FltFileObject = NULL;
	PDEVICE_OBJECT FltDeviceObject = NULL;

	RtlInitUnicodeString(&FltDevice, L"\\FileSystem\\Filters\\FltMgr");
	ntStatus = IoGetDeviceObjectPointer(&FltDevice, FILE_READ_DATA, &FltFileObject, &FltDeviceObject);
	if (NT_SUCCESS(ntStatus)) {
		HookedDriver = IoGetAttachedDeviceReference(FltDeviceObject)->DriverObject;

		fnOrigMjFunc = (pMjFunction)HookedDriver->MajorFunction[IRP_MJ_CREATE];
		HookedDriver->MajorFunction[IRP_MJ_CREATE] = FltMgrDispatch;

		ImDbg("DriverObject=0x%x", HookedDriver);
	}

	// ...

NTSTATUS FltMgrDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp) {
	PIO_STACK_LOCATION IrpStack;

	UNREFERENCED_PARAMETER(DeviceObject);

	IrpStack = IoGetCurrentIrpStackLocation(Irp);
	switch (IrpStack->MajorFunction) {
		case IRP_MJ_CREATE:
			if (IrpStack->FileObject != NULL) {
				ImDbg("Hooked > %ws", IrpStack->FileObject->FileName.Buffer);
			}
			break;
	}

	return fnOrigMjFunc(DeviceObject, Irp);
}

Результат:
830de18074.png

P.S. Честно говоря лучше использовать документированные методы, ибо мною используемый вариант заставит кричать половину антивирусов, по крайней мере должен. (сам их не использую)
 
Автор
CreatoR

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,487
firex [?]
О каком конкретно сообщении идет речь? Explorer'a?
Речь о сообщениях при открытий файла, это может быть ассоциированная с файлом программа, или проводник системы.

Если кто то сможет написать что то готовое (взять и использовать), буду очень признателен, если честно нет времени изучать как оно работает.
Мне это нужно в основном для утилиты BlockIt, т.ч будет полезно и для других :smile:.
 
Верх