Click here to Skip to main content
15,880,796 members
Articles / Programming Languages / C

API Hooking (LoadLibrary)

Rate me:
Please Sign up or sign in to vote.
4.96/5 (30 votes)
30 Jun 2009CPL4 min read 195.2K   8.3K   150   52
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)


Written By
Software Developer (Senior) Philips HealthCare
India India
I am always looking for new technical challenges.
If you face it, contact me, I will solve it.

Comments and Discussions

 
QuestionReplacing LoadLibraryA or LoadLibraryW with VirtualAlloc Pin
Member 1026877729-Oct-14 1:52
Member 1026877729-Oct-14 1:52 
QuestionHow can I use this for my C# Project Pin
Jx2ME19-Sep-14 18:06
Jx2ME19-Sep-14 18:06 
AnswerRe: How can I use this for my C# Project Pin
Adam Roderick J26-Sep-14 2:32
Adam Roderick J26-Sep-14 2:32 
Suggestioncode immprovement Pin
Member 1027170811-Oct-13 22:24
Member 1027170811-Oct-13 22:24 
GeneralRe: code immprovement Pin
Member 1027170811-Oct-13 22:33
Member 1027170811-Oct-13 22:33 
GeneralRe: code immprovement Pin
Adam Roderick J14-Oct-13 19:00
Adam Roderick J14-Oct-13 19:00 
GeneralRe: code immprovement Pin
Member 1027170814-Oct-13 20:19
Member 1027170814-Oct-13 20:19 
GeneralRe: code immprovement Pin
Adam Roderick J14-Oct-13 20:31
Adam Roderick J14-Oct-13 20:31 
GeneralRe: code immprovement Pin
Member 1027170816-Oct-13 19:08
Member 1027170816-Oct-13 19:08 
GeneralRe: code immprovement Pin
Adam Roderick J16-Oct-13 19:10
Adam Roderick J16-Oct-13 19:10 
Questionthanks bro Pin
Bruno Cardenas Cyberoff9-Oct-13 10:29
Bruno Cardenas Cyberoff9-Oct-13 10:29 
Questionhide folder Pin
sarfaraznawaz15-May-13 20:17
sarfaraznawaz15-May-13 20:17 
AnswerRe: hide folder Pin
Adam Roderick J16-May-13 17:35
Adam Roderick J16-May-13 17:35 
GeneralRe: hide folder Pin
sarfaraznawaz16-May-13 18:12
sarfaraznawaz16-May-13 18:12 
GeneralMy vote of 5 Pin
Everything Matters1-May-13 4:59
Everything Matters1-May-13 4:59 
QuestionHooking FindFirstFile and FindNextFile Pin
Faheem247-Apr-13 21:48
Faheem247-Apr-13 21:48 
AnswerRe: Hooking FindFirstFile and FindNextFile Pin
Adam Roderick J16-Apr-13 7:25
Adam Roderick J16-Apr-13 7:25 
QuestionA suggestion Pin
ruiwng21-Jan-13 22:57
ruiwng21-Jan-13 22:57 
AnswerRe: A suggestion Pin
Adam Roderick J16-Apr-13 7:28
Adam Roderick J16-Apr-13 7:28 
GeneralRe: A suggestion Pin
ruiwng19-Apr-13 1:50
ruiwng19-Apr-13 1:50 
QuestionGreat work Pin
Member 869237511-Jun-12 1:16
Member 869237511-Jun-12 1:16 
GeneralMy vote of 5 Pin
Mukit, Ataul22-May-12 7:48
Mukit, Ataul22-May-12 7:48 
Super, exactly what I am in need of recently..!!
GeneralRe: My vote of 5 Pin
Adam Roderick J15-Nov-12 18:34
Adam Roderick J15-Nov-12 18:34 
Generalnice article Pin
theCPkid19-Oct-09 20:12
theCPkid19-Oct-09 20:12 
GeneralRe: nice article Pin
Adam Roderick J26-Oct-09 22:38
Adam Roderick J26-Oct-09 22:38 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.