You are here:

C++/dll hooking

Advertisement


Question
Just to let you know, I do not plan on doing anything bad.  Now about my dll, it MUST have all the other functions of the original dll?  What if i only plan on using just one function, the add.

-------------------------
Followup To
Question -
Let's say there is an application that uses a dll called Math.dll and it has Add, Subtract, Multiply, Divide functions.  Now, I want to use my own add function located in MyMath.dll.  For me to do this, I'll use SetWindowsHookEx which requires a ThreadID of the remote process(the one in Math.dll, I think).  By the way, I assume that my SetWindowsHookEx is SetWindowsHookEx(WH_CBT, hookproc, hinstance, threadID).  My question is...how do I get the thread id of that process?  And how will my hook procedure know that it's replacing the Add function and not the other functions(Subtract, Multiply, Divide).  I think you do an IF statement in the beginning of the hook procedure, but I just don't know what condition to use.  If my question shows that i'm doing it wrong, please show me the correct way to do it.  Thanks.
Answer -
OK. I do not think what you are trying to do will work as planned. The
CBTProc installed using WH_CBT is called as follows (from the MSDN library documentation):

"The CBTProc hook procedure is an application-defined or library-defined callback function used with the SetWindowsHookEx function. The system calls this function before activating, creating, destroying, minimizing, maximizing, moving, or sizing a window; before completing a system command; before removing a mouse or keyboard event from the system message queue; before setting the keyboard focus; or before synchronizing with the system message queue. A computer-based training (CBT) application uses this hook procedure to receive useful notifications from the system."

It does _not_ allow you to re-route arbitrary functions calls to your own functions. In fact, doing so will probably be considered a dodgy thing to do at best and malicious usage at worst - i.e. a virus.

The obvious way is to replace the DLL in question with your own version and pass on requests to the unmodified function calls to the original DLL - which you could rename. Now do you see why I think this is rather dodgy and possibly virus like and maybe even illegal?

I strongly recommend that you DO NOT take any potentially illegal action.

Your replacement DLL would probably have to link to the original DLL's functions dynamically using LoadLibrary or LoadLibraryEx and GetProcAddress. You then write the replacement Add function and also wrapper functions in your DLL for _all_ the un-altered functions in the original DLL that are used by the application and any other applications that uses the DLL. These wrapper functions simply call and return the value from the original DLL's functions using the function pointer addresses returned by GetProcAddress. You can find further information in the MSDN library (online at http://www.msdn.microsoft.com/). For an example of loading a DLL and obtaining pointers to exported functions search for the article titled "Using Run-Time Dynamic Linking".

Oh, if the DLL you replace also contains data (i.e. exported global variables) that are used elsewhere then these will have to be replicated and will cause problems as your DLL's version will not necessarily have the same value as the copy contained in the original DLL - no matter how you try to keep them synchronisation.  

Answer
Yes. All the exported symbols that are used by the application that uses the original dll _must_ be present in the replacement it has to look just like the original. However, if you read the answer, you will notice that most of the replacement functions are forwarding wrapper functions that just call the matching function in the (renamed) original dll. Also the replacement should have the same name and be placed in the same directory as the original or someplace else on the path.

However if this application just uses the add function then that is conceptually the only one you need to write but you may find other applications that use the dll will fail when the replacement is installed because they call the other functions remember dlls can be used by more than one application.

The only fly in the ointment is that the name of the function may have been  converted to an exported symbol ordinal (numeric) value during linking of the application (assuming the dll is statically linked with using an import library during application linking). In this case the function(s) you replace need to be exported at the same ordinal values. I suggest you go ahead anyway but keep this point in the back of your head as a possible problem.

In fact, thinking about it, you may be able to do some clever trickery with the path and placement of the original and replacement dlls if use by other applications becomes problematic.

For example: place the replacement dll in the same directory as the application's exe and leave the original where it is (assuming it is not in this directory!). This presumes you can get LoadLibrary or LoadLibraryEx to load the original from a full pathname, and that you can determine what the full path to the original dll is.

If of course if you happen to have access to the source code of this application and can (re-) build it then you could just write and call the new add function as part of the application and re-build it.  

C++

All Answers


Answers by Expert:


Ask Experts

Volunteer


Ralph McArdell

Expertise

I am a software developer with more than 15 years C++ experience and over 25 years experience developing a wide variety of applications for Windows NT/2000/XP, UNIX, Linux and other platforms. I can help with basic to advanced C++, C (although I do not write just-C much if at all these days so maybe ask in the C section about purely C matters), software development and many platform specific and system development problems.

Experience

My career started in the mid 1980s working as a batch process operator for the now defunct Inner London Education Authority, working on Prime mini computers. I then moved into the role of Programmer / Analyst, also on the Primes, then into technical support and finally into the micro computing section, using a variety of 16 and 8 bit machines. Following the demise of the ILEA I worked for a small company, now gone, called Hodos. I worked on a part task train simulator using C and the Intel DVI (Digital Video Interactive) - the hardware based predecessor to Indeo. Other projects included a CGI based train simulator (different goals to the first), and various other projects in C and Visual Basic (er, version 1 that is). When Hodos went into receivership I went freelance and finally managed to start working in C++. I initially had contracts working on train simulators (surprise) and multimedia - I worked on many of the Dorling Kindersley CD-ROM titles and wrote the screensaver games for the Wallace and Gromit Cracking Animator CD. My more recent contracts have been more traditionally IT based, working predominately in C++ on MS Windows NT, 2000. XP, Linux and UN*X. These projects have had wide ranging additional skill sets including system analysis and design, databases and SQL in various guises, C#, client server and remoting, cross porting applications between platforms and various client development processes. I have an interest in the development of the C++ core language and libraries and try to keep up with at least some of the papers on the ISO C++ Standard Committee site at http://www.open-std.org/jtc1/sc22/wg21/.

Education/Credentials

©2016 About.com. All rights reserved.