Du kannst es ähnlich machen wie Delphi mit den Fensterprozeduren. Dazu solltest du dir mal den Code zu "MakeObjectInstance" in Classes.pas ansehen.
Du brauchst in Assembler einen Stub wie:
Code:
pop eax // Rücksprungadresse runter
push Self // Self auf den Stack legen (32-Bit Wert / Zeiger)
push eax // Rücksprungadresse wieder drauf
jmp TTastaturStatistik.LLKeyboardHookProc
LLKeyboardHookProc muss natürlich "stdcall" deklariert sein.
Den Speicherblock musst du dir mit
Block := VirtualAlloc(nil, PageSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
holen und dann statt deiner Prozedur eben "Block" als Zeiger bei SetWindowsHookEx angeben.
[Nachtrag]
Beispielcode (ungetestet):
Delphi-Quellcode:
function ClassProcAsHook(Obj: TObject; Method: Pointer): Pointer;
type
PCodeBlock = ^TCodeBlock;
TCodeBlock = packed record
bPopEax: byte;
bPushImm32: byte;
lSelf: longint;
bPushEax: byte;
bJmpDisp32: byte;
lDisp: longint;
end;
var
Block: PCodeBlock;
begin
Block := VirtualAlloc(nil, SizeOf(TCodeBlock), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
Block^.bPopEax := $58;
Block^.bPushImm32 := $68;
Block^.lSelf := longint(Obj);
Block^.bPushEax := $50;
Block^.bJmpDisp32 := $E9;
Block^.lDisp := longint(Method) - (longint(@Block^.lDisp) + 4);
Result := Block;
end;
Beim Opcode für PUSH bin ich mir nicht ganz sicher, bitte überprüfen.