This is what I use in StuffPlug:
code:
void *HookImportedFunction(const char *Dll, const char *FuncName, int Ordinal, void *Function)
{
DWORD oldProtect;
void *PrevValue=0;
DWORD image_base = (DWORD)GetModuleHandle(NULL);
IMAGE_DOS_HEADER *idh = (IMAGE_DOS_HEADER *)image_base;
IMAGE_FILE_HEADER *ifh = (IMAGE_FILE_HEADER *)(image_base +
idh->e_lfanew + sizeof(DWORD));
IMAGE_OPTIONAL_HEADER *ioh = (IMAGE_OPTIONAL_HEADER *)((DWORD)(ifh) +
sizeof(IMAGE_FILE_HEADER));
IMAGE_IMPORT_DESCRIPTOR *iid = (IMAGE_IMPORT_DESCRIPTOR *)(image_base +
ioh->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
VirtualProtect((LPVOID)(image_base +
ioh->DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress),
ioh->DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size, PAGE_READWRITE,
&oldProtect);
while(iid->Name)
{
if(lstrcmpiA(Dll, (char *)(image_base + iid->Name)) == 0)
{
//trace_printf("Found descriptor: %s\n", dhook->name);
IMAGE_THUNK_DATA * pThunk = (IMAGE_THUNK_DATA *)
((DWORD)iid->OriginalFirstThunk + image_base);
IMAGE_THUNK_DATA * pThunk2 = (IMAGE_THUNK_DATA *)
((DWORD)iid->FirstThunk + image_base);
while(pThunk->u1.AddressOfData)
{
char * name = 0;
int ordinal;
// Imported by ordinal only:
if(pThunk->u1.Ordinal & 0x80000000)
ordinal = pThunk->u1.Ordinal & 0xffff;
else // Imported by name, with ordinal hint
{
IMAGE_IMPORT_BY_NAME * pname = (IMAGE_IMPORT_BY_NAME *)
((DWORD)pThunk->u1.AddressOfData + image_base);
ordinal = pname->Hint;
name = (char *)pname->Name;
}
if(name != 0 && FuncName && strcmp(name, FuncName) == 0)
{
//trace_printf("Found entry name: %s\n", ehook->name);
PrevValue = (void*)pThunk2->u1.Function;
pThunk2->u1.Function = (DWORD)Function;
}
else if(ordinal == Ordinal)
{
//trace_printf("Found entry ordinal: %s\n", ehook->name);
PrevValue = (void*)pThunk2->u1.Function;
pThunk2->u1.Function = (DWORD)Function;
}
pThunk++;
pThunk2++;
}
}
iid++;
}
return PrevValue;
}