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:
- Injecting a DLL using registry
- Injecting a DLL using Windows hook
- Injecting a DLL using remote thread
- Injecting a DLL with Trojan DLL
- 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:
- APIHandler.exe: This EXE will inject DLL into some other application with the help of DLLCheck.dll.
- DLLCheck.dll: DLL to be injected into third party application.
- 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:
HANDLE hProc;
pLibRemote = ::VirtualAllocEx( hProcess,
NULL, sizeof(szLibPath), MEM_COMMIT, PAGE_READWRITE );
::WriteProcessMemory( hProcess, pLibRemote, (void*)szLibPath,
sizeof( szLibPath ), NULL );
hThread = ::CreateRemoteThread( hProcess, NULL, 0,
(LPTHREAD_START_ROUTINE)::GetProcAddress( hKernel32,"LoadLibraryA" ),
pLibRemote,0,NULL );
IMAGE_IMPORT_DESCRIPTOR* GetImportDescriptor(HMODULE hMod, char* pszDllName )
{
IMAGE_DOS_HEADER* pDOSHeader = (IMAGE_DOS_HEADER*)hMod;
IMAGE_OPTIONAL_HEADER* pOptionHeader = (IMAGE_OPTIONAL_HEADER*)((BYTE*)hMod +
pDOSHeader->e_lfanew + 24);
IMAGE_IMPORT_DESCRIPTOR* pImportDesc = (IMAGE_IMPORT_DESCRIPTOR*)((BYTE*)hMod +
OptionHeader->DataDirectory[ IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
char* pszImpAddr = 0;
while( pImportDesc->FirstThunk)
{
pszImpAddr = (char*)(( BYTE* )hMod+ pImportDesc->Name );
if( stricmp( pszDllName, pszImpAddr ))
{
pImportDesc++;
continue;
}
else
{
return pImportDesc;
}
}
return NULL;
}
DWORD* GetCurrentFunctAddr( HMODULE hMod,
IMAGE_THUNK_DATA* pOriginalFirstThunk,
IMAGE_THUNK_DATA* pFirstThunk,
char* pszFunctionName )
{
char* szTest;
while(pOriginalFirstThunk->u1.Function)
{
szTest = (char*)((BYTE*)hMod +
(DWORD)pOriginalFirstThunk->u1.AddressOfData+2);
if(stricmp(pszFunctionName,szTest)==0)
{
return &pFirstThunk->u1.Function;
}
pOriginalFirstThunk++;
pFirstThunk++;
}
return NULL;
}
bool ChangeAddress(DWORD* dwOldAddress,DWORD dwNewAddress)
{
DWORD dwOld;
if (!(VirtualProtect(dwOldAddress,4,PAGE_READWRITE,&dwOld)))
{
return false;
}
*dwOldAddress = dwNewAddress;
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