Hooks + LoadLibraryA (Delphi5 + Win2k) attempt #2
Аллоха, ALL!
В этот знаменательный день 12 мая 2004 г.
пиво ударило мне в голову, и я наскреб:
Я уже посылал это сообщение, но почему то на него не сильно обратили
внимание на что указывает то что никто не спросил про модуль Exchange
хотя я забыл указать его содержимое, может
все_ПОФИГУ := праздники.бухло.внутрь.create(ящик_водки) подействовало ;)
Задача состоит в следующем - надо загрузить в чужой процесс,
например блокнот (я загружал в BRED2R), свою DLL.
Я закачал http://podgoretsky.com/ftp/Docs/Delphi/Tenser/TenserAll.zip
Там есть документ
Interprocess communication на примере keyboard hook
Анатолий Тенцер
На его основе + размышления некого paul_shmakov на mastake (было
это давным-давно) я решил реализовать загрузку DLL, но столкнулся с
проблемой:
Если в Delphi открыть dpr с кодом dll которую надо загрузить, затем
выбрать Run -> Parameters -> Host Application указать программу
в которую должна загрузиться dll (в моем случае Bred), запустить,
затем запустить программу которая загружает dll, то все проходит
на ура:
dll грузиться и делает все что надо.
Но если просто запустить Bred и программу которая грузит dll то код в
этой dll не выполняется хотя LoadLibraryA выполняется.
В чем грабли?
PS: Я еще заметил что если грузить через Delphi то dll обрабатывает
сообщение SendMessage(CommonArea^.HookFormHandle, CommonArea^.WMHook, 0, 0);
а без Delphi - нет, т.е. хук на messages не работает.
>===Начало HookForm.pas==
unit HookForm;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
cbSetHook: TCheckBox;
procedure cbSetHookClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
end;
var
Form1: TForm1;
implementation
uses Exchange;
{$R *.DFM}
function SetHook(Activate: BOOL): BOOL; stdcall;
external 'HookDLL.DLL';
procedure TForm1.cbSetHookClick(Sender: TObject);
begin
SetHook(cbSetHook.Checked);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
FillChar(CommonArea^, SizeOf(CommonArea^), 0);
CommonArea^.FormHandle := Application.Handle;
CommonArea^.HookFormHandle := FindWindow(nil, '[БезИмени]-BRED2');
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
if cbSetHook.Checked then SetHook( FALSE );
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
SendMessage(CommonArea^.HookFormHandle, CommonArea^.WMHook, 0, 0);
end;
end.
>===Конец HookForm.pas==
>===Начало HookDLL.dpr==
library HookDLL;
uses
Windows,
Exchange,
Messages;
var hDll: LongWord;
function CallWndProc(nCode: Integer; wParam: WPARAM; lParam: LPARAM): Integer;
stdcall;
begin
Result := 0;
if nCode < 0 then
Result := CallNextHookEx(CommonArea^.HookHandle, nCode, wParam,
lParam)
else
if (PCWPSTRUCT(lParam)^.hwnd = CommonArea.HookFormHandle)
then
begin
hDll := LoadLibraryA('MyDLL.dll');
PostMessage(CommonArea^.FormHandle, WM_CLOSE, 0, 0);
Result := CallNextHookEx(CommonArea^.HookHandle, nCode, wParam, lParam
);
end;
end;
function SetHook(Activate : BOOL): BOOL; stdcall; export;
begin
Result := FALSE;
if Activate then
begin
CommonArea^.HookHandle := SetWindowsHookEx(WH_CALLWNDPROC,
@CallWndProc, hInstance, 0);
Result := (CommonArea^.HookHandle <> 0);
end
else
begin
if CommonArea^.HookHandle <> 0 then
begin
Result := UnhookWindowsHookEx(CommonArea^.HookHandle);
if Result then
CommonArea^.HookHandle := 0;
end;
end;
end;
exports
SetHook;
begin
end.
>===Конец HookDLL.dpr==
>===Начало MyDLL.dpr==
library MyDLL;
uses Windows;
function SetHook(Activate: BOOL): BOOL; stdcall;
external 'HookDLL.DLL';
{$R *.RES}
begin
SetHook(False);
MessageBox(0, '', '', 0);
while true do
sleep(100);
end.
>===Конец MyDLL.dpr==
>===Начало Exchange.pas==
unit Exchange;
interface
uses Windows;
type
PKeyboardHookInfo = ^TKeyboardHookInfo;
TKeyboardHookInfo = packed record
FormHandle: THandle;
HookHandle: THandle;
WMHook : Integer;
HookFormHandle: THandle;
end;
var
CommonArea: PKeyboardHookInfo = NIL;
implementation
var
Mapping: THandle = 0;
const
UniqueHookId = '{8FA5AD09-26EB-43E5-A977-91FCF972D32C}';
UniqueID = '{CE18D4DE-4C07-4F08-B18C-C07C29D3441E}';
initialization
Mapping := CreateFileMapping( INVALID_HANDLE_VALUE, NIL, PAGE_READWRITE, 0,
SizeOf(CommonArea), UniqueHookId);
CommonArea := MapViewOfFile(Mapping, FILE_MAP_ALL_ACCESS, 0, 0, 0);
CommonArea^.WMHook := RegisterWindowMessage(UniqueID);
finalization
if Assigned(CommonArea) then
UnmapViewOfFile(CommonArea);
if Mapping <> 0 then
CloseHandle(Mapping);
end.
>===Конец Exchange.pas==