Сейчас на форуме: tyns777, zds, JustLife, 2nd, morgot, Rio (+5 невидимых)

 eXeL@B —› Программирование —› Как внедрить FormCloseQuery в чужую форму?
Посл.ответ Сообщение


Ранг: 450.3 (мудрец), 13thx
Активность: 0.20
Статус: Участник

Создано: 02 августа 2009 17:24
· Личное сообщение · #1

Создавая форму на Delphi для блокирования закрытия по Alt-F4 я делаю так:

Code:
  1. procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  2. begin
  3. CanClose:=False;
  4. end;


Каким способом можно добавить тоже самое к форме в уже готовом EXE файле? Например подключив свою DLL? Или посоветуйте действенный способ блокировки закрытия по Alt-F4 без патча системных служб, глобального клавиатурного хука или написания драйвера...
Винда XP.




Ранг: 605.2 (!), 341thx
Активность: 0.470.25
Статус: Модератор
Research & Development

Создано: 02 августа 2009 18:47
· Личное сообщение · #2

проще всего хукать оконную процедуру этого exe и обрабатывать сообщение WM_CLOSE (по умолчанию идёт вызов DestroyWindow)
на крайняк можешь и WM_DESTROY ловить

-----
EnJoy!




Ранг: 516.1 (!), 39thx
Активность: 0.280
Статус: Участник

Создано: 02 августа 2009 21:23
· Личное сообщение · #3

попробовать просплайсить CallWindowProc или DefWindowProc на uMsg == WM_CLOSE




Ранг: 673.3 (! !), 400thx
Активность: 0.40.31
Статус: Участник
CyberMonk

Создано: 02 августа 2009 22:27
· Личное сообщение · #4

ToBad если это основная одна прога , то разобрать ее можно и там уже патчить сам запущенный процесс или инжект делать в данный процесс. Есть глава у айсилона Виндовс хукс , там например описаны варианты хука , локальный или глобальный , если ты укажешь ид потока , то хук будет только там где тебе надо. Там даже готовый пример есть. Там уже дело техники ...

-----
RE In Progress [!] Coding Hazard [!] Stay Clear of this Cube




Ранг: 255.8 (наставник), 19thx
Активность: 0.150.01
Статус: Участник
vx

Создано: 02 августа 2009 23:31
· Личное сообщение · #5

> Там уже дело техники ...
apfnDispatch[fnHk*] ?



Ранг: 309.8 (мудрец), 21thx
Активность: 0.170
Статус: Участник

Создано: 03 августа 2009 00:59 · Поправил: SLV
· Личное сообщение · #6

> попробовать просплайсить CallWindowProc или DefWindowProc на uMsg == WM_CLOSE
это делается с инжектом в АП жертвы, далее поиск окна и SetWindowLong (GWL_WNDPROC). Что-то типа:

Code:
  1. LRESULT CALLBACK SpyProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  2. {
  3.          if (message == WM_LBUTTONDOWN)
  4.          {
  5.                  __asm int 3
  6.          }
  7.  
  8.          return oldproc(hWnd, message, wParam, lParam);
  9. }
  10.  
  11. BOOL AlreadyClassed(HWND hwnd)
  12. {
  13.          for (int i=0; i<iWin; i++)
  14.          {
  15.                  if (hWin[i] == hwnd)
  16.                         return TRUE;
  17.          }
  18.  
  19.          return FALSE;
  20. }
  21.  
  22. BOOL CALLBACK EnumWindowsProc(          
  23.          HWND hwnd,
  24.          LPARAM lParam
  25.          )
  26. {
  27.  
  28.          GetWindowThreadProcessId(hwnd, &pid);
  29.          if (hwnd && pid == GetCurrentProcessId())
  30.          {
  31.                  if (!AlreadyClassed(hwnd))
  32.                  {
  33.                         hWin[iWin] = hwnd;
  34.                         oldproc = (DLGPROC)SetWindowLong(hWin[iWin], GWL_WNDPROC, (LONG)&SpyProc);
  35.                         iWin++;
  36.                         return TRUE;
  37.                  }
  38.          }
  39.  
  40.          return TRUE;
  41. }
  42.  
  43.  
  44. void StartKeylogger()
  45. {
  46.          EnumWindows(EnumWindowsProc, 0);
  47. }


-----
Shalom ebanats!




Ранг: 255.8 (наставник), 19thx
Активность: 0.150.01
Статус: Участник
vx

Создано: 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:
  1. --- Ring 0
  2. win32k.xxxDispatchMessage -> win32k.SfnDWORD(gpsi.pfnClient.pfnDispatchMessage = user32.DispatchClientMessage) ->  NT.Ki* ... ->
  3. --- Ring 3
  4. user32.apfnDispatch[fnDWORD = 2] -> user32.fnDWORD(user32.DispatchClientMessage, WndProc) -> user32.DispatchClientMessage(WndProc) -> WndProc

Передаваемая в ядерный калбэк(fnDWORD) структура известна(SMESSAGECALL). В этой структуре определены для обработки указатели на враппер и оконную процедуру, где последняя может заменяться. Обработчик ядерного калбэка заменяется путём захвата таблицы(она перемещается и указатель на неё заменяется в PEB).
> Перемещаем таблицу ядерных калбыков и заменяем указатель на неё в PEB.
> Заменяем обработчик с индексом 2 в этой таблице на свой.
> Наш обработчик заменит указатель(в стеке все) на оконную процедуру, в которой фильтруем сообщение.



Ранг: 4.6 (гость)
Активность: 0=0
Статус: Участник

Создано: 03 августа 2009 23:01
· Личное сообщение · #8

Ещё необходимо написать драйвер р0 для хукания SDT - затем, если нечего делать, можно писать свою ОС как поступил автор ReactOS...




Ранг: 355.4 (мудрец), 55thx
Активность: 0.320
Статус: Uploader
5KRT

Создано: 03 августа 2009 23:16
· Личное сообщение · #9

ггг, зачем вобще драйвер - такие сложности. гораздно просще есть пути

-----
Gutta cavat lapidem. Feci, quod potui. Faciant meliora potentes




Ранг: 255.8 (наставник), 19thx
Активность: 0.150.01
Статус: Участник
vx

Создано: 03 августа 2009 23:22
· Личное сообщение · #10

Я про драйвера разве сказал чтото
А дествия описанные в #7 в юзермоде происходят.



Ранг: 516.1 (!), 39thx
Активность: 0.280
Статус: Участник

Создано: 04 августа 2009 07:21
· Личное сообщение · #11

нафига лезть в такие дебри, ну подумаешь видно в spy++ или там еще где-то, и фиг с ним, очевидно ТС нужно простое и красивое решение не требующее особых затрат




Ранг: 450.3 (мудрец), 13thx
Активность: 0.20
Статус: Участник

Создано: 04 августа 2009 15:34
· Личное сообщение · #12

Большое спасибо всем за ответы! Очень много полезной информации и идей! Видимость в spy++ не проблема, усложнять тоже смысла в этой задаче нет. Сделал так:
1) Через spy++ посмотрел winproc формы и пошагал до попадания в код екзешника. Как понимаю нашёл то, что нужно.
2) Далее в этой функе после передачи параметров и перед вызовом ещё одной функции добавил проверку на WM_CLOSE и его обнуление.
Может не совсем грамотно и красиво, но получилось максимально просто, работает отлично, что и требовалось сделать!
Ещё раз спасибо!




Ранг: 355.4 (мудрец), 55thx
Активность: 0.320
Статус: Uploader
5KRT

Создано: 05 августа 2009 05:57
· Личное сообщение · #13

Clerk
Я про драйвера разве сказал чтото

Я не вам написал, а LoveLab

-----
Gutta cavat lapidem. Feci, quod potui. Faciant meliora potentes



 eXeL@B —› Программирование —› Как внедрить FormCloseQuery в чужую форму?
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати