unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
PHookData = ^THookData;
THookData = packed record
WindowProc: array[0..511] of Byte;
ThreadCode: array[0..511] of Byte;
SaveWindowProc: Pointer;
hWnd: HWnd;
GetWindowLong: function(hWnd : HWND; nIndex : INTEGER ): LongInt; stdcall;
SetWindowLong: function(hWnd : HWND; nIndex : INTEGER; wNewLong : LongInt): LongInt; stdcall;
ExitThread: procedure(dwExitCode : DWORD); stdcall;
CallWndProc: function(lpPrevWndFunc : TFNWndProc; hWnd: HWND; Msg: WORD; wParam: WPARAM;
lParam: LPARAM): lResult; stdcall;
VirtualFree: function(lpAddress : Pointer; dwSize : DWORD; dwFreeType : DWORD) : bool;
stdcall;
end;
TForm1 = class(TForm)
Button1: TButton;
private
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
function MyWndProc(hWnd: HWND; Msg: WORD; wParam: WPARAM; lParam: LPARAM): LResult; stdcall; forward;
////////////////////////////////////////////////////////////////////////////////
procedure WndProcDispatcher;
asm
CALL @@1
@@1: POP EAX
SUB EAX,2 // Opcode size für CALL @@1, somit EAX = Memory
POP EDX
PUSH EAX
PUSH EDX
JMP MyWndProc
end;
/////////////////////////////////////////////////////////////////////////////////
function MyWndProc(hWnd: HWND; Msg: WORD; wParam: WPARAM; lParam: LPARAM): lResult; stdcall;
const
MemorySize = SizeOf(THookData );
var
Memory: PHookData;
begin
if Msg = wm_Destroy then
begin
Memory.CallWndProc(Memory.SaveWindowProc, hWnd, Msg, wParam, lParam);
asm
MOV EAX,Memory
POP EDX
PUSH EAX
PUSH MemorySize
PUSH 0
PUSH EDX
JMP [EAX].THookData.VirtualFree
end;
end else
if Msg = wm_Close then
begin
end else
Result := Memory.CallWndProc(Memory.SaveWindowProc, hWnd, Msg, wParam, lParam);
end;
/////////////////////////////////////////////////////////////////////////////////
function ThreadProc(Memory: PHookData): Dword; stdcall;
begin
Memory.SaveWindowProc := Pointer ( Memory.GetWindowLong(Memory.hWnd, gwl_WndProc) );
Memory.SetWindowLong(Memory.hWnd, gwl_WndProc, Memory.WndProcDispatcher);
Memory.ExitThread(0);
end;
/////////////////////////////////////////////////////////////////////////////////
procedure SubClassWnd(hWnd);
var
Memory: PHookData;
ProcSize: Integer;
ThreadFunc: Pointer;
begin
ProcSize := PChar(@Subclass) - PChar(@MyWndProc);
Memory := VirtualAllocEx(..., SizeOf(THookData), ...);
Move(@WndProcDispatcher, Memory^, ProcSize);
Memory.hWnd := hWnd;
???
end;
end.