type
PHookData = ^THookData;
THookData =
packed record
WindowProc:
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;
function MyWndProc(hWnd: ... LParam, Memory): 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(... Memory: PHookData): LResult;
stdcall;
const
MemorySize = SizeOf(THookData);
begin
if Msg = wm_Destroy
then
begin
Memory.CallWndProc(Memory.SaveWindowProc, Msg, wParam, lParam);
asm
MOV EAX,Memory
POP EDX
PUSH EAX
PUSH MemorySize
PUSH 0
PUSH EDX
JMP [EAX].THookData.VirtualFree
end;
end .....
end;
procedure SubClassWnd;
begin
...
Memory := VirtualAllocEx(..., SizeOf(THookData), ...);
Move(@WndProcDispatcher, Memory^, CodeSize);
...
end;