Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C

API Hooking (LoadLibrary)

4.96/5 (30 votes)
30 Jun 2009CPL4 min read 202K   8.4K  
A simple approach to Hook LoadLibrary API with a sample

Introduction

If Windows is made to protect against API hooking, Trojan horses would not have effected our systems. I believe it is a loop hole from Microsoft. But from a programmer's point of view, it is a kernel level approach to PE (Portable executable) signature modification. API Hooking is one of the most crooked methods to get all the information of an executable without modifying its code. Firstly I will remind you about one thing, never ever use any content of my article for wrong purposes.

Before going to API hooking, you need to know about DLL Injection, which is a primary step for API hooking. In normal conditions, you cannot create a pointer that is referenced to another process. To achieve this, we need to inject our code into another process.

Let us familiarize ourselves with DLL Injection. DLL injection is a technique by which you can inject your own DLL into a third party executable without modifying the third party executable’s code. DLL Injection can be achieved in a number of methods, they are:

  1. Injecting a DLL using registry
  2. Injecting a DLL using Windows hook
  3. Injecting a DLL using remote thread
  4. Injecting a DLL with Trojan DLL
  5. Injecting a DLL as a debugger

Well for this article, we are just dealing with method 3, i.e., injecting a DLL using remote thread.

Background

In this technique, we have to load our DLL into a third party process with the help of LoadLibrary API of Kernel32.dll. The main difficulty in loading a DLL into another process is that, you cannot control the third party process’s thread. It is necessary for us to create our own thread in that process, for this Windows itself provides the WINAPI CreateRemoteThread, where we can specify the destination process handle as a parameter. I will give you a detailed explanation about the APIs and their use in the code section.

To explain API hooking technique, I am introducing 3 components in the sample attached with this article that will explain how to hook an API. Here I am hooking the API LoadLibrary (LoadLibraryA). Three components that are attached with this article are:

  1. APIHandler.exe: This EXE will inject DLL into some other application with the help of DLLCheck.dll.
  2. DLLCheck.dll: DLL to be injected into third party application.
  3. SampleUsingLoadLibrary.exe: Third party application, actually this application is hooked.

APIHandler.exe has the DLL path (give the path of DLL to be injected) and Injected EXE is the EXE to which our DLL is to be injected. Once our DLL is injected, it will work such that, it the part of SampleUsingLoadLibrary.exe.

The method is a little twisted, once DLLCheck.dll is injected into the EXE, the next job for the DLLCheck.DLL is to find the address of the function name (LoadLibrary) to be hooked. It can be achieved by parsing the PE file (our executable SampleUsingLoadLibrary.exe) and finding IMAGE_IMPORT_DESCRIPTOR (this data structure holds the import table information of the PE file) of Kernel32.dll inside the executable, which holds the address of LoadLibrary in our case.

Once we get the address of LoadLibrary API of the kernel32 loaded in the EXE, the next step is to find the address (using GetCurrentFunctAddr of DLLCheck.dll, refer to the code section) of our native API (MyFunction) and replace the load address using VirtualProtect WinAPI, which makes the function address changing possible inside a remote thread without the protection fault error.

Once the above mentioned steps are done, our function will have the loaded address of LoadLibrary API inside the third party EXE, so whenever a call to LoadLibrary function of Kernel32.dll is invoked inside that third party EXE, under the hood, our function will be invoked, i.e. our MyFunction API, since address is changed in PE. These are based on modifying the PE(Portable Executable) signature of EXE. We modified the IMPORT table of Kernel32.dll loaded inside our executable. Very simple and effective method. To understand more, let us go in detail with the code.

Using the Code

This code explains the stages of the API redirection:

C++
// To Inject a DLL, we need three steps in APIHandler side.
// Allocate memory in the remote process for our library
// with write permission using the below mentioned WINAPI.
HANDLE hProc;
pLibRemote = ::VirtualAllocEx( hProcess,
NULL, sizeof(szLibPath), MEM_COMMIT, PAGE_READWRITE );
C++
// This API writes the library path name to third party process.
 ::WriteProcessMemory( hProcess, pLibRemote, (void*)szLibPath,
                       sizeof( szLibPath ), NULL ); 
C++
// Load the DLL to third party process by creating a thread in that
// process, using the below mentioned WIN API, this API enable
hThread = ::CreateRemoteThread( hProcess, NULL, 0,
      (LPTHREAD_START_ROUTINE)::GetProcAddress( hKernel32,"LoadLibraryA" ),
                    pLibRemote,0,NULL );
C++
// The below mentioned code is from Injected DLL part, i.e. DLLCheck.DLL 
C++
// To redirect LoadLibrary API with our MyFunction we have do certain steps
// We have parse the PE file of third party EXE and find the import table and find
// the address of the Loadlibrary API in reference to the executable base address.
C++
// This function gets the address of the import descriptor table.
IMAGE_IMPORT_DESCRIPTOR* GetImportDescriptor(HMODULE hMod, char* pszDllName )
{
  // Get the DOS Header from which we can get the optional header.
  IMAGE_DOS_HEADER* pDOSHeader = (IMAGE_DOS_HEADER*)hMod;
  IMAGE_OPTIONAL_HEADER* pOptionHeader = (IMAGE_OPTIONAL_HEADER*)((BYTE*)hMod +
                                       pDOSHeader->e_lfanew + 24);
  // To get the IMport descriptor datastructure.
  IMAGE_IMPORT_DESCRIPTOR* pImportDesc = (IMAGE_IMPORT_DESCRIPTOR*)((BYTE*)hMod +
  OptionHeader->DataDirectory[ IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
  char* pszImpAddr = 0;
  // Iterate through the IMPORT DESCRIPTOR till we find the address of
  // Kernel32.dll in our case, since LoadLibrary is from Kernel32.dll
  while( pImportDesc->FirstThunk)
  {
   // Get the load address of the DLL.
   pszImpAddr = (char*)(( BYTE* )hMod+ pImportDesc->Name );
   if( stricmp( pszDllName, pszImpAddr ))
   {
    pImportDesc++;
    continue;
   }
   else
   {
    return pImportDesc;
   }
  }
  return NULL;
}
C++
// This function gets the address of the LoadLibraryA function.
DWORD* GetCurrentFunctAddr(  HMODULE hMod,
        IMAGE_THUNK_DATA* pOriginalFirstThunk,
        IMAGE_THUNK_DATA* pFirstThunk,
        char* pszFunctionName )
{
   // From the IMAGE thunk datastructure we
   // get the address of the imported function.
   char* szTest;
   while(pOriginalFirstThunk->u1.Function)
   {
      // Get the import load address of the function,
      // in our case LoadLibraryA.
      szTest = (char*)((BYTE*)hMod +
                    (DWORD)pOriginalFirstThunk->u1.AddressOfData+2);
      if(stricmp(pszFunctionName,szTest)==0)
     {
        return &pFirstThunk->u1.Function;
     }
     pOriginalFirstThunk++;
     pFirstThunk++;
   }
   return NULL;
}
C++
// Once address is found, we have to redirect using the VirtualProtect WinAPI
// that enables write permission to third party EXE.

bool ChangeAddress(DWORD* dwOldAddress,DWORD dwNewAddress)
{
  // Change the old address of the function with the new address.
  // Firstly this address is changed.
  DWORD dwOld;
  if (!(VirtualProtect(dwOldAddress,4,PAGE_READWRITE,&dwOld)))
  {
      return false;
  }
  *dwOldAddress = dwNewAddress;
  // Once changed it updated in the executable.
  if (!(VirtualProtect(dwOldAddress,4,PAGE_EXECUTE,&dwOld)))
  {
      return false;
  }
  else
  {
      OutputDebugString( "Change Address Final.." );
      return true;
  }
}

Points of Interest

API hooking is one of the most widely used techniques by hackers for creating Trojan, which will help them keep track of the system information, and anti virus companies around the globe use the low level API hooking to make antispyware. My intention with this article is just to make you familiar with API hooking and the vulnerabilities that are in your system without your prior knowledge. My article explained a useful API hooking, which will help you to keep track of the libraries that are loaded using LoadLibrary API in a particular EXE, which is never possible with a dependency walker. This is an ASCII version that will hook only LoadLibraryA. If you want to hook Unicode DLLs, then hook LoadlbraryW.

If you have any doubts, please feel free to ask me, if my Allah gives me the opportunity, I will write more articles of your interest.

History

  • Version 1.0

License

This article, along with any associated source code and files, is licensed under The Common Public License Version 1.0 (CPL)