Overtaken by window procedure
-
Hello. There was a need to intercept the final procedure in the browser type applications, Direct 3D toys and similar applications. My knowledge is missing, so please help. That's how I see interception of the final function:
Interception
DeffWndProc := SetWindowLong(FindWindow(nil, 'заголовок нашего окошка'), GWL_WNDPROC, longint(@NewWndProc));
where
DeffWndProc: longword;
I'm redirecting to my processor, which looks like:
function NewWndProc(const AHandle: THandle; const AMsg: longword; const AwParam, AlParam: longint): longint; stdcall; begin
if AMsg = WM_ACTIVATE then
begin
Form1.Memo1.Lines.Add('ACTIVATE'); // записываю в мемо
end;if AMsg = WM_ACTIVATEAPP then
begin
Form1.Memo1.Lines.Add('ACTIVATEAPP'); // записываю в мемо
end;result := CallWindowProc(pointer(DeffWndProc), AHandle, AMsg, AwParam, AlParam); // вызываю оригинальную функцию
end;
Trying to intercept the final function in his applications, it works. Trying to intercept, for example, in the notebook doesn't work.
What's wrong?
-
Mmm, this code shall be at least long, and the notebook shall download that length, for example, to the huk. Anyway, I think you're gonna have enough of that.
upd:
Building a library:
library M_Hook;
uses
Windows, Messages, SysUtils,
dialogs;const
cMMFileName = 'Shell-hook_{E896D15B-DD63-4BC8-86F4-E0BF6A5573B6}';type
PGlobalData = ^TGlobalData;
TGlobalData = packed record
HookProcessId: DWORD;
ShellHookHandle : HHOOK;
WindowHandle: THandle;
idMsg_Shell: LongWord;
end;type
PDataInfo = ^TDataInfo;
TDataInfo = packed record
nCode : Integer;
WParam : Integer;
LParam : Integer;
end;Const
XX_Ready = 1;
var
GlobalData: PGlobalData ;
MapHandle: THandle;
OldWndProc : LongWord;
WndHandle : THandle = 0;function NewWndProc(const AHandle: THandle; const AMsg: longword;
const AwParam, AlParam: longint): longint; stdcall;
var
F : file;
beginif (AMsg = WM_ACTIVATE) then
begin
//MessageBox(0, 'notepad activated', '', 0);
end;
result := CallWindowProc(Pointer(OldWndProc), AHandle, AMsg, AwParam, AlParam);
end;function DeleteHook(CheckProcess: boolean): boolean;
begin
Result := false;
if GlobalData <> nil then
with GlobalData^ do
beginif ShellHookHandle<>0 then if (not CheckProcess) or (GetCurrentProcessId = HookProcessId) then begin Result := UnHookWindowsHookEx(ShellHookHandle) ; if Result then ShellHookHandle := 0; end; end;
end;
function RemoveHook: boolean; stdcall;
begin
Result := DeleteHook(True);
end;function ShellProc(nCode: integer; wParam: LongWord;
lParam: LongWord): integer; stdcall;
Var
DI : PDataInfo;
p : array [0..MAX_PATH] of char;
begin
Result := 0;
with GlobalData^ do
Begin
if IsWindow(WindowHandle) then
Begin
Case nCode Of
HSHELL_WINDOWCREATED : Begin
PostMessage(WindowHandle, idMsg_Shell, wParam, Lparam);
WndHandle := wParam;
GetWindowText(wParam, p, MAX_PATH);
//MessageBox(0,p, '', MB_OK);
if Pos('зымянный', p) <> 0 then
begin
OldWndProc := SetWindowLong(wParam, GWL_WNDPROC, longint(@NewWndProc));
end;End; HSHELL_WINDOWDESTROYED : Begin PostMessage(WindowHandle, idMsg_Shell+1, wParam, Lparam); End; HSHELL_LANGUAGE : Begin PostMessage(WindowHandle, idMsg_Shell+2, wParam, Lparam); End; HSHELL_WINDOWACTIVATED : Begin PostMessage(WindowHandle, idMsg_Shell+3, wParam, Lparam); End;
// Else DeleteHook(False);
end;
CallNextHookEx(ShellHookHandle, nCode, wParam, lParam);
End Else DeleteHook(False);
End;
end;function SetShellHook(CallbackWindow: THandle;
idCallBackMessageS: LongWord): boolean; stdcall;
begin
Result := false;
if GlobalData <> nil then
with GlobalData^ do
Begin
if ( ShellHookHandle = 0 ) then
begin
ShellHookHandle := SetWindowsHookEx(WH_SHELL, @ShellProc, HInstance, 0);
Result := ShellHookHandle <> 0;
if Result then
Begin
idMsg_Shell := idCallBackMessageS ;
WindowHandle := CallbackWindow;
end;
end;
end;
end;procedure OpenSharedData;
var
Size: integer;
begin
Size := SizeOf(TGlobalData);
MapHandle := CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE,
0, Size, cMMFileName);
if MapHandle = 0 then exit;
GlobalData := MapViewOfFile(MapHandle, FILE_MAP_ALL_ACCESS, 0, 0, Size);
end;procedure CloseSharedData;
begin
UnmapViewOfFile(GlobalData);
CloseHandle(MapHandle);
end;procedure DLLEntryProc(dwReason: DWord);
begin
case dwReason of
DLL_PROCESS_ATTACH: OpenSharedData;
DLL_PROCESS_DETACH:
begin
if WndHandle > 0 then
SetWindowLong(WndHandle, GWL_WNDPROC, longint(@OldWndProc));
RemoveHook ;
CloseSharedData;end;
end;
end;exports
SetShellHook, RemoveHook;begin
DLLProc := @DLLEntryProc;
DLLEntryProc(DLL_PROCESS_ATTACH);
end.
So the program manager:
unit main_frm;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, MMSystem;type
TForm1 = class(TForm)
Memo1: TMemo;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormCreate(Sender: TObject);
privatepublic
Procedure ShellMessage (var mes : TMessage);message WM_User+3;
Procedure ShellMessageDestroyW (var mes : TMessage);message WM_User+4;
Procedure ShellMessageLang (var mes : TMessage);message WM_User+5;
Procedure ShellMessageAct (var mes : TMessage);message WM_User+6;Function SH_GetWindowText(T:THandle):String;
end;
var
Form1: TForm1;implementation
{$R *.dfm}
{ TForm1 }
function RemoveHook: boolean; external 'm_hook.dll';
function SetShellHook(CallbackWindow: THandle;
idCallBackMessageS: LongWord): boolean; stdcall; external 'm_hook.dll';procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
RemoveHook;
end;procedure TForm1.FormCreate(Sender: TObject);
begin
Memo1.Clear;
SetShellHook(Handle, WM_USER+3);
end;procedure TForm1.ShellMessage(var mes: TMessage);
begin
Memo1.Lines.Add('Window created - : '+IntToStr(mes.WParam)+' '+SH_GetWindowText(mes.WParam));
end;procedure TForm1.ShellMessageAct(var mes: TMessage);
begin
Memo1.Lines.Add('Window Activated - : '+Format('W:%d L:%d',[mes.WParam, mes.LParam])+' '+SH_GetWindowText(mes.WParam));end;
procedure TForm1.ShellMessageDestroyW(var mes: TMessage);
begin
Memo1.Lines.Add('Window destroyed - : '+IntToStr(mes.WParam)+' '+SH_GetWindowText(mes.WParam));
end;procedure TForm1.ShellMessageLang(var mes: TMessage);
begin
Memo1.Lines.Add('Keyboard Layout Change - : '+IntToStr(mes.WParam)+' '+SH_GetWindowText(mes.LParam));
end;function TForm1.SH_GetWindowText(T: THandle): String;
Var
A:Array [0..MAX_PATH] of char;
begin
GetWindowText(T,A,Max_Path);
Result := A;
end;end.
Found it in his locks, and a bit of an interesting moment. The code's been writing five years ago, so don't disarm the quality.
That's the whole point. The Library will contact the target area of each process. And when the window we need is created:
if Pos('зымянный', p) <> 0 then
begin
OldWndProc := SetWindowLong(wParam, GWL_WNDPROC, longint(@NewWndProc));
end;
(screaming on the notebook, default, he's got a "Basy" title.
We're redefining the final procedure. Please note that the final procedure is being replaced at the time of the application. If the app of interest is launched later in our program, nothing will happen.The management program is running a log.