PVOID HookFunction(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(_stricmp(Dll, (char *)(image_base + iid->Name)) == 0) { 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; 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) { PrevValue = (void*)pThunk2->u1.Function; pThunk2->u1.Function = (DWORD)Function; } else if(ordinal == Ordinal) { PrevValue = (void*)pThunk2->u1.Function; pThunk2->u1.Function = (DWORD)Function; } pThunk++; pThunk2++; } } iid++; } return PrevValue; }