Перечисление открытых объектов типа 'File'
От: MShura  
Дата: 21.04.05 12:43
Оценка: 184 (17)
Эта программа работает аналогично программе тов Руссиновича handle.
http://www.sysinternals.com/ntw2k/freeware/handle.shtml

Поводом для создания такой программы стала необходимость определения процессов, имеющих открытые файлы на каком-либо томе.
С помощью замечательной программы IDA программа handle была изучена и написана своя — более простая.

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

Данная программа перечисляет все handle у каждого процесса и если этот handle имеет тип 'File', то для него с помощью драйвера получается имя, которое и выводится на экран.

Программа работает под NT/2K и выше.
В программе приведен код, позволяющий работать с оригинальным драйвером procexp.sys, входящий в замечательную программу ProcessExplorer.
http://www.sysinternals.com/ntw2k/freeware/procexp.shtml

Здесь лежит собственно программа.
http://www.rsdn.ru/File/24534/handle.zip
Re: Перечисление открытых объектов типа 'File'
От: MShura  
Дата: 21.04.05 20:19
Оценка: 23 (1)
Благодаря Кодту обнаружил ошибку в утилите, которой пользуюсь уже почти год.
Оказалось, что запустив утилиту один раз из какого-то каталога нельзя её запустить её из другого.

Возвращаясь к "первоисточнику" обнаружил, что Руссинович совершенно не выгружает драйвер после окончания работы. Об этом красноречиво говорит утилита drivers.exe из DDK.
Собственно он даже не использует функцию NtUnloadDriver.

Причины по которой было сделано так, мне не известны.
В обновленном файле драйвер сначало копируется в SYSTEM32\DRIVERS, загружается и затем удаляется.
Как результат программу можно запускать из разных каталогов.
Единственно, что не хватает для полной аналогии с программой handle от Руссиновича, так это хранение драйвера в ресурсах. Это конечно приятная фича, но мне кажется лишняя.

Обновил файл handle.c
http://www.rsdn.ru/File/24534/handle.zip
Re[3]: Перечисление открытых объектов типа 'File'
От: MShura  
Дата: 22.04.05 09:43
Оценка: 22 (1)
OE>

OE>Can't load driver "hname": "Access is denied."


OE>win2003, права админиcтратора.


Ошибка вызванная моей невнимательностью.
У Руссиновича есть функции, в которых он разрешает привелегии.
Они похожи, но все-же слегка разные.
лечится корректировкой следующей строки в функции EnablePrivilege:
// Russinovich code
PrevState.Privileges[0].Attributes |= SE_PRIVILEGE_ENABLED;
на
PrevState.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
Re: Перечисление открытых объектов типа 'File'
От: Alexmoon Украина  
Дата: 21.04.05 13:25
Оценка:
Здравствуйте, MShura, Вы писали:

MS>Здесь лежит собственно программа.

MS>http://www.rsdn.ru/File/24534/handle.zip

код еще не смотрел, но могу сказать одно, что за работу над такими полезными фитчами и освещение оных, особая благодарность.
Во-первых такие фитчи востребованы даже без вопросов. Во-вторых разобрать ее в IDA тоже нужно время, которого как всегда критично мало.
Re: Перечисление открытых объектов типа 'File'
От: 0Z Россия http://www.ucca.ru
Дата: 21.04.05 13:27
Оценка:
Здравствуйте, MShura, Вы писали:

MS>Здесь лежит собственно программа.

MS>http://www.rsdn.ru/File/24534/handle.zip
Блин, трудно собрать. По крайней мере, из батника не получилось. Пришлось сделать проект, но все закончилось тем, что нужен DDK, которого у меня нет.

А есть скомпилированный вариант?
MCSD.NET http://www.stdevlab.com... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Re[2]: Перечисление открытых объектов типа 'File'
От: MShura  
Дата: 21.04.05 13:44
Оценка:
Здравствуйте, 0Z, Вы писали:

0Z>Здравствуйте, MShura, Вы писали:


MS>>Здесь лежит собственно программа.

MS>>http://www.rsdn.ru/File/24534/handle.zip
0Z>Блин, трудно собрать. По крайней мере, из батника не получилось. Пришлось сделать проект, но все закончилось тем, что нужен DDK, которого у меня нет.

DDK нужен чтобы собрать hname.sys.
Поскольку DDK есть не у всех, то я приложил готовый бинарник драйвера.
Желающие могут собрать handle.sys сами.

В проекте handle.exe только один файл: handle.c

Возможно у тебя не настроены переменные окружения. PATH,INCLUDE,LIB
Для того, чтобы собрать вставь в начало build.bat строку
call %Путь к студии%\Vc98\Bin\vcvars32.bat

0Z>А есть скомпилированный вариант?


Этот вариант работает через драйвер hname.sys, который должен лежать рядом с handle.exe.
http://www.rsdn.ru/File/24534/handle.exe
Re[3]: Перечисление открытых объектов типа 'File'
От: 0Z Россия http://www.ucca.ru
Дата: 21.04.05 14:13
Оценка:
Здравствуйте, MShura, Вы писали:

0Z>>А есть скомпилированный вариант?


MS>Этот вариант работает через драйвер hname.sys, который должен лежать рядом с handle.exe.

MS>http://www.rsdn.ru/File/24534/handle.exe
Спасибо!
Правда тут консольное приложение, но больше и не надо.
MCSD.NET http://www.stdevlab.com... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Re: Перечисление открытых объектов типа 'File'
От: Кодт Россия  
Дата: 21.04.05 15:47
Оценка:
Здравствуйте, MShura, Вы писали:

MS>Здесь лежит собственно программа.

MS>http://www.rsdn.ru/File/24534/handle.zip

Почему-то она у меня работает только, если лежит в каталоге C:\TEMP.
Может, она куда-то в реестр прописалась тайком?
Перекуём баги на фичи!
Re[2]: Перечисление открытых объектов типа 'File'
От: MShura  
Дата: 21.04.05 17:07
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, MShura, Вы писали:


MS>>Здесь лежит собственно программа.

MS>>http://www.rsdn.ru/File/24534/handle.zip

К>Почему-то она у меня работает только, если лежит в каталоге C:\TEMP.

К>Может, она куда-то в реестр прописалась тайком?

Драйвер не деинсталлируется полностью.
Прилагаемая программа делает почти все также, как это делает тов. Руссинович, кроме местоположения драйвера.
Он копирует драйвер из ресурсов в каталог SYSTEM32\DRIVERS, оттуда его загружает и удаляет его.
В итоге при запуске его программы из другого места всё повторяется и все работает потому, что местоположение драйвера не меняется.
В моём варианте драйвер ищется из каталога, где лежит exe, поэтому при запуске программы из другого места будет ошибка.
Естественно при перезагрузке все станет нормально.


Если кто поправит я буду рад.
Будет время попробую сам исправить.
Re[3]: Перечисление открытых объектов типа 'File'
От: IceStudent Украина  
Дата: 21.04.05 19:15
Оценка:
Здравствуйте, MShura, Вы писали:

MS>Драйвер не деинсталлируется полностью.

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

Сейчас поищу методику
С наилучшими пожеланиями, IceStudent << RSDN@Home 1.1.4 beta 5 rev. 409>>
Re[4]: Перечисление открытых объектов типа 'File'
От: MShura  
Дата: 21.04.05 20:20
Оценка:
Здравствуйте, IceStudent, Вы писали:

IS>Здравствуйте, MShura, Вы писали:


MS>>Драйвер не деинсталлируется полностью.

IS>Хм. насколько я помню, можно совершенно безболезненно загружать и выгружать драйвер, без какого-либо копирования его.

IS>Сейчас поищу методику


Ключевое слово: instdrv.c
Re[4]: Перечисление открытых объектов типа 'File'
От: IceStudent Украина  
Дата: 21.04.05 20:31
Оценка:
Здравствуйте, IceStudent

Посмотрел код. Интересный.

А вот примерный код загрузки драйвера.

BOOL LoadOurDriver(LPWSTR szDrvFileName,LPWSTR szDrvName,LPWSTR szDrvDescription)
{
    HANDLE hSCManager;
    HANDLE hService;
    WCHAR acDriverPath[MAX_PATH];
    LPWSTR szfPart;

    HKEY hKey;

    BOOL fOK = 0; // Предположим, что произойдет ошибка

    // Открываем базу данных SCM

    hSCManager = OpenSCManagerW(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
    if(hSCManager){
        GetFullPathNameW(szDrvFileName,MAX_PATH,acDriverPath, &szfPart);

        // Регистрируем драйвер

        hService = CreateService(hSCManager, szDrvName, szDrvDescription,
            SERVICE_START | DELETE, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, 
            SERVICE_ERROR_IGNORE, acDriverPath, NULL, NULL, NULL, NULL, NULL);

        if(hService){
            WCHAR szDriverRegPath[MAX_PATH];
            szDriverRegPath[0] = 0;
            wsprintfW(szDriverRegPath,L"SYSTEM\\CurrentControlSet\\Services\\%s",szDrvName);

            fOK = StartService(hService, 0, NULL);

            // Удаляем драйвер из базы данных SCM
            DeleteService(hService);
            CloseServiceHandle(hService);
        }else{
            MessageBox(NULL,L"Can't register driver.", NULL, MB_ICONSTOP);
        }
        CloseServiceHandle(hSCManager);
    }else{
        MessageBox(NULL, L"Can't connect to Service Control Manager.",NULL, MB_ICONSTOP);
    }
    return fOK;
}
С наилучшими пожеланиями, IceStudent << RSDN@Home 1.1.4 beta 5 rev. 409>>
Re[5]: Перечисление открытых объектов типа 'File'
От: IceStudent Украина  
Дата: 21.04.05 20:48
Оценка:
Здравствуйте, MShura, Вы писали:

MS>Ключевое слово: instdrv.c

Не нашёл такого. Что там, NtLoadDriver? или реализация StartService?
С наилучшими пожеланиями, IceStudent << RSDN@Home 1.1.4 beta 5 rev. 409>>
Re[2]: Перечисление открытых объектов типа 'File'
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 22.04.05 03:58
Оценка:
Здравствуйте, MShura, Вы писали:

MS>Обновил файл handle.c

MS>http://www.rsdn.ru/File/24534/handle.zip

скомпилил, запустил:

Can't load driver "hname": "Access is denied."


win2003, права админиcтратора.
... << RSDN@Home 1.1.4 beta 6 rev. 422>>
Re: Перечисление открытых объектов типа 'File'
От: MShura  
Дата: 22.04.05 10:14
Оценка:
MS>Здесь лежит собственно программа.
MS>http://www.rsdn.ru/File/24534/handle.zip

Раз уж народу понравилось, то сделаю её еще более похожей на программу от Руссиновича.
— Пофикс бага замеченного Odi$$ey под Win2003
— Теперь при сборке драйвер становится ресурсом exe. Откуда он и извлекается в каталог SYSTEM32\DRIVERS
Для маленьких утилит это конечно удобно.


Возможно кто-то обратил внимание, что в коде есть неиспользуемая функция GetObjectNameSimple.
С её помощью можно получить "каноническое" имя объекта по его handle.
При этом драйвер не используется.
К сожалению такой подход не будет работать в основном коде.
Приводит к зависанию на некоторых handle.
Пример использования GetObjectNameSimple в функции wmain.
Re[4]: Перечисление открытых объектов типа 'File'
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 22.04.05 10:48
Оценка:
Здравствуйте, MShura, Вы писали:

MS>лечится корректировкой следующей строки в функции EnablePrivilege:

MS> // Russinovich code
MS> PrevState.Privileges[0].Attributes |= SE_PRIVILEGE_ENABLED;
MS>на
MS> PrevState.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

ага, помогло
... << RSDN@Home 1.1.4 beta 6 rev. 431>>
Re[2]: Перечисление открытых объектов типа 'File'
От: vlad.k.sm  
Дата: 03.06.05 08:20
Оценка:
Здравствуйте, MShura, Вы писали:



MS>>Здесь лежит собственно программа.

MS>>http://www.rsdn.ru/File/24534/handle.zip

MS>Раз уж народу понравилось, то сделаю её еще более похожей на программу от Руссиновича.

MS>- Пофикс бага замеченного Odi$$ey под Win2003
MS>- Теперь при сборке драйвер становится ресурсом exe. Откуда он и извлекается в каталог SYSTEM32\DRIVERS
MS> Для маленьких утилит это конечно удобно.


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

MS>С её помощью можно получить "каноническое" имя объекта по его handle.
MS>При этом драйвер не используется.
MS>К сожалению такой подход не будет работать в основном коде.
MS>Приводит к зависанию на некоторых handle.
MS>Пример использования GetObjectNameSimple в функции wmain.

В коде встерчается функция "ExtactFile", я так понимаю хотелось ExtractFile
Re: Перечисление открытых объектов типа 'File'
От: vlavrinenko  
Дата: 24.01.06 10:25
Оценка:
Здравствуйте, MShura, Вы писали:

MS>Эта программа работает аналогично программе тов Руссиновича handle.

MS>http://www.sysinternals.com/ntw2k/freeware/handle.shtml
[...]
MS>Здесь лежит собственно программа.
MS>http://www.rsdn.ru/File/24534/handle.zip

К сожалению, по указанному адресу программы больше нет. Не могли бы Вы ее выслать мылом на lvu собака uaservice точка com точка ua или дать рабочую ссылку?
Re[2]: Перечисление открытых объектов типа 'File'
От: MShura  
Дата: 24.01.06 12:45
Оценка:
MS>>Здесь лежит собственно программа.
MS>>http://www.rsdn.ru/File/24534/handle.zip

V>К сожалению, по указанному адресу программы больше нет. Не могли бы Вы ее выслать мылом на lvu собака uaservice точка com точка ua или дать рабочую ссылку?


ссылка теперь рабочая.

P.S.
Удалил файл, через несколько месяцев после публикования, чтобы не занимал места на сервере.
Re[3]: Перечисление открытых объектов типа 'File'
От: vlavrinenko  
Дата: 24.01.06 13:04
Оценка:
Здравствуйте, MShura, Вы писали:

MS>ссылка теперь рабочая.


Огромное спасибо!

MS>P.S.

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

Мне кажется, что зря. Я долго искал нечто подобное в сети — эта ветка была единственным результатом.

Кстати. Я пытался сделать нечто похожее, обойдясь user-mode, через CreateRemoteThread. Почти получилось, не смог обработать только процесс System. Верно ли я понимаю, что kernel-mode драйвер нужен именно для него, а из user-mode с ним никак не совладать?
Re[4]: Перечисление открытых объектов типа 'File'
От: MShura  
Дата: 24.01.06 13:42
Оценка:
V>Кстати. Я пытался сделать нечто похожее, обойдясь user-mode, через CreateRemoteThread. Почти получилось, не смог обработать только процесс System. Верно ли я понимаю, что kernel-mode драйвер нужен именно для него, а из user-mode с ним никак не совладать?

Никак. Драйвер нужен чтобы преодолеть зависание NtQueryObject на получении имен пайпов, открытых для синхронного доступа и которые имеют pending операции чтения/записи. Все сервисы имеют такие пайпы для коммуникации с SCM.
Re: Перечисление открытых объектов типа 'File'
От: EqWu Россия  
Дата: 25.01.06 16:13
Оценка:
Здравствуйте, MShura, Вы писали:

MS>Эта программа работает аналогично программе тов Руссиновича handle.

MS>http://www.sysinternals.com/ntw2k/freeware/handle.shtml

MS>Поводом для создания такой программы стала необходимость определения процессов, имеющих открытые файлы на каком-либо томе.

MS>С помощью замечательной программы IDA программа handle была изучена и написана своя — более простая.

А такой метод не кактит?
http://wasm.ru/article.php?article=lockfileswork
Re[2]: Перечисление открытых объектов типа 'File'
От: MShura  
Дата: 25.01.06 18:03
Оценка:
EW>А такой метод не кактит?
EW>http://wasm.ru/article.php?article=lockfileswork

Подход действительно хороший.
В моем коде корень — функция NtQueryObject( ... ObjectNameInformation )
В статье корень — функция NtQueryInformationFile( ... FileNameInformation )

В результате основной недостаток — отсутствие той части полного пути файла, которая указывает на том.
В моей задача, для которой я и исследовал программу Руссиновича, эта часть была необходима.
Re[5]: Перечисление открытых объектов типа 'File'
От: gear nuke  
Дата: 03.03.06 20:49
Оценка:
Здравствуйте, IceStudent, Вы писали:

IS>А вот примерный код загрузки драйвера.


IS>
[]
IS>        GetFullPathNameW(szDrvFileName,MAX_PATH,acDriverPath, &szfPart);

IS>        // Регистрируем драйвер

IS>        hService = CreateService(hSCManager, szDrvName, szDrvDescription,
IS>            SERVICE_START | DELETE, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, 
IS>            SERVICE_ERROR_IGNORE, acDriverPath, NULL, NULL, NULL, NULL, NULL);
[]

В этом коде есть ошибка.
MSDN:

CreateService
[...]
lpBinaryPathName
[in] Pointer to a null-terminated string that contains the fully qualified path to the service binary file. If the path contains a space, it must be quoted so that it is correctly interpreted. For example, "d:\\my share\\myservice.exe" should be specified as "\"d:\\my share\\myservice.exe\"".
The path can also include arguments for an auto-start service. For example, "d:\\myshare\\myservice.exe arg1 arg2". These arguments are passed to the service entry point (typically the main function).

People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re: Перечисление открытых объектов типа 'File'
От: MShura  
Дата: 28.12.06 17:42
Оценка:
Исправлена ошибка в драйвере. Посыпаю голову пеплом. Теперь работает и под Vista.


MS>Здесь лежит собственно программа.

MS>http://www.rsdn.ru/File/24534/handle.zip
Re[2]: Перечисление открытых объектов типа 'File'
От: swiss2  
Дата: 14.01.07 20:01
Оценка:
Здравствуйте, MShura, Вы писали:

MS>Возвращаясь к "первоисточнику" обнаружил, что Руссинович совершенно не выгружает драйвер после окончания работы. Об этом красноречиво говорит утилита drivers.exe из DDK.

MS>Собственно он даже не использует функцию NtUnloadDriver.

MS>Причины по которой было сделано так, мне не известны.


Для handle они мне тоже не известны, но по крайней мере для regmon'а 4.35 Руссинович пояснил:

regsys.c

#if DBG

        //
        // Its extremely unsafe to unload a system-call hooker, so this
        // is only enabled in the debug version for testing purposes.
        //
        DriverObject->DriverUnload                          = RegmonUnload;
#endif
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.