динамическая загрузка в Windows 7 не удается - PullRequest
2 голосов
/ 21 декабря 2009

Как я уже упоминал в одном из моих предыдущих вопросов, я играю с имитацией GetProcAddress () в моем коде. Следующий код успешно делает это, однако он вызывает сбой приложения в Windows 7

void *GetFuncAddr(HMODULE hModule, char *fname) 
{
    unsigned int count = 1;
    IMAGE_DOS_HEADER *DosHeader;
    IMAGE_NT_HEADERS *NtHeaders;
    IMAGE_OPTIONAL_HEADER *OptionalHeader;
    IMAGE_DATA_DIRECTORY *DataDirectory;
    IMAGE_EXPORT_DIRECTORY *Exp;
    ULONG *addrof;
    char *fullfname;
    ULONG *faddr;

    DosHeader = (IMAGE_DOS_HEADER *)hModule; 
    if (DosHeader->e_magic != IMAGE_DOS_SIGNATURE) 
    { 
        return NULL;
    } 

    NtHeaders = (IMAGE_NT_HEADERS *)(((BYTE *)DosHeader) + DosHeader->e_lfanew); 
    if (NtHeaders->Signature != IMAGE_NT_SIGNATURE)
    { 
        return NULL;
    } 

    OptionalHeader = &NtHeaders->OptionalHeader; 
    DataDirectory = &OptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; 

    Exp = (IMAGE_EXPORT_DIRECTORY *)((size_t)DosHeader + DataDirectory->VirtualAddress); 

    addrof = (ULONG *)((BYTE*) hModule + Exp->addrof);
    faddr = (ULONG*) ((BYTE*) hModule + Exp->AddressOfFunctions);

    for(count = 0; count < Exp->NumberOfNames; count++)
    {
        fullfname = (char*)((BYTE*) hModule + addrof[count]);       
        if(strcmp(fullfname, fname) == 0)
        {   
            return (void*)((BYTE*) hModule + faddr[count]);
        }
    }

    return NULL;
}   

Неважно, какую функцию я пытался загрузить, с помощью этого приложения происходит сбой. Сбои происходят при вызове импортированной функции, так что я предполагаю, что возвращаемый указатель может быть оскорбительным. Это происходит как на x86, так и на x64. Есть ли видимая причина этого в этом коде?

Я попытался настроить функцию для возврата FARPROC, но я все путаюсь в том, как привести возвращение к ((BYTE *) hModule + faddr [count]);

В любом случае, есть идеи? решения? Любая помощь приветствуется.

Спасибо. Джесс.

РЕДАКТИРОВАТЬ Ошибка, возвращаемая некоторыми API-интерфейсами, которые я импортирую, является ошибкой 18, параметр неверен.

Ответы [ 3 ]

4 голосов
/ 22 декабря 2009

Я думаю, что вам, возможно, потребуется выполнить дополнительный поиск.

USHORT *ford;
...
ford = (USHORT*) ((BYTE*) hModule + Exp->AddressOfNameOrdinals);

, а затем смещение по порядковому номеру:

            return (void*)((BYTE*) hModule + faddr[ford[count]]);

В этой статье говорится об этом: http://msdn.microsoft.com/en-us/magazine/cc301808.aspx

1 голос
/ 22 декабря 2009

Похоже, вы принимаете Ordinal # = offset в таблице. Может быть, это не так в Windows 7 DLL.

0 голосов
/ 22 декабря 2009

Как вы создаете дескриптор hModule? И почему бы вам просто не использовать GetProcAddress (ваша функция, кажется, дублирует поведение вашей функции)?

...