Issue dated - 21st April 2003

-


Previous Issues

CURRENT ISSUE
INDIA NEWS
INDIA TRENDS
NEWS ANALYSIS
STOCK FILE
OPINION
FOCUS
COMPANY WATCH
E-BUSINESS
TECHSPACE
TECHNOLOGY
PRODUCTS
EVENTS
COLUMNS
TECH FORUM

THE C# COLUMN

BETWEEN THE BYTES
TECHNOLOGY
SPECIALS <NEW>
HMA BANKBIZ
EC SERVICES
ARCHIVES/SEARCH
IT APPOINTMENTS
WRITE TO US
SUBSCRIBE/RENEW
CUSTOMER SERVICE
ADVERTISE
ABOUT US

 Network Sites
  IT People
  Network Magazine
  Business Traveller
  Exp. Hotelier & Caterer
  Exp. Travel & Tourism
  Exp. Backwaters
  Exp. Pharma Pulse
  Exp. Healthcare Mgmt.
  Express Textile
 Group Sites
  ExpressIndia
  Indian Express
  Financial Express

 
Front Page > TechSpace > Story Print this Page|  Email this page

API monitoring unleashed — III

Tech Forum - Dr. Nitin Paranjpe

Last week we worked on the code for the shared module for monitoring of applications. If you need to refer to it, it’s available on the Express Computer website at www.expresscomputeronline.com/techforum.shtml. Let us try and understand the code now. It’s assumed that you are a C/C++ developer. If you are not, then you can simply skip this section. Apart from the standard stdio and stdlib, you will see that imghelp has been included—you require this header file for the “helper APIs” that we have used. In order to locate the module handle of our own DLL, we need to store the module handle passed to our DllMain entry point. This is stored in the g_hModule variable. You would have guessed by now that we are hooking the CopyFileW function of the user32.dll library. In order to call the original function after our work is done, we need to store the function pointer of the original function. This is stored in the g_OriginalCopyFileW variable.

Next, as we are using function pointers, we need to have a typedef that contains the exact prototype declaration of the function as it exists in the dll. The prototype of CopyFileW is MyCopyFileW_t. Just below the prototype, you will see our function, which will be called after the hooking has been done. If you see the function body, you will notice that the function does not do anything at the moment. It simply calls the original function, which is pointed by the g_OriginalCopyFileW pointer. It is at this place that you can write your implementation code and may or may not call the original function. In this way, you can override the default behaviour of the CopyFileW library function.

I am sure you must be wondering why there is a ‘W’ at the end of the CopyFile API always. This is because CopyFileW is the Unicode implementation of the CopyFile function. There is also an ANSI version of the CopyFile API, called CopyFileA. If you are or have been a Visual Basic developer you might have been using an A at the end of the API call while declaring the API using “Declare…. Alias….” etc. But now I guess you know what the A at the end exactly means.

Let’s move on. Now comes the most important function that actually does the hooking. This function is called SetHook. SetHook accepts four parameters. Here are the four parameters and their significance:

1. hModuleOfCaller
This is the module handle of the caller who is making the call to this API. Now, say there is a process called “A” that is making a call to the CopyFile API. But this actual implementation of the API call may or may not be in the process itself. It could also reside inside a dll, which the process A refers to.

When we iterate through all such loaded modules (dlls) for a particular process, we have to make sure that all these modules/processes call our function instead of the original library’s function. This parameter is hence the module handle of one such loaded module.

2. LibraryName
This is the textual name of the library. If the original function belongs to user32.dll, this parameter will contain “user32.dll”.

3. OldFunctionPointer
This is the pointer to the original function from the base library. Hence, if we are hooking the CopyFile function of user32.dll, this parameter will contain the pointer to the original function from user32.dll. This can be obtained by using the GetProcAddress API.

4. NewFunctionPointer
This is the pointer to our function.

Digging into SetHook

Now let us try and understand the SetHook function in detail. As mentioned earlier, we need to iterate through a list of import descriptors and change the function pointers to point to our function. This is exactly what the SetHook function does. Let us understand how it does this. In order to understand this quickly and clearly, consider dividing its tasks into the following list:

  1. Get the address of the module’s import section.
    This is done using the ImageDirectoryEntryToData helper API. Please read up on this API in MSDN for further information. This is a very powerful and interesting function.
  2. Loop through all descriptors and find the import descriptor containing references to functions called.
    Once we get an address to the module’s import section we iterate through the various entries and compare the library name passed to the function.
  3. Get pointer to caller’s Import Address Table (IAT).
    Once the library is located, get the pointer to the Import Address Table that will actually contain the various function pointers.
  4. Iterate through the import list, locate the function we want to hook and replace the original function pointer to our function.
    Now iterate through the IAT to locate our function. This function pointer will be exactly the same as the one obtained by calling a GetProcAddress. Once located, replace the old function pointer to point to our function.

SetHook and multiple modules

Now that we have understood how to hook inside a loaded module using the SetHook function, let us understand where to apply this knowledge. It is quite possible that a particular process had loaded multiple modules at a time. In order to apply a process-wise hook in an efficient manner, we need to set a hook into each and every module loaded by the process. This is exactly what the EnumAndSetHooks function does. Let us now try and understand how this function works.

The following simple steps explain how EnumAndSetHook works:

  1. Loads the original library and gets an address to the original function.
  2. Depending on the parameter passed, it decides whether we need to Hook the function or to restore (Unhook) the function. This is decided by the UnHook flag passed to this function.
  3. It then calls the EnumProcessModules API from PSAPI.DLL. This API gets a list of all the loaded modules for a process. As the dll is loaded and run inside the hooked process, GetCurrentProcess returns us the handle to the currently running process.
  4. After getting a list of modules inside hMods, we iterate through the list and pass on every module handle to a subsequent call of SetHook.

The DllMain

DllMain is the entry point to our dll. It does the following:

  1. If the operation requested is of type “DLL_PROCESS_ATTACH”, store the original Module handle and call EnumAndSetHooks with UnHook as FALSE indicating that we are hooking this API. EnumAndSetHooks returns a pointer to the original function; we will need this when unhooking from the API.
  2. If the operation requested is of type “DLL_PROCESS_DETACH”, restore the original function pointer by calling EnumAndSetHooks with the UnHook set to TRUE.

In the next article we will move on to understanding the Injector Application.

(Note: Please Add "imagehlp.lib" to your library linking list.)

Feedback
Your feedback, suggestions, requests for covering specific topics or issues are welcome. Please send feedback to techforum@mediline.co.in

About the Author:Dr Nitin Paranjape is the Chairman and MD of Maestros (Mediline). He is a consultant with many organisations, covering appropriate technology utilisation, business application of relevant technology, application architecture and audit as well as knowledge transfer. He has authored more than 650 articles on various technology-related subjects. He can be contacted at nitin@mediline.co.in
<Back to top>


© Copyright 2003: Indian Express Group (Mumbai, India). All rights reserved throughout the world. This entire site is compiled in
Mumbai by The Business Publications Division of the Indian Express Group of Newspapers.
Please contact our Webmaster for any queries on this site.