Hooks + LoadLibraryA (Delphi5 + Win2k)
Аллоха, ALL!
В этот знаменательный день 4 мая 2004 г.
пиво ударило мне в голову, и я наскреб:
Задача состоит в следующем - надо загрузить в чужой процесс,
например блокнот (я загружал в 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 выполняется.
В чем грабли?
>===Начало 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==
PS: В документе
Interprocess communication на примере keyboard hook
Анатолий Тенцер
Есть ошибка:
> function CreateFileMapping(
> hFile: THandle; // Идентификатор ранее открытого файла. Если hFile
> // равен -1, то объект создается в swap-файле
Вот здесь должно быть не "-1", а "0"
> lpFileMappingAttributes: PSecurityAttributes;
> // Аттрибуты защиты. Для наследования аттрибутов
> // вызывающего процесса можно передать NIL
> flProtect, // Права на чтение-запись
> dwMaximumSizeHigh, // Старшие 32 разряда размера объекта
> dwMaximumSizeLow: DWORD; // Младшие 32 разряда размера объекта
> lpName: PChar // Имя объекта
> ): THandle; stdcall;