Адреса функций из dll...

Тема в разделе "WASM.WIN32", создана пользователем Namelles_One, 3 янв 2008.

  1. Namelles_One

    Namelles_One New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2007
    Сообщения:
    39
    Мда... Не все так просто в этом мире, в том числе и получение адресов функций из dll.

    Внимание на нижеследующий код, частью - взят из kexec.

    Код (Text):
    1. // Рассчет хэша
    2. ULONG __stdcall
    3. CalcHash(char *s){
    4.     __asm{
    5.         mov     eax,s
    6.         push    edx
    7.         xor     edx,edx
    8. calc_hash:
    9.         rol     edx,3
    10.         xor     dl,[eax]
    11.         inc     eax
    12.         cmp     [eax],0
    13.         jnz     calc_hash
    14.         mov     eax,edx
    15.         pop     edx
    16.     }
    17. }
    18.  
    19. // Получение адреса функции
    20. PVOID __stdcall
    21. GetProcAddrEx(ULONG hModule, ULONG dwProcHash){
    22.     __asm
    23.     {
    24.         xor     eax,eax
    25.         mov     ebx,dwProcHash
    26.         mov     esi,hModule
    27.         mov     edi,esi
    28.         add     esi,[esi+3Ch]
    29.         mov     ecx,[esi+78h]
    30.         add     ecx,edi
    31.         mov     edx,[ecx+1ch]
    32.         push    edx
    33.         mov     edx,[ecx+24h]
    34.         push    edx
    35.         mov     esi,[ecx+20h]
    36.         add     esi,edi
    37.         cdq
    38.         dec     edx
    39. next_func:
    40.         lodsd
    41.         inc     edx
    42.         add     eax,hModule
    43.         push    eax
    44.         call    CalcHash
    45.         cmp     eax,ebx
    46.         jnz     next_func
    47.         mov     eax,hModule
    48.         xchg    eax,edx
    49.         pop     esi
    50.         add     esi,edx
    51.         shl     eax,1
    52.         add     eax,esi
    53.         xor     ecx,ecx
    54.         movzx   ecx,word ptr [eax]
    55.         pop     edi
    56.         shl     ecx,2
    57.         add     ecx,edx
    58.         add     ecx,edi
    59.         mov     eax,[ecx]
    60.         add     eax,edx
    61.     }
    62. }
    63.  
    64. // Получение массивов функций
    65. BOOL
    66. WINAPI FindApiAddr( DWORD *dwApiHash, ULONG hModule )
    67. {
    68.     int     nCounter = 0;
    69.     char    *pPnt;
    70.  
    71.     pPnt = ( char * )&api;
    72.     while ( dwApiHash[ nCounter ] != 0x00000000 )
    73.     {
    74.         *( ( DWORD * )( pPnt + nGenCounter * 4 ) ) = (DWORD)GetProcAddrEx( hModule, dwApiHash[ nCounter ] );
    75.         nGenCounter ++;
    76.         nCounter ++;
    77.     } // end while
    78.  
    79.     return TRUE;
    80. } // end of function FindApiAddr
    Итого, в цикле заполняется структура, содержащая адреса функций (наподобие того, что некогда демонстрировал в своем коде el- )

    Итак, в чем дело? Если я передаю в работу данной функции, к примеру, user32.dll, которая экспортирует 16 основных функций - все прекрасно, все работает))))
    Но - вот отдаю я ей на растерзание kernel32 и пошли приколы.... 23 функции отрабатываются отлично, а на 24 итерации - все падает, какая бы функция не была в этой ячейке.

    Вот ссылка на файл - www.slil.ru/25311051 - реверсните и посмотрите - он должен получать адреса для kernel32 и user32, а потом - выводить MessageBoxA(). Но, как вы увидите, все падает, на пресловутой 24 итерации...

    Итак, господа, в чем проблема? Почему данный код не отрабатывает так, как задумано?
     
  2. Hellspawn

    Hellspawn New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2006
    Сообщения:
    310
    Адрес:
    Москва
    дык он функцию не находит =) у тебя там нету проверки на конец иат...
    цикл пока не найдет:
    Код (Text):
    1. 00401068  |> /AD                  /LODS DWORD PTR DS:[ESI]
    2. 00401069  |. |42                  |INC EDX
    3. 0040106A  |. |0345 08             |ADD EAX,[ARG.1]
    4. 0040106D  |. |50                  |PUSH EAX
    5. 0040106E  |. |E8 ADFFFFFF         |CALL api.00401020
    6. 00401073  |. |3BC3                |CMP EAX,EBX
    7. 00401075  |.^\75 F1               \JNZ SHORT api.00401068
    косяк )
     
  3. Namelles_One

    Namelles_One New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2007
    Сообщения:
    39
    Найти не может?
    lstrlenA (в том exe - она у меня на 24 месте висит ) в kernel32 он найти не может? Вам это бредом не кажется?((((

    И как же тогда жить, если он её не находит?(
     
  4. Hellspawn

    Hellspawn New Member

    Публикаций:
    0
    Регистрация:
    4 фев 2006
    Сообщения:
    310
    Адрес:
    Москва
    Код (Text):
    1. 0012FEEC  7C808F7A  \Arg1 = 7C808F7A ASCII "lstrlenA"
    2. ...
    3. hash = 0C71E271
    4. у тебя = 9937FF47
    предлагаю кусок мыла и верёвку)))
     
  5. Namelles_One

    Namelles_One New Member

    Публикаций:
    0
    Регистрация:
    18 июл 2007
    Сообщения:
    39
    Прогон. Спать нада вовремя ложиться.

    Счас проверил еще раз - падение идет на GetModuleHandle, следующей за lstrlenA.

    И она, как раз :

    P.S. Тройной прогон. Искать нада было GetModuleHandleA.
    Все работает, тему можно закрывать)
    Мораль - не след кодить в час ночи второго января ;)
     
  6. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Получение адресов...
    Код (Text):
    1. SEH struct
    2. PrevLink            dd ?
    3. CurrentHandler  dd ?
    4. SafeOffset      dd ?
    5. PrevEsp             dd ?
    6. PrevEbp             dd ?
    7. SEH ends
    8. PSEH typedef PTR SEH
    9.  
    10. _setseh_ macro
    11.     assume fs:nothing
    12.     push ebp
    13.     push esp
    14.     push offset SehNext
    15.     push offset SehHandler
    16.     push FS:[0]
    17.     mov FS:[0],esp
    18. endm
    19.  
    20. _endseh_ macro
    21.     clc
    22. SehNext:
    23.     pop FS:[0]
    24.     add esp,16
    25. endm
    26.  
    27. SehHandler proto pExcept:DWORD, pFrame:DWORD, pContext:DWORD, pDispatch:DWORD
    28.  
    29. SehHandler proc uses edx pExcept:DWORD, pFrame:DWORD, pContext:DWORD, pDispatch:DWORD
    30.     mov edx,pFrame
    31.     assume edx:ptr SEH
    32.     mov eax,pContext
    33.     assume eax:ptr CONTEXT
    34.     push [edx].SafeOffset
    35.     pop [eax].regEip
    36.     push [edx].PrevEsp
    37.     sub dword ptr [esp],16
    38.     pop [eax].regEsp
    39.     push [edx].PrevEbp
    40.     pop [eax].regEbp
    41.     mov [eax].regEax,STATUS_INVALID_PARAMETER  
    42.     or [eax].regEFlags,1
    43.     xor eax,eax     ;ExceptionContinueExecution
    44.     ret
    45. SehHandler endp
    46.  
    47. ImageQueryFunctionRvaFromName proc uses ebx esi edi ImageBase:PVOID, FunctionName:PCHAR, FunctionRva:PULONG
    48. Local ExportDirectory:PIMAGE_EXPORT_DIRECTORY
    49. Local NumberOfNames:ULONG
    50.     _setseh_
    51.     mov ebx,ImageBase
    52.     invoke RtlImageNtHeader, ebx
    53.     test eax,eax
    54.     jz err_image_
    55.     assume eax:PIMAGE_NT_HEADERS
    56.     mov eax,[eax].OptionalHeader.DataDirectory.VirtualAddress
    57.     test eax,eax
    58.     jz err_image_  
    59.     add eax,ebx
    60.     assume eax:PIMAGE_EXPORT_DIRECTORY 
    61.     mov ExportDirectory,eax
    62.     mov esi,[eax].AddressOfNames   
    63.     test esi,esi
    64.     jz err_table_  
    65.     mov eax,[eax].NumberOfNames
    66.     test eax,eax
    67.     jz err_table_
    68.     mov NumberOfNames,eax
    69.     add esi,ebx;в esi - массив имен функций
    70.     xor edi,edi;в edx - храним индекс
    71. loop_: 
    72.     mov eax,dword ptr [esi]
    73.     add eax,ebx
    74.     invoke CompareAsciizString, FunctionName, eax
    75.     .if Eax
    76.     mov ecx,ExportDirectory    
    77.     assume ecx:PIMAGE_EXPORT_DIRECTORY
    78.     mov eax,[ecx].AddressOfNameOrdinals
    79.     add eax,ebx ;в esi - массив слов с индесками  
    80.     movzx edi,word ptr [2*edi+eax]
    81.     sub edi,[ecx]._Base;вычитаем начальный ординал
    82.     inc edi;т.к. начальный ординал начинается с 1
    83.     mov esi,[ecx].AddressOfFunctions
    84.     add esi,ebx;в esi - массив адресов функций
    85.     mov eax,dword ptr [4*edi+esi]
    86.     test eax,eax
    87.     jz err_image_
    88.     mov ebx,FunctionRva
    89.     mov dword ptr [ebx],eax
    90.     xor eax,eax
    91.     .else
    92.     add esi,4
    93.     inc edi
    94.     dec NumberOfNames
    95.     jnz loop_
    96.     mov eax,STATUS_PROCEDURE_NOT_FOUND     
    97.     .endif
    98. exit_:
    99.     _endseh_
    100.     ret
    101. err_image_:
    102.     mov eax,STATUS_INVALID_IMAGE_FORMAT
    103.     jmp exit_
    104. err_table_:
    105.     mov eax,STATUS_BAD_FUNCTION_TABLE
    106.     jmp exit_
    107. ImageQueryFunctionRvaFromName endp