Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2004.12.05;
Скачать: [xml.tar.bz2];

Вниз

Hook на всё   Найти похожие ветки 

 
#Мастер#   (2004-10-17 18:31) [0]

Привет всем мастерам! Подскажите, как поставть Hook на клавиатуру и на мышь? Можно ли поставить Hook на запуск программ, процессов. Извините за ламерство...


 
SammIk ©   (2004-10-17 19:27) [1]

Можно


 
AlexKocharin ©   (2004-10-17 19:52) [2]

Hook на клаву и мышь:

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;

type
 TForm1 = class(TForm)
   CheckBox1: TCheckBox;
   CheckBox2: TCheckBox;
   CheckBox3: TCheckBox;
   Edit1: TEdit;
   procedure FormCreate(Sender: TObject);
   procedure FormDestroy(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

const
 MyHotKey = ord(" ");

var
 Form1: TForm1;

implementation

{$R *.dfm}

var
 HookHandle: hHook;

function HookProc(Code: integer; WParam: word; LParam: Longint): Longint; stdcall;
var
 msg: PEVENTMSG;
 key: integer;
begin
 if Code >= 0 then begin
   result := 0;
   msg := Pointer(LParam);
   with Form1 do
     case msg.message of
       WM_MOUSEMOVE: Caption := IntToStr(msg.ParamL) + #32 + IntToStr(msg.ParamH);
       WM_LBUTTONDOWN: CheckBox1.Checked := true;
       WM_LBUTTONUP: CheckBox1.Checked := false;
       WM_RBUTTONDOWN: CheckBox2.Checked := true;
       WM_RBUTTONUP: CheckBox2.Checked := false;
       WM_KEYUP: CheckBox3.Checked := false;
       WM_KEYDOWN: begin
         CheckBox3.Checked := true;
         key := msg.paramL and 255;
         if key in [48..57, 65..90]
           then Edit1.Text := Edit1.Text + chr(key);
       end;
     end;
 end else
   result := CallNextHookEx(HookHandle, code, WParam, LParam);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
 //Form1.FormStyle := fsStayOnTop;
 CheckBox1.Enabled := false;
 CheckBox1.Caption := "left button";
 CheckBox2.Enabled := false;
 CheckBox2.Caption := "right button";
 CheckBox3.Enabled := false;
 CheckBox3.Caption := "keyboard";
 HookHandle := SetWindowsHookEx(WH_JOURNALRECORD, @HookProc, HInstance, 0);
 Edit1.Text := "";
 Edit1.Enabled := false;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
 if HookHandle > 0 then
   UnhookWindowsHookEx(HookHandle);
end;

end.


 
#Мастер#   (2004-10-19 14:39) [3]

SammIk, каким образом?


 
AlexKocharin ©   (2004-10-20 22:26) [4]

Hook на запуск программ и процессов, вроде, поставить нельзя.


 
DeadMeat ©   (2004-10-21 00:48) [5]

Хук можно только на создание (или появление... точно не помню) окон.
А создание процессов надо ловить... На это есть два способа.
Один через реестр (не надежный)
Другой через перехват CreateProcess (WinExec, ShellExecute)

---
...Death Is Only The Begining...


 
DeadMeat ©   (2004-10-21 00:48) [6]

Забыл добавить, что мне известны только два способа... т.е. ИМХО это все...

---
...Death Is Only The Begining...


 
Digitman ©   (2004-10-21 08:17) [7]


> #Мастер#


с пом. ф-ции PsSetCreateProcessNotifyRoutine можно получать нотификации о старте/завершении процессов, но работать она будет только на НТ-платформе и только в контексте драйвера режима ядра.

пример простейшего драйвера и оболочки к нему есть на wasm.ru


 
SammIk ©   (2004-10-21 13:11) [8]

[7] не мучте его пока))
Пока перехватывай ф-ю CreateProcessA(W - для NT) Поскольку все к ним.


 
Digitman ©   (2004-10-21 14:23) [9]


> SammIk ©   (21.10.04 13:11) [8]


для этого нужно знать  момент старта процесса, потенциально способного вызвать CreateProcess

парадокс Мюнхгаузена ...


 
SammIk ©   (2004-10-22 07:04) [10]

2 [9]
Не понял, разьясни


 
Digitman ©   (2004-10-22 08:27) [11]


> SammIk ©   (22.10.04 07:04) [10]
> Не понял, разьясни


ну перехват-то ты должен осуществить во всех работающих процессах !

предположим, в некий момент времени ты перечислил все активные процессы и внедрил в их ВАП код, перехватывающий CreateProcess()

а как же вновь стартующие после этого процессы ? ведь они вполне м.б. стартованы не с пом. CreateProcess(), а иными способами (с пом. WinExec, ShellExecute, ole/com/com+ механизма) !


 
SammIk ©   (2004-10-22 08:34) [12]

Дык на то и перехватываем эту ф-ю, дабы смотреть что стартует.
Запускаем процесс(с флагом преостаноки), а после загрузки патчим и его, потом резумаем.
Такое ведь тоже можно))
А все эти вызова сходятся к CreateProcessW(WinExec,ShellExecute, ole/com/com+ механизма).
Который в свою очередь вызывает NtCreateProcess, которую впринципе и надо хватать))


 
Digitman ©   (2004-10-22 08:58) [13]


> Запускаем процесс(с флагом преостаноки), а после загрузки
> патчим и его, потом резумаем.
> Такое ведь тоже можно))


и что ты будешь "патчить", если в ВАП процесса, запущенного тобой с флагом CREATE_SUSPENDED, на этот момент еще не загружен образ модуля kernel32 ? kernel32.EAT еще не загружена, callingprocess.IAT еще не настроена, потому что не загружена kernel32.EAT ..


 
SammIk ©   (2004-10-22 09:05) [14]

Серьезно?
Надо проверить, я в этом не уверенн.


 
Digitman ©   (2004-10-22 09:37) [15]


> SammIk ©   (22.10.04 09:05) [14]


> Надо проверить


проверь.
но лучше все же не заниматься ерундой, а использовать kernel mode driver, задействующий предназначенный как раз для этой цели сист.механизм в виде PsSetCreateProcessNotifyRoutine()

вот пример оболочки к простейшему одноуровневому драйверу (исх.текст драйвера и готовый sys-файл доступны в кач-ве примера на wasm.ru)
оболочка при посредничестве драйвера отслеживает старт/завершение некоего интересующего процесса



 PWaitParams = ^TWaitParams;
 TWaitParams = packed record
   hEvent: THandle; //сигналящее событие
   hDevice: THandle; //дивайс, передающий нам инф-цию о старте/завершении процессов
   ExitNow: Boolean; //флаг, предписывающий немедленное завершение следящего за событиями трэда
   CallbackFunc: TNotifyProcessEvent; //ф-ция, вызываемая при наступлении ожидаемого нами события
 end;

//структура, возвращаемая драйвером по запросу оболочки
 PProcessData = ^TProcessData;
 TProcessData = packed record
  Create: LongBool; //True - старт, False - завершение процесса
  ProcessId: DWord; //ид-р процесса
  ProcessName: array[0..511] of Char; //полное имя процесса, включая путь к его исп.файлу
 end;

 TNotifyProcessEvent = procedure(ProcessId: DWord; Created: Boolean);

//эта ф-ция вызывается всякий раз, когда стартует/завершается интересующий процесс
procedure EtkaProcessEvent(ProcessId: DWord; Created: Boolean);
begin
//если интересующий процесс стартовал
 if Created then
   InjectLibrary(ProcessId, InjectLibDir + "\" + sInjectLibName); //немедленно внедрим в его ВАП свой модуль
end;

//следящий трэд
function WinEtkaWatchDog(Params: PWaitParams): Integer;
var
 pd: PProcessData;
 len: DWord;
begin
//приоритет трэда д.б. наивысшим для немедленной реакции на событие
 SetThreadPriority(GetCurrentThread, THREAD_PRIORITY_HIGHEST);
 try
   New(pd);
   with Params^, pd^ do
   try
//известим о факте уже работающего интересующего нас процесса
на момент активации мониторинга      
     ProcessId := FindProcess(ExtractFileName(WinEtkaProcessName));
     if ProcessId <> 0 then
       CallbackFunc(ProcessId, Create);
//ждем событий, о которых просигналит драйвер
     while (WaitForSingleObject(hEvent, INFINITE) <> WAIT_FAILED) do
//если был сигнал на завершение трэда
//или драйвер не вернул инф-цию о событии старта/завершения некоего процесса
       if ExitNow or not DeviceIoControl(hDevice,
                                         IOCTL_GET_PROCESS_DATA,
                                         nil, 0,
                                         pd, SizeOf(pd^),
                                         len, nil) then
//закругляемся
         Break
       else
         begin
//это интересующий нас процесс ?
           if stricomp(@pd^.ProcessName[0], PChar(WinEtkaProcessName)) = 0 then
             CallbackFunc(ProcessId, Create);
         end;

   finally
     Dispose(pd);
   end;
 except
 end;
end;

//старт системы мониторинга
procedure StartMonitor;
var
 hSCM, hService: THandle;
 idThread, BytesReturned: DWord;
 State: TServiceStatus;
begin
 if Started then Exit;
//проверим, существует ли файл драйвера по заданному пути
//если не существует, запишем его туда, извлекая его образ, например, из ресурса данного приложения
 CheckDriverExists;
 hSCM := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
 Win32Check(hSCM <> 0);
 try
   hService := CreateService(hSCM, "ProcessMon", "NT process Montor",
                             SERVICE_START or SERVICE_STOP or _DELETE,
                             SERVICE_KERNEL_DRIVER,
                             SERVICE_DEMAND_START,
                             SERVICE_ERROR_IGNORE,
                             PChar(DrvName),
                             nil, nil, nil, nil, nil);
   Win32Check(hService <> 0);
   try
     Win32Check(StartService(hService, 0, SvcStartParams));
     with WaitParams do
     try
       hDevice := CreateFile(sDeviceName,
                             GENERIC_READ or GENERIC_WRITE,
                             0, nil, OPEN_EXISTING, 0, 0);
       Win32Check(hDevice <> 0);
       try
         hEvent := CreateEvent(nil, FALSE, FALSE, nil);
         Win32Check(hEvent <> 0);
         try
           ExitNow := False;
           WaitParams.CallbackFunc := @EtkaProcessEvent;
//стартуем следящий трэд
           hWaitThread := BeginThread(nil, 0, @WinEtkaWatchDog, @WaitParams, 0, idThread);
           Win32Check(hWaitThread <> 0);
           try
//активизируем подсистему слежения
             Win32Check(DeviceIoControl(hDevice,
                                         IOCTL_SET_NOTIFY,
                                         @hEvent,
                                         SizeOf(hEvent), nil, 0, BytesReturned, nil)
                       );
             Started := True;
           except
             ExitNow := True;
             SetEvent(hEvent);
             WaitForSingleObject(hWaitThread, INFINITE);
             CloseHandle(hWaitThread);
             raise;
           end;
         except
           CloseHandle(hEvent);
           raise;
         end;
       except
         CloseHandle(hDevice);
         raise;
       end;
     except
       ControlService(hService, SERVICE_CONTROL_STOP, State);
       raise;
     end;
   finally
     DeleteService(hService);
     CloseServiceHandle(hService);
   end;
 finally
   CloseServiceHandle(hSCM);
 end;
end;

//стоп системы мониторинга
procedure StopMonitor;
var
 hSCM, hService: THandle;
 BytesReturned: DWord;
 State: TServiceStatus;
begin
 if Started then
   with WaitParams do
   begin
     ExitNow := True;
     SetEvent(hEvent);
     WaitForSingleObject(hWaitThread, INFINITE);
     CloseHandle(hWaitThread);
     Win32Check(DeviceIoControl(hDevice, IOCTL_REMOVE_NOTIFY, nil, 0, nil, 0, BytesReturned, nil));
     CloseHandle(hEvent);
     CloseHandle(hDevice);
     hSCM := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
     hService := OpenService(hSCM, "ProcessMon", SERVICE_STOP or _DELETE);
     ControlService(hService, SERVICE_CONTROL_STOP, State);
     DeleteService(hService);
     CloseServiceHandle(hService);
     CloseServiceHandle(hSCM);
     Started := False;
   end;
end;


 
SammIk ©   (2004-10-22 10:44) [16]

Гы, базару нет.
Самый класный способ))



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2004.12.05;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.037 c
1-1100686685
Ascan
2004-11-17 13:18
2004.12.05
Отмена переноса слов по "-" в TWebBrowser


14-1100534252
Drakon
2004-11-15 18:57
2004.12.05
Разработки Winamp прекращены


3-1099816795
Dell3r
2004-11-07 11:39
2004.12.05
TTable


1-1101015885
Кириешки
2004-11-21 08:44
2004.12.05
Как определить что под курсором находится ссылка ?


10-1069399394
Юрий
2003-11-21 10:23
2004.12.05
TCorbaConnection возвращает BAD_OPERATION





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский