Сейчас на форуме: bartolomeo, tyns777 (+5 невидимых) |
eXeL@B —› Программирование —› INVALID_KERNEL_HANDLE |
Посл.ответ | Сообщение |
|
Создано: 04 февраля 2011 11:06 · Поправил: ARCHANGEL · Личное сообщение · #1 Привет всем. Пишу драйвер, который периодически закрывает дескрипторы других процессов (типа продвинутого анлокера). Так вот проблема в том, что дескриптор, который ещё мгновенье назад был валидным, может быть закрыт владельцем, или может быть защищён от закрытия, тогда через ZwClose его не закрыть. В этом случае последняя генерит иксепшн, который приводит к бсоду. Более подробно я прочитал ----- Stuck to the plan, always think that we would stand up, never ran. |
Ранг: 419.0 (мудрец), 647thx Активность: 0.46↗0.51 Статус: Участник "Тибериумный реверсинг" |
Создано: 04 февраля 2011 19:39 · Личное сообщение · #2 |
|
Создано: 04 февраля 2011 19:57 · Личное сообщение · #3 |
|
Создано: 04 февраля 2011 21:52 · Личное сообщение · #4 |
|
Создано: 05 февраля 2011 03:01 · Личное сообщение · #5 |
|
Создано: 05 февраля 2011 15:06 · Поправил: Clerk · Личное сообщение · #6 Так как любой процесс может в любой момент времени обратиться к описателю, а манипуляции таблицами хэндлов асинхронны(видимо это ошибка в архитектуре), значит вы должны поставить высокоуровневый фильтр и выполнять синхронизацию. Так как вам не доступны мехонизмы типо морфинга кода в буфер и редиректа треда на него из колбеков и пр., значет используется тупо патч сервисных таблиц(сст). Дальше можно не описывать |
|
Создано: 07 февраля 2011 10:37 · Личное сообщение · #7 Clerk Как показали эксперименты, то ни фильтры, ни перехват здесь не нужны, так как вероятность обратиться к невалидному дескриптору ничтожно мала - ведь анлок нужен для долгосрочно удерживаемых дескрипторов, которые не будут освобождены в произвольный момент времени. Проблему с INVALID_KERNEL_HANDLE удалось решить так – вначале надо вызвать ZwQueryObject, если вернётся STATUS_SUCCESS, то проверяем поле ProtectFromClose, если оно установлено, то сбрасываем вызовом ZwSetInformationObject. Более подробно – исходники. Прикладываю код драйвера и простенького управляющего приложения, выполняющего (по идее они должны выполнять) функции анлокера. Суть в том, что это всё почему-то не работает. Т.е не то, чтоб почему-то – всё совершенно ясно, почему. Ещё Рэм писал в своей статье про 3 метода работы с занятыми файлами, что: «при вызове ZwQueryInformationFile для хэндла открытого именованного канала, (в случае если этот канал работает в блокирующем режиме) вызывающий поток будет ждать поступления сообщения в канал, а это событие может никогда и не произойти.» Здесь нет ZwQueryInformationFile, но ситуация аналогична. Самое интересное, что когда я стал дебажить настоящий анлокер, то он тоже завесился именно на таком именованном канале. Я уже и поток отдельный сделал, который прибивается по таймауту – ничего не помогает. Перепробовал несколько вариантов (там один ещё есть закомментированный – тоже не работает). Теперь подробнее, что же не работает. В общем, почти всё работает – имена объектов получаются, дескрипторы в чужих процессах закрываются, но есть одно но – когда приложение с помощью драйвера пытается получить имя объекта этого долбанного именованного канала, то либо всё приложение, либо вообще система перестают на что-то реагировать. Как быть в такой ситуации? c6f6_06.02.2011_CRACKLAB.rU.tgz - UnlockProject.rar ----- Stuck to the plan, always think that we would stand up, never ran. |
|
Создано: 07 февраля 2011 21:12 · Личное сообщение · #8 ARCHANGEL > надо вызвать ZwQueryObject, если вернётся STATUS_SUCCESS, то проверяем поле ProtectFromClose, если оно установлено, то сбрасываем вызовом ZwSetInformationObject. Более подробно – исходники. Во первых какие есчо исходники, это базовый функционал для работы с описателями. Во вторых ваше решение асинхронно. Тоесть нет никаких гарантий что после валидации описателя он не будет закрыт другим тредом. У вас реально бредовый подход к решениею системных задач. |
|
Создано: 08 февраля 2011 10:06 · Личное сообщение · #9 |
|
Создано: 08 февраля 2011 18:58 · Личное сообщение · #10 ARCHANGEL Давайте логически подумаем. Так как менеджер закрывает описатель асинхронно, значит нужно както синхронизировать, причём не нарушив работу менеджера. Значит нужно получить управление гдето внутри менеджера в процессе закрытия описателя. Тогда можно направить ход исполнения по необходимому пути(control flow.. ?). Само просто видимо поставить колбек на тип(OkayToCloseProcedure). В нём выполнять необходимые действия. Для начала пойдёт. |
|
Создано: 09 февраля 2011 10:08 · Личное сообщение · #11 Clerk lkd> dt _object_type 89e22ca0 nt!_OBJECT_TYPE +0x000 Mutex : _ERESOURCE +0x038 TypeList : _LIST_ENTRY [ 0x89e22cd8 - 0x89e22cd8 ] +0x040 Name +0x048 DefaultObject : (null) +0x04c Index : 5 +0x050 TotalNumberOfObjects : 0x31 +0x054 TotalNumberOfHandles : 0x1e0 +0x058 HighWaterNumberOfObjects : 0x32 +0x05c HighWaterNumberOfHandles : 0x1e4 +0x060 TypeInfo : _OBJECT_TYPE_INITIALIZER +0x0ac Key : 0x636f7250 +0x0b0 ObjectLocks : [4] _ERESOURCE lkd> dt _OBJECT_TYPE_INITIALIZER 89e22ca0+60 nt!_OBJECT_TYPE_INITIALIZER +0x000 Length : 0x4c +0x002 UseDefaultObject : 0 '' +0x003 CaseInsensitive : 0 '' +0x004 InvalidAttributes : 0xb0 +0x008 GenericMapping : _GENERIC_MAPPING +0x018 ValidAccessMask : 0x1f0fff +0x01c SecurityRequired : 0x1 '' +0x01d MaintainHandleCount : 0 '' +0x01e MaintainTypeList : 0 '' +0x020 PoolType : 0 ( NonPagedPool ) +0x024 DefaultPagedPoolCharge : 0x1000 +0x028 DefaultNonPagedPoolCharge : 0x290 +0x02c DumpProcedure : (null) +0x030 OpenProcedure : (null) +0x034 CloseProcedure : (null) +0x038 DeleteProcedure : 0x805d2cd0 +0x03c ParseProcedure : (null) +0x040 SecurityProcedure : 0x805f9144 +0x044 QueryNameProcedure : (null) +0x048 OkayToCloseProcedure : (null) Если я правильно понял, то асинхронно не удаление описателя из таблицы дескрипторов, а удаление самого неиспоьзуемого объекта, т.е. того, на которого уже нет ссылок. Т.е. юзермодная CloseHandle (и соответственно NtClose в ядре) не вернёт управление, пока не удалит (грубо говоря) указатель на объект и не уменьшит через ObpDereferenceObject число ссылок в нём. Но когда число ссылок равно нулю, объект асинхронно удаляется, так? Дизасм NtClose говорит, что где-то так, но это противоречит логике, ведь тогда зачем делать CloseProcedure и OkayToCloseProcedure? И почему вы, Clerk, утверждаете, что юзать надо именно OkayToCloseProcedure? Я хз, как проверить на деле (во время отладки) все эти гипотезы, ибо не смотря на возможную асинхронность (ведь, скорее всего, так и есть, т.к. поля объекта CloseProcedure и OkayToCloseProcedure содержат null), закрытие описателя происходит быстро, и я не могу проверить, было ли оно асинхронно. ----- Stuck to the plan, always think that we would stand up, never ran. |
|
Создано: 09 февраля 2011 19:17 · Поправил: Clerk · Личное сообщение · #12 ARCHANGEL > асинхронно не удаление описателя из таблицы дескрипторов, а удаление самого неиспоьзуемого объекта Асинхронна работа с описателями. Пока один тред его изменяет другой получает предыдущее состояние, что далее ведёт к исключениям и пр. > И почему вы, Clerk, утверждаете, что юзать надо именно OkayToCloseProcedure? Не утверждаю что нужно именно это юзать, просто пример привёл, более того вполне вероятно что этот колбек не подходит(хз до валидации описателя он вызывается или после нужно смореть). Пытаюсь обьяснить саму модель отложенного вызова, что из него вы будите делать не имеет значения(например таже синхронизация). Допустим имеется часть графа, где для удобства макро именовано [i][j][k]. Причём NL(i) > NL(j) > NL(k). Мы получаем управление на j, целевой код k. Нужно както пропустить(выполнить и после этого получить управление) j наиболее эффективным способом, в частности не использовать исключения при переходе к k. Это достигается переключением на отморфленный код(тоесть перемещённый и изменённый), например новый граф [i'][j'][f][k'], i -> i', тогда после прохода j до перехода на k исполнится наш код f. Выбор i зависит от выбранного механизма. |
|
Создано: 10 февраля 2011 11:39 · Личное сообщение · #13 |
|
Создано: 10 февраля 2011 17:32 · Личное сообщение · #14 ARCHANGEL Какой есчо сплайсинг. Я патч рассматриваю как запрещённую манипуляцию, так как целостность модулей нарушается, тоесть образ портится. MS также это рассматривает и борется с этим посредством патчгварда. Забудте про изменение кодосекций. > получить управление после закрытия описателя? Подойдёт любое место в процессе обработки, в частности колбеки и референсы. Я не могу обьяснить проще, чем описал выше. |
|
Создано: 11 февраля 2011 10:13 · Личное сообщение · #15 |
|
Создано: 11 февраля 2011 13:03 · Личное сообщение · #16 |
|
Создано: 11 февраля 2011 13:34 · Личное сообщение · #17 kannabis Конкретно с инвалидными дескрипторами проблема уже решена. В принципе, уже почти решился вопрос с объектами, работа с которыми приводила к зависанию потока, получающего имя объектов. Остался только один вопрос (теоретического характера) - чем конкретно плоха асинхронность работы с описателями? ----- Stuck to the plan, always think that we would stand up, never ran. |
|
Создано: 11 февраля 2011 16:26 · Личное сообщение · #18 |
|
Создано: 11 февраля 2011 16:33 · Личное сообщение · #19 |
|
Создано: 18 марта 2011 10:38 · Личное сообщение · #20 Вот ещё нашёл кодес, может, кому пригодится: Code:
Оригинал вот здесь ----- Stuck to the plan, always think that we would stand up, never ran. |
eXeL@B —› Программирование —› INVALID_KERNEL_HANDLE |