I want know if is possible hook a callback function for example like EnumWindowsProc()
using inline hook approach? and if yes, could provide a code snippet (example) please?
Thank you.
EDITION:
EnumWindowsProc
is a callback implemented in other app. I not call it inside my app.
And i want hook EnumWindowsProc
in this other app, by dll injection.
You have to handle EnumWindows at first, then you have to replace pointer to original EnumWindowsProc to yourself.
My example is valid fow win32
unit Patch;
interface
procedure PatchEnumWindows(Patch: Boolean);
implementation
uses SysUtils, SyncObjs, Windows;
const
INSTR_SIZE = 6;
var
OldEnumWindows: array [0..INSTR_SIZE-1] of Byte;
EnumWindowsPatched: Boolean = False;
function PatchedEnumWindows(EnumWindowsProc: Pointer; Param: Pointer); stdcall;
begin
// You have to replace original EnumWindowsProc to yourself
end;
procedure ApiRedirect(OrigFunction, NewFunction: Pointer; var Old);
const
TEMP_JMP: array[0..INSTR_SIZE-1] of Byte = ($E9,$90,$90,$90,$90,$C3);
var
JmpSize: DWORD;
JMP: array [0..INSTR_SIZE-1] of Byte;
OldProtect: DWORD;
begin
Move(TEMP_JMP, JMP, INSTR_SIZE);
JmpSize := DWORD(NewFunction) - DWORD(OrigFunction) - 5;
if not VirtualProtect(LPVOID(OrigFunction), INSTR_SIZE, PAGE_EXECUTE_READWRITE, OldProtect) then
raise Exception.CreateFmt('%s', [SysErrorMessage(GetLastError)]);
Move(OrigFunction^, Old, INSTR_SIZE);
Move(JmpSize, JMP[1], 4);
Move(JMP, OrigFunction^, INSTR_SIZE);
VirtualProtect(LPVOID(OrigFunction), INSTR_SIZE, OldProtect, nil);
end;
procedure PatchEnumWindows(Patch: Boolean);
var
OrigEnumWindows: Pointer;
begin
if Patch <> EnumWindowsProcPatched then begin
OrigEnumWindows := GetProcAddress(GetModuleHandle('user32.dll'), 'EnumWindows');
if Patch then begin
ApiRedirect(OrigEnumWindows, @PatchedEnumWindows, OldEnumWindows);
end
else begin
Move(OldEnumWindows, OrigEnumWindows, INSTR_SIZE);
end;
EnumWindowsPatched := Patch;
end;
end;
end.