Текущий архив: 2004.12.05;
Скачать: CL | DM;
Вниз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 вся ветка
Текущий архив: 2004.12.05;
Скачать: CL | DM;
Память: 0.52 MB
Время: 0.045 c