О конвенции вызова...

Тема в разделе "WASM.RESEARCH", создана пользователем Mibori, 19 авг 2008.

  1. Mibori

    Mibori New Member

    Публикаций:
    0
    Регистрация:
    19 авг 2008
    Сообщения:
    4
    дизассемблировал Awl.dll из комплекта Finereader Pro 8
    IDA дает следующий блок:
    Код (Text):
    1. .text:2382CBB0 ; --------------- S U B R O U T I N E ---------------------------------------
    2. .text:2382CBB0
    3. .text:2382CBB0 ; Attributes: bp-based frame
    4. .text:2382CBB0
    5. .text:2382CBB0 ; protected: bool __thiscall AWL::CMessageLoop::TryOnIdle(long)
    6. .text:2382CBB0                 public ?TryOnIdle@CMessageLoop@AWL@@IAE_NJ@Z
    7. .text:2382CBB0 ?TryOnIdle@CMessageLoop@AWL@@IAE_NJ@Z proc near
    8. .text:2382CBB0                                         ; CODE XREF: AWL::CMessageLoop::DoMessageLoop(void)+8Ep
    9. .text:2382CBB0
    10. .text:2382CBB0 var_10          = dword ptr -10h
    11. .text:2382CBB0 var_C           = dword ptr -0Ch
    12. .text:2382CBB0 var_4           = dword ptr -4
    13. .text:2382CBB0 arg_0           = dword ptr  8
    14. .text:2382CBB0
    15. .text:2382CBB0                 push    ebp
    16. .text:2382CBB1                 mov     ebp, esp
    17. .text:2382CBB3                 push    0FFFFFFFFh
    18. .text:2382CBB5                 push    offset loc_2387DD50
    19. .text:2382CBBA                 mov     eax, large fs:0
    20. .text:2382CBC0                 push    eax
    21. .text:2382CBC1                 mov     large fs:0, esp
    22. .text:2382CBC8                 sub     esp, 8
    23. .text:2382CBCB                 mov     edx, [ebp+arg_0]
    24. .text:2382CBCE                 mov     eax, [ecx]      ; первый член класса
    25. .text:2382CBD0                 push    ebx
    26. .text:2382CBD1                 push    esi
    27. .text:2382CBD2                 push    edi
    28. .text:2382CBD3                 mov     [ebp+var_10], esp
    29. .text:2382CBD6                 push    edx
    30. .text:2382CBD7                 mov     [ebp+var_4], 0
    31. .text:2382CBDE                 call    dword ptr [eax+8] ; <- интересующая строка
    32. .text:2382CBE1                 mov     ecx, [ebp+var_C] ;
    33. .text:2382CBE4                 mov     large fs:0, ecx
    34. .text:2382CBEB                 pop     edi
    35. .text:2382CBEC                 pop     esi
    36. .text:2382CBED                 pop     ebx
    37. .text:2382CBEE                 mov     esp, ebp
    38. .text:2382CBF0                 pop     ebp
    39. .text:2382CBF1                 retn    4
    40. .text:2382CBF1 ?TryOnIdle@CMessageLoop@AWL@@IAE_NJ@Z endp
    как видим метод CMessageLoop::TryOnIdle вызывается по конвенции thiscall и ссылка на объект должна лежать в ecx
    не могу понять одного, имеется
    Код (Text):
    1. .text:2382CBDE                 call    dword ptr [eax+8] ; <- интересующая строка
    по какой конвенции это вызов, и как хотя бы приблизительно это выглядет на Си?

    Единственное, что я могу тут понять, так это то, что в ecx - ссылка на объект CMessageLoop, в еах кладётся значение первого поля этого объекта. Это поле представляет из себя структуру или массив как минимум из трёх элементов, и третьим элементом является указатель на функцию, которая, собственно и вызывается.
     
  2. Velheart

    Velheart New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2008
    Сообщения:
    526
    Так это просто вызов виртуальной функции, а превый член класса -- указатель на таблицу функций
     
  3. Ursus

    Ursus Member

    Публикаций:
    0
    Регистрация:
    15 мар 2006
    Сообщения:
    238
    Адрес:
    Russia
    Код (Text):
    1. class CMessagLoop {
    2.    virtual void Method1();
    3.    virtual void Method2();
    4.    virtual void Method3();
    5. }
    6.  
    7. this -> [vfptr] -> [vtable]
    8.  
    9. [vtable + 0]  -> [ Method1 address ] -> Method1()
    10. [vtable + 4]  -> [ Method2 address ] -> Method2()
    11. [vtable + 8]  -> [ Method3 address ] -> Method3()
    Вот примерно так. Здесь стрелки - это операции разыменования указателей.
    Т.е. this указывает непосредственно на vfptr, который есть ничто иное, как указатель на таблицу виртуальных функций vtable, которая, в свою очередь, представляет собой массив указателей на сами виртуальные функции.
     
  4. Mibori

    Mibori New Member

    Публикаций:
    0
    Регистрация:
    19 авг 2008
    Сообщения:
    4
    Спасибо.