![]() |
|
Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply |
![]()
|
|
| Rrader |
|
||||||||||||||
|
Inspired =) ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 1535 Регистрация: 7.5.2005 Репутация: 29 Всего: 191 |
Windows XP SP2. Завершение работы.
Навеяно недавней темой... Решил написать свои мысли и наработки по этому вопросу. При появлении окошка завершения работы определяем, что на экране на самом деле отображаются два главных окна - одно класса #32770 - непосредственно диалог завершения работы, и весьма интересное окошко с именем класса "DimmedWindowClass", которое при вызове команды "Завершение работы" постепенно обесцвечивается. Dim по-английски означает "тусклый" Задаюсь вопросом, а что это за окно такое, и как создается? Чтобы получить наибольшее количество информации об окне в чужом приложении, нужно сделать две вещи: 1) Определить адрес оконной процедуры через инжект (специфика SetWindowLong не позволяет сделать это "мирно" из "чужого" АП); 2) Определить время создания окна - то есть перехватить функцию CreateWindowExA(W). Перехват даст параметры и адрес возврата, куда можно отправиться дизассемблером. explorer.exe написан с использованием Unicode-версий API-функций, поэтому смело можно ставить перехват на CreateWindowExW. Для уверенности можно вызвать IsWindowUnicode для любого окна, созданного процессом, и получить True После контролируемого запуска explorer.exe, отфильтровав логи, обнаруживаем следующую строку:
Более подобных окон explorer не создает. Тут же убеждаемся, что создание идет не напрямую в EXE, а через специальную библиотеку расширения GINA (Graphical Identification and Authentication DLL). Теперь пропускаем все параметры через декодеры стилей и в конечном итоге получаем (Pascal):
Окно имеет нулевого родителя. При создании невидимо. Ширина и высота, Left, Top определяются до этого вызова предварительно через вызовы GetSystemMetrics(SM_CXVIRTUALSCREEN, SM_CYVIRTUALSCREEN, SM_XVIRTUALSCREEN, SM_YVIRTUALSCREEN), но об этом далее. Возвращённый дескриптор $00170254 есть само окно - при каждом показе оно пересоздается, поэтому этот дескриптор нужно получать каждый раз заново для сбора информации. Его можно получить, если создать StayOnTop-форму во время показа окна завершения работы, и вывести информацию об окне "DimmedWindowClass" под курсором мыши. $75940000 - соответственно базовый адрес загрузки (который PEB.ImageBaseAddress) msgina.dll в данном случае. Декодируем стили (нулевые стили опущены) уже в runtime и получаем: Обычные стили: WS_CLIPSIBLINGS or WS_VISIBLE or WS_POPUP or WS_DISABLED; Расширенные стили: WS_EX_TOPMOST; Стили класса: 0; Делаю вывод - стили дополнительно изменяются при показе окна. Настало время получить адрес оконной процедуры окна. Инжект необходимо делать через W-функции, иначе будут возвращаться некорректные значения. Инжект осуществляю следующим образом:
Адрес оконной процедуры: @WndProc = $75967A78; Вернемся к нему позже. У нас есть адрес возврата CreateWindowExW: @Func = $759678D5; Отправляемся по данному адресу в дизассемблере. На предварительном этапе исследования нас не интересует весь листинг функции.
А что это за функция такая в этой библиотеке? Называется она CDimmedWindow::Create Данная функция является внутренней библиотечной функцией класса CDimmedWindow и не экспортируется. Это не конструктор класса. Остаётся лишь подсмотреть, что происходит с окном после создания, а для этого необходимо изучить, как работает оконная процедура.
Здесь есть две новые функции - CDimmedWindow::SetupDim и CDimmedWindow::StepDim. Из названия примерно понятно, для чего они служат, но нужно детально разобраться, как ребята из MS все сделали!
Как видно, здесь идёт идет работа со структурой данных через [esi+0xxh], параметры которой недокументированы. Придется самостоятельно их описать. Займемся этим после изучения работы функции CDimmedWindow::SetupDim. Функция DimPixels, встретившаяся выше, выполняет математические преобразования цветов. Её ассемблерный вариант с адаптацией для Delphi:
|
||||||||||||||
|
|||||||||||||||
| Rrader |
|
||||||||
|
Inspired =) ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 1535 Регистрация: 7.5.2005 Репутация: 29 Всего: 191 |
Мой вольный перевод этой функции на "чистый" Delphi есть в конце этого материала (но и в таком виде она рабочая). Более того, в ассемблерном виде она быстрее работает. Итак, CDimmedWindow::SetupDim:
Вернемся к недокументированной структуре данных, которую адресует регистр esi (указатель на которую передают в CreateWindowExW через последний параметр). Требуется её воссоздать - все безликие смещения заменить на поля. Но назначение полей, названия, их размер и число неизвестны. Придется думать. Поговорим о каждом параметре по порядку. Все выкладки относятся к полностью недокументированной структуре, которой нет даже в отладочных символах. Определение назначения полей структуры при документировании Самая важная и сложная задача - если разобраться с этим, то можно определить названия полей, поскольку становится известным весь алгоритм работы. Основной метод решения - анализ ассемблерных листингов - мы смотрим, где каждое поле фигурирует, в контексте какой функции используется, какие данные в него заносятся и как производится обработка поля (по типу массива, вложенной записи, непосредственно или как-нибудь ещё). Дополнительный метод - анализ содержимого памяти в runtime, создание дампов. Помогает в ситуациях, когда основной метод сложен к применению. Для данного исследования я не применял такой метод. Определение названий полей структуры при документировании Название поля выбирается с учетом выбранной нотации: можно использовать, например, венгерскую нотацию, а можно и не использовать Определение размера и числа полей структуры при документировании Предварительно считаем, что размер всех полей = SizeOf(Pointer). Плюс допускаем, что все структуры упакованы (packed - нет выравнивания). Это работает в большинстве случаев для Windows-структур. Но не всегда, это следует помнить! Поля могут быть и типа Byte, и сложных типов (например, структур или динамических массивов). Может быть и выравнивание, а также неполное использование полей. После таких допущений идет анализ исходных текстов (можно анализировать и память) - ищем обращения к различным полям (т.е. разные смещения), все смещения заносим в таблицу. После этого смотрим на соотношения между смещениями, корректируем результаты (если отличия везде на SizeOf(Pointer), то просто замечательно). Число полей = числу записей в табличке. Вернемся к исследованию. Для полноты картины осталось рассмотреть еще кое-что - конструктор и деструктор класса CDimmedWindow, а также полностью разобрать работу CDimmedWindow::Create. Конструктор:
Деструктор:
CDimmedWindow::Create:
|
||||||||
|
|||||||||
| Rrader |
|
||||||||||
|
Inspired =) ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 1535 Регистрация: 7.5.2005 Репутация: 29 Всего: 191 |
Подводя небольшой итог, можно сказать, что работа всего класса базируется на интересующей нас структуре, адресуемой регистром esi. В этот регистр изначально структура попадает через регистр ecx (еще до передачи в CreateWindowExW). Это означает, что нам нужно произвести дополнительное исследование той функции, которая вызывает функцию CDimmedWindow::Create, на предмет содержимого регистра ecx.
Но до вызова любой функции класса при его объявлении вызывается конструктор класса. Конструирование класса CDimmedWindow осуществляется в двух местах библиотеки одинаковым кодом (не буду слишком углубляться):
Немного погодя идет вызов CDimmedWindow::Create:
Число 40h - количество памяти, которая должна быть выделена. В конструкторе многое прекрасно видно (имею в виду размеры)
Просуммировав все размеры, можно получить 40h. Назовем структуру TDimmedParams. Теперь можно перевести все коды на Delphi, при этом часть действий можно опустить. Делается это последовательно, мы теперь знаем, что и где лежит в структуре, переписываем листинги по аналогии
Пример использования:
Это все. Буду рад услышать любые замечания и критику. Рабочий проект находится в прикреплённом файле. Всем привет Присоединённый файл ( Кол-во скачиваний: 35 )
Attach.rar 11,53 Kb |
||||||||||
|
|||||||||||
| Romikgy |
|
|||
![]() Любитель-программер ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7326 Регистрация: 11.5.2005 Где: Porto Franco Odes sa Репутация: 13 Всего: 146 |
интересная статейка
респект афтору )) вопрос , вся эта движуха дабы реализовать потускнение формы? аль чет другое? -------------------- Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. |
|||
|
||||
| Rrader |
|
|||
|
Inspired =) ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 1535 Регистрация: 7.5.2005 Репутация: 29 Всего: 191 |
||||
|
||||
| Romikgy |
|
|||
![]() Любитель-программер ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7326 Регистрация: 11.5.2005 Где: Porto Franco Odes sa Репутация: 13 Всего: 146 |
а что еще вкусного есть в нем ?
-------------------- Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. |
|||
|
||||
| Rrader |
|
|||
|
Inspired =) ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 1535 Регистрация: 7.5.2005 Репутация: 29 Всего: 191 |
Расширение довольно многофункционально. Здесь лежит старая, но очень известная статья про GINA. Остальная инфа в MSDN. Что важно сейчас:
В Windows 7 так же. Внутренний функционал распределили по другим модулям. А вот список классов msgina.dll из XP SP2:
|
|||
|
||||
![]()
|
| Правила форума "Delphi: WinAPI и системное программирование" | |
|
|
Запрещено: 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |