Получить созданные/измененные/удаленные файлы определенным процессом из сеанса отслеживания событий (ETW)

Я искал решение для получения всех созданных/измененных и удаленных файлов определенным процессом из сеанса трассировки событий (ETW) (я буду обрабатывать данные из файла etl, а не из сеанса в реальном времени).

По-видимому, самым простым решением для этого было получение событий FileCreate и FileDelete от FileIo_Name и сопоставьте их с соответствующим DiskIo_TypeGroup1. Однако это решение не работает для меня, так как я не получаю никаких событий DiskIo_TypeGroup1 для соответствующих событий FileDelete, поэтому я не могу получить идентификатор процесса. Также не со всеми событиями FileCreate связано событие DiskIo_TypeGroup1 (думаю, это происходит для пустых созданных файлов или только для открытых файлов).

Примечание. Мне необходимо сопоставление DiskIo_TypeGroup1, поскольку в событиях FileIo_Name не заполнены члены ThreadId и ProcessId — они установите значение (ULONG)-1. Кроме того, я не могу решить, какие файлы были только что открыты или изменены, не зная «размера записи файла». DiskIo_TypeGroup1 также не имеет заполненных элементов ThreadId и ProcessId (в заголовке события в более новых ОС), но имеет Член структуры IssuingThreadId, из которого я могу получить сопоставление ProcessId с событиями класса Thread_TypeGroup1.

Поэтому я исследовал, как класс FileIo_Create может мне помочь, и заметил, что могу получить элемент CreateOptions, который может иметь следующие флаги: (FILE_SUPERSEDE, FILE_CREATE, FILE_OPEN , FILE_OPEN_IF, FILE_OVERWRITE, FILE_OVERWRITE_IF). Но первоначальная проблема все еще сохраняется. Как проверить, был ли файл создан с нуля, а не только что открыт (например, в случае FILE_SUPERSEDE)?

Возможно, я смогу использовать класс FileIo_ReadWrite для получения события Write. Например, при использовании класса DiskIo_TypeGroup1. Итак, если что-то было записано в файл, то могу ли я предположить, что файл был либо создан, либо изменен?

Чтобы найти удаленные файлы, я думаю, что класс FileIo_Info и событие Delete являются решением. Думаю, я могу получать события Delete и сопоставлять их с FileIo_Name, чтобы получить имена файлов.

Примечание: FileIo_Create, FileIo_Info, FileIo_ReadWrite содержат информацию об идентификаторе процесса.

Верны ли мои предположения? Что будет лучшим решением для моей проблемы?


person T. Nicolae    schedule 30.06.2016    source источник
comment
какой язык вы используете? Для .net вы можете использовать TraceEvent (nuget.org/packages/Microsoft.Diagnostics. Tracing.TraceEvent) для анализа ETL, здесь у вас есть события для всех событий FileIO и DiskIO в классе KernelTraceEventParser.   -  person magicandre1981    schedule 30.06.2016
comment
Привет @magicandre1981, я использую C++, но уже просмотрел KernelTraceEventParser, к сожалению, это не решило мою проблему, потому что TraceEvent только анализирует и форматирует события более удобным способом, не имея какой-либо высокоуровневой обработки, как в моем случае вывода created/modified/ удаленные файлы из определенного процесса. Спасибо за ваш комментарий.   -  person T. Nicolae    schedule 01.07.2016
comment
что вы имеете в виду под высоким уровнем? любые события имеют свойство processid, имя_процесса   -  person magicandre1981    schedule 01.07.2016
comment
Да, вы правы, почти все события имеют идентификатор процесса, кроме FileIo_Name (или, по крайней мере, я не могу их получить) и некоторых других событий, таких как TcpIp (см. Примечания внизу). Другой связанный вопрос можно найти здесь: stackoverflow.com/questions/26440639/ etw-system-calls-tracing Также я извлек ETL с помощью Tracerpt, чтобы увидеть результаты IMG.   -  person T. Nicolae    schedule 01.07.2016
comment
Я могу получить имя файла на событии FileIO. Я понятия не имею, какая у вас проблема   -  person magicandre1981    schedule 02.07.2016
comment
Привет @magicandre1981, я более подробно рассмотрю реализацию KernelTraceEventParser, чтобы увидеть, в чем разница (поскольку я использую непосредственно собственные API) или что я пропустил, и вернусь с подробностями, спасибо.   -  person T. Nicolae    schedule 02.07.2016
comment
ты добился какого-то прогресса?   -  person magicandre1981    schedule 06.07.2016


Ответы (1)


Я поделюсь своим реализованным решением следующим образом:

  1. Созданные файлы:

    • I have stored all FileIo_Create events as a pending create operation and waited to receive associated FileIo_OpEnd to decide if the file was opened, created, overwritten, or superseded from the ExtraInfo structure member.
  2. Измененные файлы:

    • I marked files as dirty for every Write event from FileIo_ReadWrite and every SetInfo event with InfoClass->FileEndOfFileInformation and InfoClass->FileValidDataLengthInformation from FileIo_Info. Finally on Cleanup event from FileIo_SimpleOp verify if the file was marked as dirty and store as modified.
  3. Удаленные файлы:

    • I marked the files as deleted if was opened with the CreateOptions->FILE_DELETE_ON_CLOSE flag from FileIo_Create or if a Delete event from FileIo_Info appears. Finally on Cleanup event from FileIo_SimpleOp stored the file as deleted.

Также идентификатор процесса и имя файла были получены из событий FileIo_Create, точнее из члена структуры OpenPath и члена заголовка события ProcessId.

person T. Nicolae    schedule 13.02.2017
comment
Хорошо, но как вы выяснили, что означает каждое значение ExtraInfo? - person MoeKav; 24.10.2018
comment
Извините, но я не помню, откуда я взял эту информацию. Но, как показывает мой код, значение ExtraInfo FileIo_OpEnd, связанное с FileIo_Create, содержит одно из следующих значений: #define FILE_SUPERSEDED 0x00000000 #define FILE_OPENED 0x00000001 #define FILE_CREATED 0x00000002 #define FILE_OVERWRITTEN 0x00000003 #define FILE_EXISTS 0x00000004 #define FILE_DOES_NOT_EXIST 0x00000005 - person T. Nicolae; 06.11.2018
comment
@MoeKav, пожалуйста, проверьте приведенное выше сообщение и посмотрите, поможет ли оно вам. - person T. Nicolae; 06.11.2018