|
API monitoring unleashed — II
TechForum - Dr. Nitin Paranjpe
Continuing
from where we left off last week, we will plunge right into the
Shared Module. This is a Windows Dynamic Link Library, a very simple
DLL that contains the overridden code as well as the actual injection
code. Why do we need the Injector Application if this DLL is doing
the injection part? We need the application for the simple reason
that DLLs cant run by themselves. Another reason is that the
injector application is the one that will create memory, load the
DLL, etc, inside the remote processes space.
Now, let us see how to write such a DLL
in MS VC++ 6.0:
Just follow the following steps; they are
so simple that even if you have never used a VC++ IDE, you can still
create the DLL and write the corresponding code very easily:
1. Start VC++ IDE. Select the Project template
(from the Projects Tab) as Win32 Dynamic-Link Library.
DO NOT touch any other settings or checkboxes. Enter the Project
Name as SharedModule as shown in Figure 1.

2. Now, select the Project type as A
simple DLL project as shown in Figure 2.

3. Now, the wizard will create the files
for you and inject the basic code. Open the file view from the Workspace
View. If workspace view is not visible, press ALT+0.
4. From the file view, double-click on
the SharedModule.cpp file. This file will be visible under the Source
Files tree.
5. Add the following code just below the
#include stdafx.h line. There will be a point-by-point
explanation of the code after we have finished all the steps.
#include <stdio.h>
#include <imagehlp.h>
#include <stdlib.h>
HANDLE g_hModule = INVALID_HANDLE_VALUE;
PROC g_OriginalCopyFileW;
typedef BOOL WINAPI MyCopyFileW_t(
LPCWSTR lpExistingFileName,
LPCWSTR lpNewFileName,
BOOL bFailIfExists
);
BOOL WINAPI MyCopyFileW(
LPCWSTR lpExistingFileName,
LPCWSTR lpNewFileName,
BOOL bFailIfExists
)
{
BOOL ReturnValue;
MyCopyFileW_t* fn = (MyCopyFileW_t*)g_OriginalCopyFileW;
ReturnValue = (*fn)(lpExistingFileName,
lpNewFileName,
bFailIfExists);
return ReturnValue;
}
void SetHook(HMODULE hModuleOfCaller, LPSTR LibraryName,
PROC OldFunctionPointer, PROC NewFunctionPointer)
{
if(hModuleOfCaller == g_hModule)
return;
if(hModuleOfCaller == 0)
return;
ULONG ulSize;
// Get the address of the modules import section
PIMAGE_IMPORT_DESCRIPTOR pImportDesc =
(PIMAGE_IMPORT_DESCRIPTOR)
ImageDirectoryEntryToData(
hModuleOfCaller,
TRUE,
IMAGE_DIRECTORY_ENTRY_IMPORT,
&ulSize
);
// Does this module have an import section ?
if (pImportDesc == NULL)
return;
// Loop through all descriptors and find the
// import descriptor containing references to callees functions
while (pImportDesc->Name)
{
PSTR pszModName = (PSTR)((PBYTE) hModuleOfCaller +
pImportDesc->Name);
if (stricmp(pszModName, LibraryName) == 0)
break; // Found
pImportDesc++;
} // while
if (pImportDesc->Name == 0)
return;
// Get callers IAT
PIMAGE_THUNK_DATA pThunk =
(PIMAGE_THUNK_DATA)( (PBYTE) hModuleOfCaller +
pImportDesc->FirstThunk );
PROC pfnCurrent = OldFunctionPointer;
// Replace current function address with new one
while (pThunk->u1.Function)
{
// Get the address of the function address
PROC* ppfn = (PROC*) &pThunk->u1.Function;
// Is this the function were looking for?
BOOL bFound = (*ppfn == pfnCurrent);
if (bFound)
{
MEMORY_BASIC_INFORMATION mbi;
::VirtualQuery(ppfn, &mbi,
sizeof(MEMORY_BASIC_INFORMATION));
// In order to provide writable access to this part of the
// memory we need to change the memory protection
if (FALSE == ::VirtualProtect(
mbi.BaseAddress,
mbi.RegionSize,
PAGE_READWRITE,
&mbi.Protect)
)
return;
*ppfn = *NewFunctionPointer;
BOOL bResult = TRUE;
// Restore the protection back
DWORD dwOldProtect;
::VirtualProtect(
mbi.BaseAddress,
mbi.RegionSize,
mbi.Protect,
&dwOldProtect
);
break;
} // if
pThunk++;
} // while
}
PROC EnumAndSetHooks(LPSTR BaseLibraryName, LPSTR BaseFunctionName,
PROC NewFunctionPointer, bool UnHook, PROC Custom)
{
HMODULE hMods[1024];
DWORD cbNeeded;
unsigned int i;
typedef BOOL (WINAPI * PFNENUMPROCESSMODULES)(
HANDLE hProcess,
HMODULE *lphModule,
DWORD cb,
LPDWORD lpcbNeeded
);
HMODULE hBaseLib = LoadLibrary(BaseLibraryName);
PROC hBaseProc;
if(UnHook)
hBaseProc = (PROC) Custom;
else
hBaseProc = GetProcAddress(hBaseLib, BaseFunctionName);
PFNENUMPROCESSMODULES m_pfnEnumProcessModules;
HMODULE m_hModPSAPI = ::LoadLibraryA(PSAPI.DLL);
m_pfnEnumProcessModules = (PFNENUMPROCESSMODULES)
::GetProcAddress(m_hModPSAPI, EnumProcessModules);
HANDLE hProcess = ::GetCurrentProcess();
if( m_pfnEnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
{
for ( i = 0; i < (cbNeeded / sizeof(HMODULE)); i++ )
{
SetHook(hMods[i], BaseLibraryName, hBaseProc, NewFunctionPointer);
}
}
return hBaseProc;
}
6. After you have copy-pasted the code, modify the DllMain function
as shown below. If you find that difficult simply remove the DllMain
function and copy-paste the function given below directly inside
the CPP file:
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
g_hModule = hModule;
g_OriginalCopyFileW = EnumAndSetHooks(KERNEL32.DLL,
CopyFileW, (PROC) MyCopyFileW, false, 0);
case DLL_PROCESS_DETACH:
EnumAndSetHooks(KERNEL32.DLL, CopyFileW,
(PROC) GetProcAddress(LoadLibrary(KERNEL32),CopyFileW),
true, (PROC) MyCopyFileW);
break;
}
return TRUE;
}
Now compile the application, it should
successfully compile and generate the DLL. If it fails, please feel
free to send me a dump of the error log. Please send it to paragp@mediline.co.in
In the next article I will explain the
above code and we can then move ahead to writing the code for the
injector application.
(Note: Please Add "imagehlp.lib"
to your library linking list.)
 |
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 |
|