![]() |
eXeL@B —› Программирование —› Как внедрить FormCloseQuery в чужую форму? |
Посл.ответ | Сообщение |
|
Создано: 02 августа 2009 17:24 · Личное сообщение · #1 Создавая форму на Delphi для блокирования закрытия по Alt-F4 я делаю так: Code:
Каким способом можно добавить тоже самое к форме в уже готовом EXE файле? Например подключив свою DLL? Или посоветуйте действенный способ блокировки закрытия по Alt-F4 без патча системных служб, глобального клавиатурного хука или написания драйвера... Винда XP. ![]() |
|
Создано: 02 августа 2009 18:47 · Личное сообщение · #2 |
|
Создано: 02 августа 2009 21:23 · Личное сообщение · #3 |
|
Создано: 02 августа 2009 22:27 · Личное сообщение · #4 ToBad ![]() ----- RE In Progress [!] Coding Hazard [!] Stay Clear of this Cube ![]() |
|
Создано: 02 августа 2009 23:31 · Личное сообщение · #5 |
|
Создано: 03 августа 2009 00:59 · Поправил: SLV · Личное сообщение · #6 > попробовать просплайсить CallWindowProc или DefWindowProc на uMsg == WM_CLOSE это делается с инжектом в АП жертвы, далее поиск окна и SetWindowLong (GWL_WNDPROC). Что-то типа: Code:
----- Shalom ebanats! ![]() |
|
Создано: 03 августа 2009 20:46 · Поправил: Clerk · Личное сообщение · #7 > это делается с инжектом в АП жертвы, далее поиск окна и SetWindowLong (GWL_WNDPROC). > oldproc = (DLGPROC)SetWindowLong(hWin[iWin], GWL_WNDPROC, (LONG)&SpyProc); Как и сказано в #5, захват таблицы ядерных калбэков. Удалённо вызвать SetWindowLong() нельзя, ибо в ядре проверка текущего процесса. Но можно заменить обработчик посредством замены указателя. Это мощный способ, предложенный выше шелуха(тулзы типо Spy++ покажут всю инфу). Я не реализовал пока, только теоретически. При инициализации системы сервер(csrss) вызывает теневой сервис NtUserInitializeClientPfnArrays(user32.ClientThreadSetup() ->). Этот сервис копирует в ядро три таблицы, которые содержат указатели на обёртки, обрабатывающие соответствующие события. Таблицы устанавливаются однократно и только подсистемой. Адреса обработчиков глобальны в системе. Таблицы находится в переменной ядра(gpsi(.pfnClientA/W):SERVERINFO). При определённых событиях поток возвращается в юзермод, для обработки этого события(KeUserModeCallback/KiUserCallbackDispatcher). С каждым типом события связан обработчик в таблице apfnDispatch(PEB.KernelCallbackTable). Для ядерного калбэка адрес обработчика определяется его индексом, собственно это хорошо описано(и захват этой таблицы также). Нас интересует калбэк с индексом 2, носящий имя fnDWORD. Он является является враппером для некоторых функций, которые определены в таблице gpsi ядра. Оконную процедуру вызывает user32.DispatchClientMessage(), эта функция определена в таблице gpsi и передаётся в ядерный калбэк параметром, последний передаёт на неё управление, а он в свою очередь передаёт управление на оконную процедуру, тоесть цепочка: Code:
Передаваемая в ядерный калбэк(fnDWORD) структура известна(SMESSAGECALL). В этой структуре определены для обработки указатели на враппер и оконную процедуру, где последняя может заменяться. Обработчик ядерного калбэка заменяется путём захвата таблицы(она перемещается и указатель на неё заменяется в PEB). > Перемещаем таблицу ядерных калбыков и заменяем указатель на неё в PEB. > Заменяем обработчик с индексом 2 в этой таблице на свой. > Наш обработчик заменит указатель(в стеке все) на оконную процедуру, в которой фильтруем сообщение. ![]() |
|
Создано: 03 августа 2009 23:01 · Личное сообщение · #8 |
|
Создано: 03 августа 2009 23:16 · Личное сообщение · #9 |
|
Создано: 03 августа 2009 23:22 · Личное сообщение · #10 |
|
Создано: 04 августа 2009 07:21 · Личное сообщение · #11 |
|
Создано: 04 августа 2009 15:34 · Личное сообщение · #12 Большое спасибо всем за ответы! Очень много полезной информации и идей! Видимость в spy++ не проблема, усложнять тоже смысла в этой задаче нет. Сделал так: 1) Через spy++ посмотрел winproc формы и пошагал до попадания в код екзешника. Как понимаю нашёл то, что нужно. 2) Далее в этой функе после передачи параметров и перед вызовом ещё одной функции добавил проверку на WM_CLOSE и его обнуление. Может не совсем грамотно и красиво, но получилось максимально просто, работает отлично, что и требовалось сделать! Ещё раз спасибо! ![]() |
|
Создано: 05 августа 2009 05:57 · Личное сообщение · #13 |
![]() |
eXeL@B —› Программирование —› Как внедрить FormCloseQuery в чужую форму? |