InstallDllImportHook - Hook calls between modules

Top  Previous  Next



<aHookInfo> := InstallDllImportHook( <cCallingModule>, <cCalledFunctionName>, <cCalledModule>, <nCallback> )






Name of module from which calls to <cCalledFunctionName> are to be hooked.




Name of function to which calls from <cCallingModule> are to be hooked.




Name of module to which calls are to be hooked.




Address of callback (returned for example by Callback) function to be called instead of the original function.


Return value


When the operation succeeds an Array of two numeric elements (LONG values) is returned. The first element is the memory address of the original call address in the import table of <cCallingModule> that was modified. The constant to access it is DLLHOOKINFO_INDEX_HOOKADDRESS. The second element is the original call address found in the import table. The constant to access it is DLLHOOKINFO_INDEX_ORIGINALPROCADDRESS. These values can later be used to restore the original call with RemoveDllImportHook.


If the operation fails, NIL is returned.




InstallDllImportHook hooks calls between modules. When a module is loaded, its calls to functions in other modules must be "resolved". Normally the load address of a called module is not known at link time, hence the final addresses of called functions in it cannot be placed in the calling module at link time. This resolution takes place when a module is loaded. Every module comes with an import table containing references to all used functions in other modules. After loading a module (and the ones which it needs that have not been loaded before) the loader fixes its import table: All memory addresses of the used functions are written to its import table. This import table is changed by InstallDllImportHook.


The installed callback must receive the passed parameters and use the correct calling convention. If the call is not handled by the callback, it must pass on to the original function. This can be accomplished with CallAddress using the second element of <aHookInfo> as address to be called. Don't forget to pass on the received parameters in this case.










Quick Info


Library: cckptcor.lib /cckptcor.dll



See also











STATIC originalAddress




LOCAL hookInfo,envValue


* Hook any call from "xpprt1.dll" to "GetEnvironmentVariableA" in dll "kernel32.dll"

* to the callback function "MyHookFunc"

hookInfo := InstallDllImportHook("xpprt1.dll","GetEnvironmentVariableA",;



* That didn't work?

IF hookInfo == NIL

  MessageBox(0,"Hooking failed")




* Save the original address for passsing on the call to the original function



MessageBox(0,"Hooking successful.")


* HOOKINFO is our special value

envValue := GETENV("HOOKINFO")


* Display what we received

MessageBox(0,SVI("Returned value for HOOKINFO: &1",envValue))


* Any other value should return the real value of the environment variable

envValue := GETENV("SystemRoot")


* Display what we received

MessageBox(0,SVI("Returned value for SystemRoot: &1",envValue))


* Now remove the Hook


MessageBox(0,"Hook removed.")


* Now let's see what GETENV returns

envValue := GETENV("HOOKINFO")


* Display what we received (should be empty this time but it isn't, hence

* Xbase++ caches environment variables!)

MessageBox(0,SVI("Returned value for HOOKINFO after unhooking: &1",envValue))






* This function is called instead of the original GetEnvironmentVariableA function

CALLBACK FUNCTION MyHookFunc(p1,p2,p3)


* Display the passed parameters


          "Hook function called")


* Handle our special case...

IF CopyMemoryToString(p1) == "HOOKINFO"


  * Size Request?

  IF p3 == 0

     RETURN 11



  * Return our special result value

  WriteMemory(p2,"Holy Moly!"+CHR(0),11)


  * Return the size





* Pass the call on to the original function

RETURN CallAddress(originalAddress,p1,p2,p3)