Мда... Не все так просто в этом мире, в том числе и получение адресов функций из dll. Внимание на нижеследующий код, частью - взят из kexec. Код (Text): // Рассчет хэша ULONG __stdcall CalcHash(char *s){ __asm{ mov eax,s push edx xor edx,edx calc_hash: rol edx,3 xor dl,[eax] inc eax cmp [eax],0 jnz calc_hash mov eax,edx pop edx } } // Получение адреса функции PVOID __stdcall GetProcAddrEx(ULONG hModule, ULONG dwProcHash){ __asm { xor eax,eax mov ebx,dwProcHash mov esi,hModule mov edi,esi add esi,[esi+3Ch] mov ecx,[esi+78h] add ecx,edi mov edx,[ecx+1ch] push edx mov edx,[ecx+24h] push edx mov esi,[ecx+20h] add esi,edi cdq dec edx next_func: lodsd inc edx add eax,hModule push eax call CalcHash cmp eax,ebx jnz next_func mov eax,hModule xchg eax,edx pop esi add esi,edx shl eax,1 add eax,esi xor ecx,ecx movzx ecx,word ptr [eax] pop edi shl ecx,2 add ecx,edx add ecx,edi mov eax,[ecx] add eax,edx } } // Получение массивов функций BOOL WINAPI FindApiAddr( DWORD *dwApiHash, ULONG hModule ) { int nCounter = 0; char *pPnt; pPnt = ( char * )&api; while ( dwApiHash[ nCounter ] != 0x00000000 ) { *( ( DWORD * )( pPnt + nGenCounter * 4 ) ) = (DWORD)GetProcAddrEx( hModule, dwApiHash[ nCounter ] ); nGenCounter ++; nCounter ++; } // end while return TRUE; } // end of function FindApiAddr Итого, в цикле заполняется структура, содержащая адреса функций (наподобие того, что некогда демонстрировал в своем коде el- ) Итак, в чем дело? Если я передаю в работу данной функции, к примеру, user32.dll, которая экспортирует 16 основных функций - все прекрасно, все работает)))) Но - вот отдаю я ей на растерзание kernel32 и пошли приколы.... 23 функции отрабатываются отлично, а на 24 итерации - все падает, какая бы функция не была в этой ячейке. Вот ссылка на файл - www.slil.ru/25311051 - реверсните и посмотрите - он должен получать адреса для kernel32 и user32, а потом - выводить MessageBoxA(). Но, как вы увидите, все падает, на пресловутой 24 итерации... Итак, господа, в чем проблема? Почему данный код не отрабатывает так, как задумано?
дык он функцию не находит =) у тебя там нету проверки на конец иат... цикл пока не найдет: Код (Text): 00401068 |> /AD /LODS DWORD PTR DS:[ESI] 00401069 |. |42 |INC EDX 0040106A |. |0345 08 |ADD EAX,[ARG.1] 0040106D |. |50 |PUSH EAX 0040106E |. |E8 ADFFFFFF |CALL api.00401020 00401073 |. |3BC3 |CMP EAX,EBX 00401075 |.^\75 F1 \JNZ SHORT api.00401068 косяк )
Найти не может? lstrlenA (в том exe - она у меня на 24 месте висит ) в kernel32 он найти не может? Вам это бредом не кажется?(((( И как же тогда жить, если он её не находит?(
Код (Text): 0012FEEC 7C808F7A \Arg1 = 7C808F7A ASCII "lstrlenA" ... hash = 0C71E271 у тебя = 9937FF47 предлагаю кусок мыла и верёвку)))
Прогон. Спать нада вовремя ложиться. Счас проверил еще раз - падение идет на GetModuleHandle, следующей за lstrlenA. И она, как раз : P.S. Тройной прогон. Искать нада было GetModuleHandleA. Все работает, тему можно закрывать) Мораль - не след кодить в час ночи второго января
Получение адресов... Код (Text): SEH struct PrevLink dd ? CurrentHandler dd ? SafeOffset dd ? PrevEsp dd ? PrevEbp dd ? SEH ends PSEH typedef PTR SEH _setseh_ macro assume fs:nothing push ebp push esp push offset SehNext push offset SehHandler push FS:[0] mov FS:[0],esp endm _endseh_ macro clc SehNext: pop FS:[0] add esp,16 endm SehHandler proto pExcept:DWORD, pFrame:DWORD, pContext:DWORD, pDispatch:DWORD SehHandler proc uses edx pExcept:DWORD, pFrame:DWORD, pContext:DWORD, pDispatch:DWORD mov edx,pFrame assume edx:ptr SEH mov eax,pContext assume eax:ptr CONTEXT push [edx].SafeOffset pop [eax].regEip push [edx].PrevEsp sub dword ptr [esp],16 pop [eax].regEsp push [edx].PrevEbp pop [eax].regEbp mov [eax].regEax,STATUS_INVALID_PARAMETER or [eax].regEFlags,1 xor eax,eax ;ExceptionContinueExecution ret SehHandler endp ImageQueryFunctionRvaFromName proc uses ebx esi edi ImageBase:PVOID, FunctionName:PCHAR, FunctionRva:PULONG Local ExportDirectory:PIMAGE_EXPORT_DIRECTORY Local NumberOfNames:ULONG _setseh_ mov ebx,ImageBase invoke RtlImageNtHeader, ebx test eax,eax jz err_image_ assume eax:PIMAGE_NT_HEADERS mov eax,[eax].OptionalHeader.DataDirectory.VirtualAddress test eax,eax jz err_image_ add eax,ebx assume eax:PIMAGE_EXPORT_DIRECTORY mov ExportDirectory,eax mov esi,[eax].AddressOfNames test esi,esi jz err_table_ mov eax,[eax].NumberOfNames test eax,eax jz err_table_ mov NumberOfNames,eax add esi,ebx;в esi - массив имен функций xor edi,edi;в edx - храним индекс loop_: mov eax,dword ptr [esi] add eax,ebx invoke CompareAsciizString, FunctionName, eax .if Eax mov ecx,ExportDirectory assume ecx:PIMAGE_EXPORT_DIRECTORY mov eax,[ecx].AddressOfNameOrdinals add eax,ebx ;в esi - массив слов с индесками movzx edi,word ptr [2*edi+eax] sub edi,[ecx]._Base;вычитаем начальный ординал inc edi;т.к. начальный ординал начинается с 1 mov esi,[ecx].AddressOfFunctions add esi,ebx;в esi - массив адресов функций mov eax,dword ptr [4*edi+esi] test eax,eax jz err_image_ mov ebx,FunctionRva mov dword ptr [ebx],eax xor eax,eax .else add esi,4 inc edi dec NumberOfNames jnz loop_ mov eax,STATUS_PROCEDURE_NOT_FOUND .endif exit_: _endseh_ ret err_image_: mov eax,STATUS_INVALID_IMAGE_FORMAT jmp exit_ err_table_: mov eax,STATUS_BAD_FUNCTION_TABLE jmp exit_ ImageQueryFunctionRvaFromName endp