Delphi DLLs in Hooks and COM Objects

Writing a DLL that will be injected into another processes address space in Delphi can be a tricky job if you loose sight of how Windows handles these DLL's. One other issue is the instability of Delphi DLL in other processes address space. The bug in the Runtime Library of Delphi since D2 has finally been tracked down and the fix for it can be found here.

  When Windows loads a process that will load your global DLL it will create a new copy of the DLL in each process. This means that global variables in the DLL are not global between processes, it is only global within the one process.

For instance assume three processes will load your global hood DLL.

When the DLLs are loaded into the processes address space it looks like the following.

  Notice that VariableA in ProcessA is NOT the same as VariableA in ProcessB or VariableA in ProcessC. This seems straightforward but it is easy to loose track of that fact when you start to develop the DLL. One place this will have an impact is when you try to place the mechanism to communicate with a program that is in the recipient of the hook notifications. When you insert the hook into the Windows hook mechanism you will need to tell the DLLs the handle of the window to send message to for instance. Did you notice the plural use of DLL. If you simply create a global variable the DLL and assign the Form's handle in your test application then the copy of the DLL that is loaded into your applications process space is the ONLY copy of the DLL that has that value. I can't repeat this enough.

  How can we communicate with instances of the DLL over all processes? The only way to do this in Delphi is using Memory Mapped Files (MMFs). There is a mechanism supported in Microsoft C compilers to do this but its underlying implementation uses MMFs. By creating a named Memory Mapped File in the control application each DLL instance can open this MMF and map the same data into its process space.

  One other catch is when a hook is passed a pointer to it hook procedure in one process the pointer is meaningless in another process. This means that the data pointed to by the pointer must be written to a Memory Mapped File and that data may then be opened by other processes and read back out.

A simple CBT demo that illustrates the use of MMF's to handle the global data and the passing of the hook procedures data to the control application for display can be downloaded from here

 


mustangpeak.net

  Last Modified on: