This is the root and kernel interface of Win32 CodeHook.
You can call GetCodeHook to get the root interface.
You can also call ICodeHook.CreateCodeHook to create a new interface.
It supports both raw mode hook and advanced hook.
Delphi syntax:
ICodeHook = interface(IErrorCodeHook) procedure GetDirectCodeHook(out Obj); stdcall; procedure GetCodeHookHelper(out Obj); stdcall; procedure CreateCodeHook(out Obj); stdcall; procedure SetUserDataSize(ASize: Integer); stdcall; function Hook(ATarget, AHook: Pointer): TCodeHookHandle; stdcall; function Unhook(AHandle: TCodeHookHandle): LongBool; stdcall; function GetHookInfo(AHandle: TCodeHookHandle; AInfo: PCodeHookInfo): LongBool; stdcall; function GetUserData(AHandle: TCodeHookHandle): Pointer; stdcall; function AdvancedHook(ATargetObject: Pointer; ATarget: Pointer; ATargetCallingConvention: Integer; AHook: Pointer; AHookCallingConvention: Integer; AParamCount: Integer; AExtraParams: PCardinal; AExtraParamCount: Integer; AFlags: Cardinal): TCodeHookHandle; stdcall; function AdvancedUnhook(AHandle: TCodeHookHandle): LongBool; stdcall; function FindHookHandleFromTarget(ATarget: Pointer): TCodeHookHandle; stdcall; function CallPreviousMethod(AHandle: TCodeHookHandle; AParams: PCardinal): Cardinal; stdcall; function CallMethod(AObject: Pointer; AMethod: Pointer; AParams: PCardinal; AParamCount: Integer; ACallingConvention: Integer): Cardinal; stdcall; end;C++ syntax:
class ICodeHook: public ICodeHookError {
public:
virtual void _stdcall GetDirectCodeHook(IDirectCodeHook **) = 0;
virtual void _stdcall GetCodeHookHelper(ICodeHookHelper **) = 0;
virtual void _stdcall CreateCodeHook(ICodeHook **) = 0;
virtual void _stdcall SetUserDataSize(int Size) = 0;
virtual TCodeHookHandle _stdcall Hook(Pointer Target, Pointer Hook) = 0;
virtual BOOL _stdcall Unhook(TCodeHookHandle Handle) = 0;
virtual BOOL _stdcall GetHookInfo(TCodeHookHandle Handle, PCodeHookInfo Info) = 0;
virtual Pointer _stdcall GetUserData(TCodeHookHandle Handle) = 0;
virtual TCodeHookHandle _stdcall AdvancedHook(Pointer TargetObject,
Pointer Target, int TargetCallingConvention,
Pointer Hook, int HookCallingConvention,
int ParamCount,
PUINT ExtraParams, int ExtraParamCount,
UINT Flags) = 0;
virtual BOOL _stdcall AdvancedUnhook(TCodeHookHandle Handle) = 0;
virtual TCodeHookHandle _stdcall FindHookHandleFromTarget(Pointer Target) = 0;
virtual UINT _stdcall CallPreviousMethod(TCodeHookHandle Handle, PUINT Params) = 0;
virtual UINT _stdcall CallMethod(Pointer Object, Pointer Method,
PUINT Params, int ParamCount, int CallingConvention) = 0;
};
Function:
Retrieve interface IDirectCodeHook
Delphi syntax:
C++ syntax:
Params
GetDirectCodeHook
Retrieve interface IDirectCodeHook
Delphi syntax:
procedure GetDirectCodeHook(out Obj); stdcall;
C++ syntax:
virtual void calltype GetDirectCodeHook(IDirectCodeHook **) = 0;
Params
- Obj
- Address of pointer variable that receives the interface pointer.
- This function doesn't return value.
Function:
Retrieve interface ICodeHookHelper
Delphi syntax:
C++ syntax:
Params
GetCodeHookHelper
Retrieve interface ICodeHookHelper
Delphi syntax:
procedure GetCodeHookHelper(out Obj); stdcall;
C++ syntax:
virtual void calltype GetCodeHookHelper(ICodeHookHelper **) = 0;
Params
- Obj
- Address of pointer variable that receives the interface pointer.
- This function doesn't return value.
Function:
Create an instance of interface ICodeHook
Delphi syntax:
C++ syntax:
Params
CreateCodeHook
Create an instance of interface ICodeHook
Delphi syntax:
procedure CreateCodeHook(out Obj); stdcall;
C++ syntax:
virtual void calltype CreateCodeHook(ICodeHook **) = 0;
Params
- Obj
- Address of pointer variable that receives the interface pointer.
- This function doesn't return value.
- Usually you don't need to call this function because the interface returned by GetCodeHook is enough to you.
Function:
Set the user data record size.
Delphi syntax:
C++ syntax:
Params
SetUserDataSize
Set the user data record size.
Delphi syntax:
procedure SetUserDataSize(ASize: Integer); stdcall;
C++ syntax:
virtual void calltype SetUserDataSize(int Size) = 0;
Params
- ASize
- The size of user data in byte.
- This function doesn't return value.
- You can specify a user data size and call GetUserData to retrieve the user data pointer then you can store information to the user data.
Function:
Low level hook a method.
Delphi syntax:
C++ syntax:
Params
Hook
Low level hook a method.
Delphi syntax:
function Hook(ATarget, AHook: Pointer): TCodeHookHandle; stdcall;
C++ syntax:
virtual TCodeHookHandle calltype Hook(Pointer Target, Pointer Hook) = 0;
Params
- ATarget
- Address of the target function.
- AHook
- Address of the hook function.
- A handle that represents the code hook information.
- The prototype of the hook function should be exactly same as the target.
That's to say, the parameters count and the calling convention should be same.
Function:
Low level unhook a method.
Delphi syntax:
C++ syntax:
Params
Unhook
Low level unhook a method.
Delphi syntax:
function Unhook(AHandle: TCodeHookHandle): LongBool; stdcall;
C++ syntax:
virtual BOOL calltype Unhook(TCodeHookHandle Handle) = 0;
Params
- AHandle
- The handle returned by HookMethod.
- Return TRUE on success, otherwise, return FALSE.
Function:
Retrieve the hook information.
Delphi syntax:
C++ syntax:
Params
GetHookInfo
Retrieve the hook information.
Delphi syntax:
function GetHookInfo(AHandle: TCodeHookHandle; AInfo: PCodeHookInfo): LongBool; stdcall;
C++ syntax:
virtual BOOL calltype GetHookInfo(TCodeHookHandle Handle, PCodeHookInfo Info) = 0;
Params
- AHandle
- The handle represents the code hook information
- AInfo
- Pointer to a TCodeHookInfo record (structure).
- Return TRUE on success, otherwise, return FALSE.
Function:
Retrieve the user data buffer.
Delphi syntax:
C++ syntax:
Params
GetUserData
Retrieve the user data buffer.
Delphi syntax:
function GetUserData(AHandle: TCodeHookHandle): Pointer; stdcall;
C++ syntax:
virtual Pointer calltype GetUserData(TCodeHookHandle Handle) = 0;
Params
- AHandle
- The handle represents the code hook information
- If the function successes, returns the pointer to the user data.
If the function fails, returns NULL (nil).
- User data is another way to store customized information beside extra parameters.
User data allow you to store and retrieve any data in the code hook handle.
The initial user data memory is guaranteed to be zero.
Note:
Don't forget to call ICodeHook.SetUserDataSize to set the property user data size, otherwise, you will get wrong user data memory.
Function:
Advanced mode hook a method.
Delphi syntax:
C++ syntax:
Params
AdvancedHook
Advanced mode hook a method.
Delphi syntax:
function AdvancedHook(ATargetObject: Pointer;
ATarget: Pointer; ATargetCallingConvention: Integer;
AHook: Pointer; AHookCallingConvention: Integer;
AParamCount: Integer;
AExtraParams: PCardinal; AExtraParamCount: Integer;
AFlags: Cardinal): TCodeHookHandle; stdcall;
C++ syntax:
virtual TCodeHookHandle calltype AdvancedHook(Pointer TargetObject, Pointer Target, int TargetCallingConvention, Pointer Hook, int HookCallingConvention, int ParamCount, PUINT ExtraParams, int ExtraParamCount, UINT Flags) = 0;
Params
- ATargetObject
- Address of the "this" pointer of the target.
If the target is a global function, set this parameter to NULL. - ATarget
- Address of the target function.
- ATargetCallingConvention
- The calling convention of the target function.
- AHook
- Address of the hook function. See remarks.
- AHookCallingConvention
- The calling convention of the hook function.
- AParamCount
- The param count of the target function. See remarks.
- AExtraParams
- Pointer to extra parameters. See remarks.
- AExtraParamCount
- The count of extra parameters.
- AFlags
- For future use. Now pass it with 0.
- A handle that represents the code hook information.
- Note on the hook function:
The prototype of the hook function should be in a fixed form, independent on the target.
The prototype should be,
Delphi syntax: function HookCallback(AExtraParam1: Cardinal; AExtraParam2: Cardinal .. AExtraParamN: Cardinal; AHandle: TCodeHookHandle; AParams: PCodeHookParamAccessor): Cardinal; CallingConvertion;
C++ syntax: DWORD CallingConvertion HookCallback(DWORD AExtraParam1, DWORD AExtraParam2 .. DWORD AExtraParamN, TCodeHookHandle AHandle, PDWORD AParams);
If no extra parameters, the prototype should be
Delphi syntax: function HookCallback(AHandle: TCodeHookHandle; AParams: PCodeHookParamAccessor): Cardinal; CallingConvertion;
C++ syntax: DWORD CallingConvertion HookCallback(TCodeHookHandle AHandle, PDWORD AParams);
You can access the hook information using AHandle by calling ICodeHook.GetHookInfo.
You can also access the customized user data information using AHandle by calling ICodeHook.GetUserData.
The parameter AParams is the parameters that are passed to the target function. You can access the parameters by accessing AParams[0], AParams[1], etc. For example, if the hook is for Windows API MessageBox, then AParams[0] is the first parameter of MessageBox, hWnd. AParams[1] is the second, lpText, AParams[2] is lpCaption, and AParams[3] is uType.
This function assumes the hook function is a global function. If object function is used as hook, you should better use ICodeHookHelper.HookWithObjectMethod to make the hook.
Note on the parameter count:
AParamCount is base on the presupposition that the target function takes simple parameters.
"Simple" means all parameters are simple data type with no more than 32 bits. The simple data types include byte, char, short, word, int, dword, pointer, single float, etc.
Other types such as double float (64 bits float), Intel extended float (80 bits float), Windows Variant type, record (structure) are not simple.
If non-simple parameters are in the target function, you should better use raw mode hook and make the hook function exactly same prototype with the target function rather than using the advanced hook.
Note on the extra parameters:
You can pass predefined values as extra parameters and fetch the values in the hook function. This is a good place to connect the hook function with current running enviroment. You can pass the necessary information to the hook function as parameters instead of putting it in the global context. A typical very useful use is to pass the "this" pointer if the hook is a class member function.
The extra parameters are passed as partial of the hook function's parameters, beside the code hook handle (AHandle) and the parameter pointer (AParams).
The order passing the mixed parameters is that the first extra parameter is passed, then the second, then the third, after all extra parameters are passed, the code hook handle (AHandle) is passed, and the parameter pointer (AParams) is passed last.
So in both Delphi and C++, when declaring the hook function, the first extra parameter should be at the most left, and the parameter pointer (AParams) should be at the most right.
Function:
Advanced mode unhook a method.
Delphi syntax:
C++ syntax:
Params
AdvancedUnhook
Advanced mode unhook a method.
Delphi syntax:
function AdvancedUnhook(AHandle: TCodeHookHandle): LongBool; stdcall;
C++ syntax:
virtual BOOL calltype AdvancedUnhook(TCodeHookHandle Handle) = 0;
Params
- AHandle
- The handle returned by AdvancedHook.
- Return TRUE on success, otherwise, return FALSE.
Function:
Find handle from a given target address.
Delphi syntax:
C++ syntax:
Params
FindHookHandleFromTarget
Find handle from a given target address.
Delphi syntax:
function FindHookHandleFromTarget(ATarget: Pointer): TCodeHookHandle; stdcall;
C++ syntax:
virtual TCodeHookHandle calltype FindHookHandleFromTarget(Pointer Target) = 0;
Params
- ATarget
- The target address to find.
- If this function successes, return the handle found. Otherwise, return INVALID_CODEHOOK_HANDLE.
- To get the target address from a handle, use ICodeHook.GetHookInfo.
Function:
Call previous function.
Delphi syntax:
C++ syntax:
Params
CallPreviousMethod
Call previous function.
Delphi syntax:
function CallPreviousMethod(AHandle: TCodeHookHandle; AParams: PCardinal): Cardinal; stdcall;
C++ syntax:
virtual UINT calltype CallPreviousMethod(TCodeHookHandle Handle, PUINT Params) = 0;
Params
- AHandle
- The handle that represents the code hook information.
- AParams
- The pointer to the parameters.
- Return what the previous function returns. If the previous function doesn't return a value, the return value is undefined.
Function:
Call a function with specified calling convention and parameters.
Delphi syntax:
C++ syntax:
Params
CallMethod
Call a function with specified calling convention and parameters.
Delphi syntax:
function CallMethod(AObject: Pointer; AMethod: Pointer;
AParams: PCardinal; AParamCount: Integer; ACallingConvention: Integer): Cardinal; stdcall;
C++ syntax:
virtual UINT calltype CallMethod(Pointer Object, Pointer Method, PUINT Params, int ParamCount, int CallingConvention) = 0;
Params
- AObject
- The object instance if the destination is an object method. If the destination is a global method, set this parameter to NULL.
- AMethod
- The address of the destination method.
- AParams
- The pointer to the parameters.
- AParamCount
- The parameters count.
- ACallingConvention
- The calling convention of the previous function.
- Return what the function returns. If the function doesn't return a value, the return value is undefined.
- Usually use CallPreviousMethod instead of this function.
This function should only be used when you use raw mode hooking while you want to call the previous function without prototype.