Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Отслеживание копирования


Автор: ANDeath 13.11.2006, 15:29
Подскажите пожалуйста, какими методами можно отследить копирование файлов на локальной машине (с/на флешку,  с/на CD, через сетку), причем требуется информация: кто (ip, имя машины, имя пользователя), куда (ip, путь к исходной дириктории), когда и само сабой что копировалось.

Автор: Softaz 13.11.2006, 15:52
Код

System.IO.FileSystemWatcher

См. аттач

Добавлено @ 15:55 
Но работает только с локальной машиной и с NTFS.

Автор: ANDeath 13.11.2006, 16:04
Softaz, я с .NET сталкиваюсь впервые, мне то всего-то надо узнать инфу перечисленную выше и отправить на сервер (последнее по началу задумывалось делать через VBS, да если честно не хочется заморачиваться еще с C# - итак голова гудит) объясни или пошли туда где описан монстр System.IO.FileSystemWatcher и с чем его едят? Премного благодарен.

Автор: Softaz 13.11.2006, 16:17
Если тебе нужно не только мониторить, но и сохранять файлы до _изменения_, то это не подойдет.
Надо перехватывать функции в kernel mode. Можно, конечно и в UserMode, но обхитрить такую программку можно будет с полпенька. Для запуска файла

Код

ZwCreateProcess
RtlCreateProcessPrameters
RtlCreateUserProcess
NtResumeThread


И тогда уже это не .NET, а win32 native code
Рабочий пример:
Код

NTSTATUS NewZwCreateFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, 
        PLARGE_INTEGER AllocationSize, ULONG FileAttributes, ULONG ShareAccess, ULONG CreateDisposition, ULONG CreateOptions, PVOID EaBuffer, 
        ULONG EaLength)
{   
    NTSTATUS    status;
    WCHAR        *pExt;
    CHAR        szProcess[NT_PROCNAMELEN];
    
    status = OldZwCreateFile(FileHandle, DesiredAccess, ObjectAttributes, IoStatusBlock, AllocationSize,
            FileAttributes, ShareAccess, CreateDisposition, CreateOptions, EaBuffer, EaLength);

    if (wcsrchr(ObjectAttributes->ObjectName->Buffer, '\\') < wcsrchr(ObjectAttributes->ObjectName->Buffer, '.'))
    {
        if (wcslen(ObjectAttributes->ObjectName->Buffer) < 5) return status;
        pExt = wcsrchr(ObjectAttributes->ObjectName->Buffer, '.');
        if (pExt == NULL) return status;
        GetProcessName(szProcess);
        if (bIncExt) if (!TestMask(szInclude, &pExt[1])) return status;
        if (bExcExt) if (TestMask(szExclude,  &pExt[1])) return status;
        if (bIncProgram) if (!TestProgram(szPrograms, szProcess))   return status;
        if (bExcProgram) if (TestProgram(szExcPrograms, szProcess)) return status;

        PCREATE_BUFFER pBuffer = AddCreateEntry();
        if (pBuffer != NULL)
        {
            LARGE_INTEGER time, time_local;
            TIME_FIELDS   tf;

            pBuffer->hfile   = *FileHandle;
            wcsncpy(pBuffer->szBuffer, ObjectAttributes->ObjectName->Buffer, 255); 
            strncpy(pBuffer->szProcess, szProcess, NT_PROCNAMELEN);

            KeQuerySystemTime(&time);
            ExSystemTimeToLocalTime(&time, &time_local);
            RtlTimeToTimeFields(&time_local, &tf);

            if (tf.Hour < 10) 
            {
                strcpy(pBuffer->szTime, "0");
                _itoa(tf.Hour, (pBuffer->szTime+1), 10);
            }
            else _itoa(tf.Hour, pBuffer->szTime, 10);
            strcat(pBuffer->szTime, ":");

            if (tf.Minute < 10) 
            {
                strcat(pBuffer->szTime, "0");
                _itoa(tf.Minute, (pBuffer->szTime+4), 10);
            } 
            else _itoa(tf.Minute, (pBuffer->szTime+3), 10);
            strcat(pBuffer->szTime,

Автор: Exception 13.11.2006, 16:20
Цитата(ANDeath @  13.11.2006,  17:04 Найти цитируемый пост)
Softaz, я с .NET сталкиваюсь впервые, мне то всего-то надо узнать инфу перечисленную выше и отправить на сервер (последнее по началу задумывалось делать через VBS, да если честно не хочется заморачиваться еще с C# - итак голова гудит)


Простите, тогда причём тут .NET?

Автор: ANDeath 13.11.2006, 16:32
Цитата

Простите, тогда причём тут .NET

Ищу готовые ответы, да вот только все более куда-то в дебри уносит...

Автор: mr.DUDA 13.11.2006, 19:18
FileSystemWatcher работает и с FAT32.

Автор: Softaz 13.11.2006, 21:17
Цитата(mr.DUDA @  13.11.2006,  19:18 Найти цитируемый пост)
FileSystemWatcher работает и с FAT32.

У меня не работал почему-то. Мне сказали, что и не работает... свято верил  smile 

Автор: ANDeath 14.11.2006, 11:21
Товарищи, а реально изучить и написать следующее...

Есть любая win NT, с любой файловой системой, на этой локальной машине следует провернуть:
Как только происходит копирование на сьемный носитель (флешка, диск) следует тут же отправить подробную инфу на сервер; если сервер недоступен, то повторить чуть поже...

Это при условии, что я .net не знаю, вообще занимаюсь веб-разработкой, ну и когда-то написал в институте на С++ MFC пару прог...
За какое время, такое возможно изучить и написать, и какие средства для это надо использовать?

Автор: archimed7592 15.11.2006, 02:39
Цитата(ANDeath @  14.11.2006,  12:21 Найти цитируемый пост)
оварищи, а реально изучить и написать следующее...
вполне...что утечек информации много? smile скорее через интернет, чем через флешку...

Цитата(ANDeath @  14.11.2006,  12:21 Найти цитируемый пост)
Это при условии, что я .net не знаю, вообще занимаюсь веб-разработкой, ну и когда-то написал в институте на С++ MFC пару прог...За какое время, такое возможно изучить и написать, и какие средства для это надо использовать?
.net здесь вообще не при чем. смотри в сторону winapi. особенно при условии, что машина win NT любая...т. е. не исключено, что .net на ней нет smile за какое время, сказать сложно. смотря насколько всевидящей должна быть прога.

Автор: alir 15.11.2006, 11:26
ANDeath
Если все-таки решил на .net, то начинай копать с примера:

Код

using System;
using System.Text;

namespace FileWatcher
{
    class DemoFileWatcher
    {
        static FileSystemWatcher fw;
        public static void OnChanged(Object o, FileSystemEventArgs e)
        {
            Console.WriteLine("File:" + e.FullPath + "Change type:" + e.ChangeType);
        }
        public static void OnRenamed(Object o, RenamedEventArgs e)
        {
            Console.WriteLine("File {0} renamed to {1}", e.OldFullPath, e.FullPath);
        }
        static void Main(string[] args)
        {
            fw = new FileSystemWatcher();
            fw.Path = @"C:\windows"
            fw.IncludeSubdirectories = true;
            //в фильтрах указывай какие изменения будешь отслеживать
            fw.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.FileName | NotifyFilters.CreationTime | NotifyFilters.LastWrite;
            fw.Filter = "*.*";
            fw.EnableRaisingEvents = true;
            fw.Changed += new FileSystemEventHandler(OnChanged);
            fw.Renamed += new RenamedEventHandler(OnRenamed);
            Console.ReadLine();
        }


если # не любишь:

Код

Imports System.IO
Module FileWatcher
    Public fw As FileSystemWatcher
    Sub Main()
        fw = New FileSystemWatcher()
        fw.Path = "C:\windows" : fw.IncludeSubdirectories = True : fw.Filter = "*.*"
        fw.NotifyFilter = NotifyFilters.LastAccess Or NotifyFilters.LastWrite Or NotifyFilters.FileName
        fw.EnableRaisingEvents = True
        AddHandler fw.Changed, AddressOf OnChanged
        AddHandler fw.Created, AddressOf OnChanged
        AddHandler fw.Deleted, AddressOf OnChanged
        AddHandler fw.Renamed, AddressOf OnRenamed
        Console.ReadLine()
    End Sub
    Public Sub OnChanged(ByVal o As Object, ByVal e As FileSystemEventArgs)
        Dim s As String = ""
        Select Case e.ChangeType
            Case WatcherChangeTypes.Changed
                s = "changed"
            Case WatcherChangeTypes.Created
                s = "created"
            Case WatcherChangeTypes.Deleted
                s = "deleted"
        End Select
        Console.WriteLine("File:" + e.FullPath + ":" + s)
    End Sub
    Public Sub OnRenamed(ByVal o As Object, ByVal e As RenamedEventArgs)
        Console.WriteLine("File {0} renamed to {1}", e.OldName, e.FullPath)
    End Sub
End Module


Цитата
Товарищи, а реально изучить и написать следующее...

Все реально, в том числе и для .net. Организацию сетки смотри в System.Net.

Автор: ANDeath 15.11.2006, 12:28
alir, лично мне, начинать надо с общей концепции .net) но все равно спасибо...
Уже решил писать на С++ под api хук, следящий за буфером обмена...
потом или службу попытаюсь создать, или прогу висящую в трее, о которой никто не должен знать...а может и на vbs, что-нибудь придумаю...

Автор: Softaz 15.11.2006, 13:28
ANDeath, ты на hxxp://wasm.ru/forum/ сходи - там такие темы через день всплывают, почитай статьи Ms-Rem о перехвате функций.
Только писать такое на .net будет сложнее, чем на обычном с++. Потому что для последнего случая в сети полно примеров перехвата функций.
Опыт ты получишь колоссальный, главное на 100-ой неудачной компиляции не сдаться.

Автор: mr.DUDA 15.11.2006, 21:48
Цитата(ANDeath @  15.11.2006,  11:28 Найти цитируемый пост)
Уже решил писать на С++ под api хук, следящий за буфером обмена...

Фигня получится, если к примеру будем тотал командиром копировать, или драг-дропом, или через батник, и т.п.

Автор: ANDeath 17.11.2006, 10:43
mr.DUDA, да, пожалуй ты прав, а есть ли какие-нибудь идеи? вариант с апи тогда вообще отпадает?

Автор: mr.DUDA 17.11.2006, 11:39
API Hook нужен на функции CopyFile/CopyFileEx и MoveFile/MoveFileEx, см. http://www.codeproject.com/system/hooksys.asp

Автор: ANDeath 17.11.2006, 14:16
mr.DUDA, а как это хук на CopyFile b MoveFile, они же ничего в очередь сообщений не кидают?

Автор: mr.DUDA 17.11.2006, 14:53
Цитата(ANDeath @  17.11.2006,  13:16 Найти цитируемый пост)
mr.DUDA, а как это хук на CopyFile b MoveFile, они же ничего в очередь сообщений не кидают?

Почитай плз ссылку что я дал выше. API хук и windows hook разные вещи. API hook юзает вин-hook для инжекции в чужое адресное пространство, но по сути своей и назначению - совершенно другая область: api-hooks = перехват вызовов WinAPI функций, win-hooks = перехват оконных сообщений.

Автор: ANDeath 17.11.2006, 15:04
mr.DUDA, на данный момент, имеет ли смысл изучать это все? смогу ли я после всего узнать куда был скопирован файл, и определить является ли пункт назначения съемным носителем (cd, флешка, внешний хард)?

Автор: mr.DUDA 17.11.2006, 20:35
Цитата(ANDeath @  17.11.2006,  14:04 Найти цитируемый пост)
 смогу ли я после всего узнать куда был скопирован файл

Да, путь source и destination в обеих функциях есть, этого достаточно.

Цитата(ANDeath @  17.11.2006,  14:04 Найти цитируемый пост)
и определить является ли пункт назначения съемным носителем (cd, флешка, внешний хард)?

Это придётся отдельно сделать - в .NET есть стандартный класс DriveInfo, у него можно это узнать. Если нужна более детальная инфа о типе носителя (например, отличить флешку от флопика), то помогут классы из неймспейса System.Management

Автор: ANDeath 18.11.2006, 01:04
mr.DUDA, во-первых, большое спасибо за консультацию, приступаю к изучению апи-хук  smile ...если есть какая-нибудь инфа о том как его писать - поделись пожалуйста...

во-вторых, а по букве из пути destination нельзя ли определить тип запоминающего устройства?
для флопи это понятно будет - диск A
для флешки и мобильного харда, может можно как-нибудь определить через апи-функции?
а вот как отследить запись на cd - явно проблема...

Автор: Softaz 18.11.2006, 02:21
Цитата(ANDeath @  18.11.2006,  01:04 Найти цитируемый пост)
а вот как отследить запись на cd - явно проблема...

Обычно дисковод блокируется во время записи (иногда его блокируют также некоторые инсталляторы, но редко)
Так что если заблокирован, то скорее всего что-то пишут.


Так один приколист сделал прогу, "запоминающую" первый обнаруженный дисковод, и если производилась запись, то отправлял комп в ребут. Если вставлялся другой дисковод - все было нормально. И так несколько дисководов хапнул как сломанные.



Цитата(ANDeath @  18.11.2006,  01:04 Найти цитируемый пост)
во-вторых, а по букве из пути destination нельзя ли определить тип запоминающего устройства?

Вот для этого и существуют классы, названные mr.DUDA.

Автор: mr.DUDA 18.11.2006, 12:45
Цитата(ANDeath @  18.11.2006,  00:04 Найти цитируемый пост)
во-вторых, а по букве из пути destination нельзя ли определить тип запоминающего устройства?для флопи это понятно будет - диск Aдля флешки и мобильного харда, может можно как-нибудь определить


Цитата(mr.DUDA @  17.11.2006,  19:35 Найти цитируемый пост)
в .NET есть стандартный класс DriveInfo, у него можно это узнать. Если нужна более детальная инфа о типе носителя (например, отличить флешку от флопика), то помогут классы из неймспейса System.Management


Автор: ANDeath 18.11.2006, 13:12
Кажется, меня не так поняли...я хотел узнать можно ли определить тип зап. устройства по имени, ограничиваясь языками с++ и vbs, ну не хватит мне времени чтобы еще в .NET ковыряться...
Softaz, а как связать: сидюк блокируется после начала записи и перехват апи-функций копирования? Насколько я себе это представляю, проги типа стандартного win-резака и nero про запоминают список необходимых файлов (ссылки на них), а потом просто читая эти файлы, пишут на CD. Так?

P.S.: вопрос о  литературе и примерах об api-хуках остается открытым и крайне актуальным.
Ссылка на пример? предоставленная mr.DUDA, безусловно является крайне полезной, но не достаточно информативной для меня.
В нете нашел как писать апи-хуки на pascal, да вот только видно не владею им в достаточно степени.

Автор: mr.DUDA 18.11.2006, 15:10
Цитата(ANDeath @  18.11.2006,  12:12 Найти цитируемый пост)
Кажется, меня не так поняли...я хотел узнать можно ли определить тип зап. устройства по имени, ограничиваясь языками с++ и vbs, ну не хватит мне времени чтобы еще в .NET ковыряться...

Тогда эта тема - кандидат на перемещение в один из указанных разделов.  smile 

Автор: ANDeath 19.11.2006, 17:03
mr.DUDA, если бы там отвечали, я бы здесь не сидел... smile 

Автор: mr.DUDA 19.11.2006, 22:07
ANDeath, так или иначе, по C++ и VBS никто здесь советов не даёт.

Автор: ANDeath 2.12.2006, 17:40
Триумфальное возвращение к .NET  smile 

Средствами WMI и VBS ничего неудалось поделать; основная проблемма заключается в том чтобы узнать путь к файлу, который был скопирован.

Копал и Api-hook для CopyFile, но работает это не слаженно и его можно легко обойти....
Так же смотрел исходники filemon с его виртуальным драйвером - слишком много гемороя...

И вот я вернулся к .NET...просмотрел, на скорую руку, синтаксис C#...и пространство имен System.IO. И опять возникает вопрос можно ли понять какой файл был скопирован? Хотя бы следить за событиями чтения файлов? Я уже даже незнаю как решать эту проблему, может как-нибудь связывать событие создания файла с процессами (просто предположение). Я уже не вспоминаю про запись на компакт-диски...

Автор: Softaz 2.12.2006, 17:53
Цитата(ANDeath @  2.12.2006,  17:40 Найти цитируемый пост)
И опять возникает вопрос можно ли понять какой файл был скопирован?


Ты внимательнее ответы читай  smile 
Вот здесь http://forum.vingrad.ru/s/07187540e1f9ed2618dc69c3af4ad45e/topic-121301.html#
в аттаче целая программка

Автор: ANDeath 3.12.2006, 14:08
[b]Softaz[/b,
Во-первых эта программа у меня только запустила форму и отказалась как-либо реагировать на нажатие кнопок и на события происходящие в папке, указаной в xml-документе...может она только показательная и оно так и надо, но...

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

FormMain.cs
Код

.....
DataRowView drv = (DataRowView)bs.Current;

System.IO.FileSystemWatcher fileSystemWatcher13 = new FileSystemWatcher();
fileSystemWatcher13.NotifyFilter = System.IO.NotifyFilters.FileName | System.IO.NotifyFilters.Size;
fileSystemWatcher13.Path = drv.Row["path"].ToString();
fileSystemWatcher13.IncludeSubdirectories = Convert.ToBoolean(drv.Row["inc_sf"]);
fileSystemWatcher13.Filter = drv.Row["filter"].ToString();
fileSystemWatcher13.SynchronizingObject = this;

fileSystemWatcher13.Changed += new System.IO.FileSystemEventHandler(this.fileSystemWatcher12_Changed);
fileSystemWatcher13.Created += new System.IO.FileSystemEventHandler(this.fileSystemWatcher12_Changed);
fileSystemWatcher13.Deleted += new System.IO.FileSystemEventHandler(this.fileSystemWatcher12_Changed);
fileSystemWatcher13.Renamed += new System.IO.RenamedEventHandler(this.fileSystemWatcher122_Changed);
.....

Автор: ivashkanet 3.12.2006, 15:21
fileSystemWatcher следит за конкретной папкой (или файлом). Есу дела нет как изменилось его содержимое. 
Ты скопировал или модифицировал или еще что-нить сделал  smile Ему главное, что состояние объекта его наблюдения изменилось  smile 

Цитата(ANDeath @  3.12.2006,  13:08 Найти цитируемый пост)
каким образом здесь возможно отследить за копированием?

Можно так:
Цитата(ANDeath @  3.12.2006,  13:08 Найти цитируемый пост)
fileSystemWatcher13.Changed += new System.IO.FileSystemEventHandler(this.fileSystemWatcher12_Changed);
fileSystemWatcher13.Created += new System.IO.FileSystemEventHandler(this.fileSystemWatcher12_Changed);

Правда для Changed нужно как-то отсеивать модификацию файла прямо в папке.
Хотя я считаю, что это не нужно делать воообще.

Или ты хочешь отследить момент когда ИЗ контролируемой папки что-то копируют?
Тогда FSW не особо проходит. Не ставить же его на все доступные диски  smile 


Автор: ANDeath 3.12.2006, 16:47
Цитата

Или ты хочешь отследить момент когда ИЗ контролируемой папки что-то копируют?

Именно! а зачем мне следить за наполнением папок? поддерживать чистоплотность?  smile

Цитата

Тогда FSW не особо проходит. Не ставить же его на все доступные диски

Может как-нибудь сканировать порты usb? или наблюдать за драйверами?

Автор: Rustemka 5.12.2006, 00:51
Когда я тоже думал (неделюку назад) systemwatcher юзать, но если его юзаешь, то нельзя флэшку отключить, пишет что она "занята"
если останавливаешь программу наблюдатель, то "флэшку можно безопасно извлечь из компьютера"

вариант 2. если физически выдернуть флэшку и назад воткнуть, то наблюдения за файловой системой прекратятся, можно что угодно скопировать на флэшку или с нее.

Вот тебе и файло наблюдательsmile разочаровал он меня!

Добавлено @ 00:54 
Может быть конечно все таки решение понемножку созреет (не только у меня)

Автор: ANDeath 5.12.2006, 12:28
Когда меня осенило писать все на VBS используя WMI, я в наивном неведении, что нельзя отслеживать события чтения, все-таки написал скрипт, который перехватывал созданные методом копирования файлы и реализовал модуль, который следил за подключениями сьемных носителей (тип 1 в FSO)...в такой ситуации "вариант 2" - это не проблемма...а автоматическое прекращение выполнение скрипта - только на руку...
...но что делать, со слабонервными, которые боятся дотронуться до флешки пока точно не убедятся что она отключена? это взаправду косяк...
...но повтарюсь, трабл в том чтобы определить какой файл был скопирован!!!

p.s.: судя по молчанию здешних мастеров, вывод один - въежать в код filemon и медленно, но уверенно писать прототип на winapi...

p.p.s.: впрочем, меня вчера уже уволили с испытательного срока и мне уже .... зато прокачался немалым опытом smile 
...а фирма, в которую я нанимался программистом, послала заказ какой-то здешней фирме-разработчику, которая в свою очередь обещала написать прогу, следящую за всеми перемещениями в FS (в том числе и запись на CD) на .NET...любопытно, не правда ли? smile

Автор: Rustemka 5.12.2006, 14:46
ANDeath данную программу и тему планируешь развивать?

Автор: ANDeath 5.12.2006, 16:13
Rustemka, есть маленький интерес к этому делу, но идей нет...
Через файловую систему, что либо подобное не реализуется, можешь не капать, проверенно на WMI и .NET...
...и оно правильно, там все реализуется через объекты, и это логично: создание, изменение параметров и удаление объекта зафиксировать легко...

Сейчас других проблем поболее, так что буду поддерживать тему пассивно...

P.S.:
Знакомый, бывший кгб-шник, занимавшийся радио-компьтер техникой советских времен, рассказывал что эту проблему легко решали на ассемблере (через вектора прерывания, порты и т.п.), а люди пользующиеся языками высокого уровня, на самом деле не программисты, а так - прикладники...старая школа smile

Автор: Rustemka 5.12.2006, 16:47
А если копать в сторону, e.GetType там можно найти например, кто изменил файл?
e.GetType.GUID  Не работает

Оказывается так можно и за сетевым ресурсом наблюдать, только не понятно кто это сделал (скопировал, удалил)

Автор: ivashkanet 5.12.2006, 16:54
Rustemka, e.GetType возвращает тип объекта 
Т.е. тебе вернется тип <кто-то что-то>EventArgs 

Автор: mr.DUDA 5.12.2006, 22:42
Rustemka, в данном случае я полностью согласен с ANDeath. Задача неразрешима только средствами .NET; придётся привлекать более низкоуровневые вещи, ну а про них я уже выше писал. Кстати, по-другому такие тулзы называются руткитами  smile 

Автор: Rustemka 6.12.2006, 21:23
Я кстати мини програмку написал, но это только для лога за локальными ресурсами, но как вот быть с cd-rom и с "безопасным извлечением" флэшки увы открыт остался вопрос.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)