Поводом для создания такой программы стала необходимость определения процессов, имеющих открытые файлы на каком-либо томе.
С помощью замечательной программы IDA программа handle была изучена и написана своя — более простая.
Поскольку очень часто у читателей форума WinAPI возникают вопросы подобные моему, то я решил опубликовать свои изыскания.
Данная программа перечисляет все handle у каждого процесса и если этот handle имеет тип 'File', то для него с помощью драйвера получается имя, которое и выводится на экран.
Программа работает под NT/2K и выше.
В программе приведен код, позволяющий работать с оригинальным драйвером procexp.sys, входящий в замечательную программу ProcessExplorer. http://www.sysinternals.com/ntw2k/freeware/procexp.shtml
Благодаря Кодту обнаружил ошибку в утилите, которой пользуюсь уже почти год.
Оказалось, что запустив утилиту один раз из какого-то каталога нельзя её запустить её из другого.
Возвращаясь к "первоисточнику" обнаружил, что Руссинович совершенно не выгружает драйвер после окончания работы. Об этом красноречиво говорит утилита drivers.exe из DDK.
Собственно он даже не использует функцию NtUnloadDriver.
Причины по которой было сделано так, мне не известны.
В обновленном файле драйвер сначало копируется в SYSTEM32\DRIVERS, загружается и затем удаляется.
Как результат программу можно запускать из разных каталогов.
Единственно, что не хватает для полной аналогии с программой handle от Руссиновича, так это хранение драйвера в ресурсах. Это конечно приятная фича, но мне кажется лишняя.
Ошибка вызванная моей невнимательностью.
У Руссиновича есть функции, в которых он разрешает привелегии.
Они похожи, но все-же слегка разные.
лечится корректировкой следующей строки в функции EnablePrivilege:
// Russinovich code
PrevState.Privileges[0].Attributes |= SE_PRIVILEGE_ENABLED;
на
PrevState.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
код еще не смотрел, но могу сказать одно, что за работу над такими полезными фитчами и освещение оных, особая благодарность.
Во-первых такие фитчи востребованы даже без вопросов. Во-вторых разобрать ее в IDA тоже нужно время, которого как всегда критично мало.
Здравствуйте, MShura, Вы писали:
MS>Здесь лежит собственно программа. MS>http://www.rsdn.ru/File/24534/handle.zip
Блин, трудно собрать. По крайней мере, из батника не получилось. Пришлось сделать проект, но все закончилось тем, что нужен DDK, которого у меня нет.
Здравствуйте, 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>А есть скомпилированный вариант?
Здравствуйте, MShura, Вы писали:
0Z>>А есть скомпилированный вариант?
MS>Этот вариант работает через драйвер hname.sys, который должен лежать рядом с handle.exe. MS>http://www.rsdn.ru/File/24534/handle.exe
Спасибо!
Правда тут консольное приложение, но больше и не надо.
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, MShura, Вы писали:
MS>>Здесь лежит собственно программа. MS>>http://www.rsdn.ru/File/24534/handle.zip
К>Почему-то она у меня работает только, если лежит в каталоге C:\TEMP. К>Может, она куда-то в реестр прописалась тайком?
Драйвер не деинсталлируется полностью.
Прилагаемая программа делает почти все также, как это делает тов. Руссинович, кроме местоположения драйвера.
Он копирует драйвер из ресурсов в каталог SYSTEM32\DRIVERS, оттуда его загружает и удаляет его.
В итоге при запуске его программы из другого места всё повторяется и все работает потому, что местоположение драйвера не меняется.
В моём варианте драйвер ищется из каталога, где лежит exe, поэтому при запуске программы из другого места будет ошибка.
Естественно при перезагрузке все станет нормально.
Если кто поправит я буду рад.
Будет время попробую сам исправить.
Здравствуйте, MShura, Вы писали:
MS>Драйвер не деинсталлируется полностью.
Хм. насколько я помню, можно совершенно безболезненно загружать и выгружать драйвер, без какого-либо копирования его.
Здравствуйте, IceStudent, Вы писали:
IS>Здравствуйте, MShura, Вы писали:
MS>>Драйвер не деинсталлируется полностью. IS>Хм. насколько я помню, можно совершенно безболезненно загружать и выгружать драйвер, без какого-либо копирования его.
IS>Сейчас поищу методику
Раз уж народу понравилось, то сделаю её еще более похожей на программу от Руссиновича.
— Пофикс бага замеченного Odi$$ey под Win2003
— Теперь при сборке драйвер становится ресурсом exe. Откуда он и извлекается в каталог SYSTEM32\DRIVERS
Для маленьких утилит это конечно удобно.
Возможно кто-то обратил внимание, что в коде есть неиспользуемая функция GetObjectNameSimple.
С её помощью можно получить "каноническое" имя объекта по его handle.
При этом драйвер не используется.
К сожалению такой подход не будет работать в основном коде.
Приводит к зависанию на некоторых handle.
Пример использования GetObjectNameSimple в функции wmain.
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
К сожалению, по указанному адресу программы больше нет. Не могли бы Вы ее выслать мылом на lvu собака uaservice точка com точка ua или дать рабочую ссылку?
MS>>Здесь лежит собственно программа. MS>>http://www.rsdn.ru/File/24534/handle.zip
V>К сожалению, по указанному адресу программы больше нет. Не могли бы Вы ее выслать мылом на lvu собака uaservice точка com точка ua или дать рабочую ссылку?
ссылка теперь рабочая.
P.S.
Удалил файл, через несколько месяцев после публикования, чтобы не занимал места на сервере.
Здравствуйте, MShura, Вы писали:
MS>ссылка теперь рабочая.
Огромное спасибо!
MS>P.S. MS>Удалил файл, через несколько месяцев после публикования, чтобы не занимал места на сервере.
Мне кажется, что зря. Я долго искал нечто подобное в сети — эта ветка была единственным результатом.
Кстати. Я пытался сделать нечто похожее, обойдясь user-mode, через CreateRemoteThread. Почти получилось, не смог обработать только процесс System. Верно ли я понимаю, что kernel-mode драйвер нужен именно для него, а из user-mode с ним никак не совладать?
V>Кстати. Я пытался сделать нечто похожее, обойдясь user-mode, через CreateRemoteThread. Почти получилось, не смог обработать только процесс System. Верно ли я понимаю, что kernel-mode драйвер нужен именно для него, а из user-mode с ним никак не совладать?
Никак. Драйвер нужен чтобы преодолеть зависание NtQueryObject на получении имен пайпов, открытых для синхронного доступа и которые имеют pending операции чтения/записи. Все сервисы имеют такие пайпы для коммуникации с SCM.
Здравствуйте, MShura, Вы писали:
MS>Эта программа работает аналогично программе тов Руссиновича handle. MS>http://www.sysinternals.com/ntw2k/freeware/handle.shtml
MS>Поводом для создания такой программы стала необходимость определения процессов, имеющих открытые файлы на каком-либо томе. MS>С помощью замечательной программы IDA программа handle была изучена и написана своя — более простая.
Подход действительно хороший.
В моем коде корень — функция NtQueryObject( ... ObjectNameInformation )
В статье корень — функция NtQueryInformationFile( ... FileNameInformation )
В результате основной недостаток — отсутствие той части полного пути файла, которая указывает на том.
В моей задача, для которой я и исследовал программу Руссиновича, эта часть была необходима.
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
Здравствуйте, 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