Click here to Skip to main content
6,629,885 members and growing! (22,046 online)
Email Password   helpLost your password?
General Programming » Threads, Processes & IPC » Inter-Process Communication License: The Common Public License Version 1.0 (CPL)

API Hooking (LoadLibrary)

By Adam Roderick J 09

A simple approach to Hook LoadLibrary API with a sample
C++ (VC6, VC7, VC7.1, VC8.0), C++/CLI, C
Version:18 (See All)
Posted:29 Jun 2009
Updated:30 Jun 2009
Views:9,359
Bookmarked:52 times
Announcements
Loading...
 
Search    
Advanced Search
Add to IE Search
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
19 votes for this article.
Popularity: 5.73 Rating: 4.48 out of 5
1 vote, 5.3%
1

2
2 votes, 10.5%
3
1 vote, 5.3%
4
15 votes, 78.9%
5

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:

// 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 );
// This API writes the library path name to third party process.
 ::WriteProcessMemory( hProcess, pLibRemote, (void*)szLibPath,
                       sizeof( szLibPath ), NULL ); 
// 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 );
// The below mentioned code is from Injected DLL part, i.e. DLLCheck.DLL 
// 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.
// 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;
}
// 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;
}
// 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)

About the Author

Adam Roderick J 09


Member
He started his career with Turbo c as a instructor, in a small computer education centre. Then he became a programmer in C++, VC++. He spends most of his time in learning and getting new information about the current domain and technology. He always do programming and likes making reusable tools. He spends some of his time in other interests which includes cooking, bodybuilding and sleeping. He sleeps when he finds hard to get a solution to some problem. He believes in god and faith.
He is too enthusiastic and confident to get his goal in life. He believe in one of the motivation quotes from Samuel Johnson
"Great works are performed, not by strength, but by perseverance."
He is now working hard to get a better job than the current one.
Occupation: Instructor / Trainer
Location: Russian Federation Russian Federation

Other popular Threads, Processes & IPC articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 25 of 27 (Total in Forum: 27) (Refresh)FirstPrevNext
Generalnice article PinmembertheCPkid21:12 19 Oct '09  
GeneralRe: nice article PinmemberAdam Roderick J 0923:38 26 Oct '09  
GeneralMy vote of 1 PinmemberRedDK19:27 7 Jul '09  
GeneralRe: My vote of 1 PinmemberARJ 198219:34 7 Jul '09  
GeneralRe: My vote of 1 PinmemberRedDK8:12 14 Jul '09  
Generalhook TerminateProcess and ExitProcess didn't work Pinmemberbtb3680:27 7 Jul '09  
GeneralRe: hook TerminateProcess and ExitProcess didn't work PinmemberARJ 19824:02 7 Jul '09  
GeneralRe: hook TerminateProcess and ExitProcess didn't work Pinmemberbtb36816:13 7 Jul '09  
GeneralRe: hook TerminateProcess and ExitProcess didn't work PinmemberARJ 198218:49 7 Jul '09  
GeneralRe: hook TerminateProcess and ExitProcess didn't work Pinmemberbtb36821:52 7 Jul '09  
GeneralRe: hook TerminateProcess and ExitProcess didn't work [modified] PinmemberARJ 198222:48 7 Jul '09  
GeneralRe: hook TerminateProcess and ExitProcess didn't work Pinmemberbtb36823:44 7 Jul '09  
GeneralRe: hook TerminateProcess and ExitProcess didn't work PinmemberARJ 198219:42 8 Jul '09  
GeneralRe: hook TerminateProcess and ExitProcess didn't work Pinmemberbtb36821:11 8 Jul '09  
GeneralRe: hook TerminateProcess and ExitProcess didn't work PinmemberARJ 198223:03 8 Jul '09  
GeneralRe: hook TerminateProcess and ExitProcess didn't work Pinmemberbtb36823:25 8 Jul '09  
GeneralGreat article!!! Pinmembersasusk34:27 2 Jul '09  
GeneralRe: Great article!!! PinmemberARJ 19823:07 4 Jul '09  
GeneralHow about Exttextout? Pinmembercrystalicetpmc5:22 30 Jun '09  
GeneralRe: How about Exttextout? PinmemberARJ 19823:05 1 Jul '09  
GeneralRe: How about Exttextout? Pinmembercrystalicetpmc3:56 1 Jul '09  
GeneralRe: How about Exttextout? PinmemberARJ 19823:19 2 Jul '09  
GeneralRe: How about Exttextout? Pinmembercrystalicetpmc12:18 3 Jul '09  
GeneralMy vote of 2 PinmemberEric Haddan15:28 29 Jun '09  
GeneralRe: My vote of 2 PinmemberARJ 19822:27 30 Jun '09  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 30 Jun 2009
Editor: Deeksha Shenoy
Copyright 2009 by Adam Roderick J 09
Everything else Copyright © CodeProject, 1999-2009
Web20 | Advertise on the Code Project