if ( cFuncs == 0 ) // If no imported functions, we're done!
return false;
// These next few lines ensure that we'll be able to modify the IAT,
// which is often in a read-only section in the EXE.
DWORD flOldProtect, flNewProtect, flDontCare;
MEMORY_BASIC_INFORMATION mbi;
// Get the current protection attributes
VirtualQuery( pIAT, &mbi, sizeof(mbi) );
// remove ReadOnly and ExecuteRead attributes, add on ReadWrite flag
flNewProtect = mbi.Protect;
flNewProtect &= ~(PAGE_READONLY | PAGE_EXECUTE_READ);
flNewProtect |= (PAGE_READWRITE);
// If the Default hook is enabled, build an array of redirection stubs in the processes memory.
DLPD_IAT_STUB * pStubs = 0;
if ( DLLHook->UseDefault )
{
// Allocate memory for the redirection stubs. Make one extra stub at the
// end to be a sentinel
pStubs = new DLPD_IAT_STUB[ cFuncs + 1];
if ( !pStubs )
return false;
}
// Scan through the IAT, completing the stubs and redirecting the IAT
// entries to point to the stubs
pIteratingIAT = pIAT;
char sztest2[10];
itoa(*pIteratingIAT->u1.Function,sztest2,16);
WriteToFile("3");
WriteToFile("\r\n");
WriteToFile(sztest2);
WriteToFile("\r\n");
while ( pIteratingIAT->u1.Function )
{
char sztest4[10];
itoa(*pIteratingIAT->u1.Function,sztest4,16);
WriteToFile("4");
WriteToFile("\r\n");
WriteToFile(sztest4);
WriteToFile("\r\n");
void* HookFn = 0; // Set to either the SFunctionHook or pStubs.
if ( !IMAGE_SNAP_BY_ORDINAL( pINT->u1.Ordinal ) ) // import by name
{
PIMAGE_IMPORT_BY_NAME pImportName = MakePtr( PIMAGE_IMPORT_BY_NAME, pBaseLoadAddr, pINT->u1.AddressOfData );
// Iterate through the hook functions, searching for this import.
SFunctionHook* FHook = DLLHook->Functions;
// Save the old function in the SFunctionHook structure and get the new one.
FHook->OrigFn = reinterpret_cast<void*>(pIteratingIAT->u1.Function);
HookFn = FHook->HookFn;
break;
}
FHook++;
}
// If the default function is enabled, store the name for the user.
if ( DLLHook->UseDefault )
{
pStubs->pszNameOrOrdinal = (DWORD)&pImportName->Name;
}
}
else
{
// If the default function is enabled, store the ordinal for the user.
if ( DLLHook->UseDefault )
{
pStubs->pszNameOrOrdinal = pINT->u1.Ordinal;
}
}
// If the default function is enabled, fill in the fields to the stub code.
if ( DLLHook->UseDefault )
{
pStubs->data_call = (DWORD)(PDWORD)DLLHook->DefaultFn
- (DWORD)(PDWORD)&pStubs->instr_JMP;
pStubs->data_JMP = *(PDWORD)pIteratingIAT - (DWORD)(PDWORD)&pStubs->count;
// If it wasn't manually hooked, use the Stub function.
if ( !HookFn )
{
HookFn = (void*)pStubs;
}
}
// Replace the IAT function pointer if we have a hook.
if ( HookFn )
{
// Cheez-o hack to see if what we're importing is code or data.
// If it's code, we shouldn't be able to write to it
if ( IsBadWritePtr( (PVOID)pIteratingIAT->u1.Function, 1 ) )
{
}
else if ( osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
{
// Special hack for Win9X, which builds stubs for imported
// functions in system DLLs (Loaded above 2GB). These stubs are
// writeable, so we have to explicitly check for this case
// if ( pIteratingIAT->u1.Function > 0x80000000 )
// pIteratingIAT->u1.Function = reinterpret_cast<DWORD>(HookFn);
}
}
if ( DLLHook->UseDefault )
{
pStubs++; // Advance to next stub
}
pIteratingIAT++; // Advance to next IAT entry
pINT++; // Advance to next INT entry
if ( DLLHook->UseDefault )
{
pStubs->pszNameOrOrdinal = 0; // Final stub is a sentinel
}
// Put the page attributes back the way they were.
VirtualProtect( pIAT, sizeof(PVOID) * cFuncs, flOldProtect, &flDontCare);
return true;
}
//===========================================================================
// Top level routine to find the EXE's imports, and redirect them
bool HookAPICalls( SDLLHook* Hook )
{
if ( !Hook )
return false;
// Convert imports RVA to a usable pointer
PIMAGE_IMPORT_DESCRIPTOR pImportDesc = MakePtr( PIMAGE_IMPORT_DESCRIPTOR,
hModEXE, importRVA );
// Save off imports address in a global for later use
g_pFirstImportDesc = pImportDesc;
// Iterate through each import descriptor, and redirect if appropriate
while ( pImportDesc->FirstThunk )
{
PSTR pszImportModuleName = MakePtr( PSTR, hModEXE, pImportDesc->Name);
if ( lstrcmpi( pszImportModuleName, Hook->Name ) == 0 )
{