Hooking includes a range of methods for changing or expanding the behavior of an operating system, application, or other software parts by intercepting API function calls, messages, or events passed between software components. The code that controls such interception is called a hook.
DDetours is a library that allows you to insert and remove the hook from the function. It supports both (x86 and x64) architecture. The basic idea of this library is to replace the prologue of the target function by inserting unconditional jump instruction to the intercepted function.
Hooking rules
To run your hook correctly, you must follow the following rules:
- Intercept procedure must have the same original procedure signature. That means the same parameters (types) and same calling convention.
- When hooking Delphi Object/COM Object, the first parameter of the InterceptProc/Trampoline must be a pointer to that object, which we call Self.
- When doing multi-hooks, each hook needs its NextHook/Trampoline function.
- When building a multi-thread application, inserting/removing hooks should be done inside the BeginTransaction/EndTransaction frame.
- Never try to call the original function directly inside the Intercept function, as this may result in a recursive call. Always use NextHook/Trampoline function.
- Use EnterRecursiveSection/ExitRecursiveSection when calling a function that may call internally the original function.
Here is some sample source code from the example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
type TMessageBox = function(hWnd: hWnd; lpText, lpCaption: LPCWSTR; uType: UINT): Integer; stdcall; var TrampolineMessageBox: TMessageBox = nil; function InterceptMessageBox(hWnd: hWnd; lpText, lpCaption: LPCWSTR; uType: UINT): Integer; stdcall; var Self: TMain; begin Self := GetTrampolineParam(TrampolineMessageBox); Self.Caption := 'MessageBox hooked !'; Result := TrampolineMessageBox(hWnd, 'this text was hooked', 'this title was hooked', MB_ICONWARNING); end; procedure TMain.FormCreate(Sender: TObject); begin BtnUnHook.Enabled := False; end; procedure TMain.BtnHookClick(Sender: TObject); begin TrampolineMessageBox := InterceptCreate(@MessageBox, @InterceptMessageBox, Self); BtnUnHook.Enabled := True; BtnHook.Enabled := False; end; procedure TMain.BtnMsgBoxClick(Sender: TObject); begin MessageBox(0, 'text', 'caption', 0); end; procedure TMain.BtnUnHookClick(Sender: TObject); begin if Assigned(TrampolineMessageBox) then begin InterceptRemove(@TrampolineMessageBox); TrampolineMessageBox := nil; BtnHook.Enabled := True; BtnUnHook.Enabled := False; end; end; initialization finalization if Assigned(TrampolineMessageBox) then InterceptRemove(@TrampolineMessageBox); |
Check out and download the powerful DDetour library over on Github!
With the use of Windows IDE, you can quickly and easily hook Delphi and windows API functions with the ddetours library. Try your Free Trial here.
Design. Code. Compile. Deploy.
Start Free Trial Upgrade Today
Free Delphi Community Edition Free C++Builder Community Edition