-1

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 hook `EnumWindows()` first in order to gain access to any callback function that is passed to it. And then you can hook those callback(s) when they are being called for the first time – Remy Lebeau Jul 10 '18 at 16:50

1 Answers1

1

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.
Pavel Minenkov
  • 368
  • 2
  • 9