В ответ на топик
http://www.rsdn.ru/forum/Message.aspx?mid=157597Автор: mik1
Дата: 19.12.02
Функция-аналог GetProcAddress
На самом деле функция немного отличается, т.к. принимает имя в юникоде, и возвращает адрес через указатель.
Плюс работает медленнее, т.к. я пока решил не оптимизировать поиск по упорядоченному массиву строк, коим является список экспорта библиотек.
Поддерживается фишка, когда реальный адрес функции находится не в текущей библиотеке, а в экспортируемой ею. Кстати в документации я об этом почти ничего не нашел.
bool get_proc_address(HMODULE h, void * target, WCHAR *name)
{
BYTE *hb = (BYTE *)h;
DWORD na = (DWORD)(hb + *((DWORD *)(hb+0x3C)));
DWORD ea = (DWORD)(hb + *((DWORD *)(na+0x78))); //export table
DWORD eas = *((DWORD *)(na+0x7C)); //export table size
int sz = *((DWORD *)(ea+0x18));
DWORD *fpa = (DWORD *)(hb + (*((DWORD *)(ea+0x1C)))); //addresses
DWORD *fna = (DWORD *)(hb + (*((DWORD *)(ea+0x20)))); //names
WORD *foa = (WORD *)(hb + (*((DWORD *)(ea+0x24)))); //ordinals
while (sz>0)
{
char * fn = (char *)(hb+(*fna));
WCHAR *ntf = name;
while(*fn == *((char *)ntf))
{
if (*fn == 0)
{
DWORD ordinal = (*foa);
DWORD fa = (DWORD)(hb+(*(fpa+ordinal))); //function address
if ((fa >= ea) && (fa < (ea+eas)))
{
// address out of this PE module
char * a = (char *)fa;
DWORD ia = (DWORD)(hb + *((DWORD *)(na+0x80))); //import table
for(;;)
{
DWORD dllname_rva = *((DWORD *)(ia + 0xC));
if (dllname_rva == 0) break;
char *dllname = (char *)(hb + dllname_rva);
char *aa = a;
for(;;)
{
char c1 = (char)(((*aa>='a') && (*aa<='z'))?(*aa&~32):*aa);
char c2 = (char)(((*dllname>='a') && (*dllname<='z'))?(*dllname&~32):*dllname);
if (c1!=c2) break;
if (c1=='.')
{
aa++;
DWORD *lookup = (DWORD*)(hb + *((DWORD *)(ia)));
DWORD *ifa = (DWORD*)(hb + *((DWORD *)(ia + 0x10)));
for (;;)
{
char *in = (char *)(hb + *lookup + 2);
a = aa;
while(*in == *a)
{
in++;
a++;
if (*in == 0)
{
*((DWORD *)target) = *ifa;
return false;
}
}
lookup++;
ifa++;
}
}
aa++;
dllname++;
}
ia += 0x14;
}
}
*((DWORD *)target) = fa;
return false;
}
fn++;
ntf++;
}
fna++;
foa++;
sz--;
}
return true;
}
PS: Модератору: посмотри на for(;). После обработки _ccode_ ... _/ccode_ одна точка с запятой исчезла