Проблема со вставкой asm в модуль Delphi

Тема в разделе "WASM.BEGINNERS", создана пользователем essess, 19 окт 2008.

  1. essess

    essess New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2008
    Сообщения:
    6
    Есть:

    function NtUserPostMessage(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): BOOL; stdcall;
    asm
    pop ebp
    mov eax, $11DB
    call @SystemCall
    ret $10
    @SystemCall:
    mov edx, esp
    sysenter
    end;

    в основном модуле(Unit1.pas) функция работает, а при переносе в дополнительный(Unit2.pas) начинаются проблемы
    Access violation at address, подскажите в чем причина и варианты устранения.
     
  2. CyberManiac

    CyberManiac New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2003
    Сообщения:
    2.473
    Адрес:
    Russia
    Может быть, в несохранении регистров? Для коррекктной работы асм-вставка должна сохранять ebx и ещё что-то там (полный список есть в документации).
     
  3. _basmp_

    _basmp_ New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2005
    Сообщения:
    2.939
    pusha
    ...
    popa
     
  4. axe_roma

    axe_roma New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2004
    Сообщения:
    93
    Адрес:
    Russia
    да надо ставить pushad в самом начале после asm а в конце popad типо того :
    Код (Text):
    1. function NtUserPostMessage(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): BOOL; stdcall;
    2. asm
    3. pushad
    4. pop ebp
    5. mov eax, $11DB
    6. call @SystemCall
    7. ret $10
    8. @SystemCall:
    9. mov edx, esp
    10. sysenter
    11. popad
    12. end;
    Или просто в отладчике пройтись по етому коду и глянуть что не так
     
  5. essess

    essess New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2008
    Сообщения:
    6
    Я посмотрел pushad и popad
    [​IMG]
    а pusha и popa дали вообще интересную картину
    [​IMG]

    я так понял проблема при вызове ret $10.

    А в орегинальном варианте, я щас ошибок не вылетает,
    а происходит зациклевание(возвращается к предыдущим строкам кода после вызова ret $10)
    и программа повисает намертво. Чудеса прям какието.
     
  6. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    С Delphi дела не имел, но, может, проблема в несоответствии конвенции вызова? Судя по дизасму из скриншота Delphi любит fastcall, значит, первые три параметра передадутся в eax, ecx и edx. Тогда не 'ret 0x10', а 'ret 0x4'.
     
  7. essess

    essess New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2008
    Сообщения:
    6
    2 Mika0x65
    Поменял 'ret 0x10' на 'ret 0x4' отладчик дал практически такуюже картинку как с pusha, да и в основном модуле все прекрасно работает.

    Пример откуда брал вставку asm:
    http://www.vbstreets.ru/VB/Articles/66404.aspx

    pusha и pushad в основном модуле в работу функции никаких изменений не вносят...
    т.е. с ними работает как и без них
     
  8. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    CyberManiac
    Все необходимые регистры и так сохранены.
    axe_roma
    Сами вообще подумали, чё сделали? Мало того, что до popad дело вообще не дойдёт, так ещё ebp в начале испохаблен.
    Mika0x65
    Ну да... а вот ключевое слово stdcall в прототипе функции совсем ни о чём не говорит.
    essess
    Вы бы прежде чем советам вида "pushad/popad" следовать, своей бы головой подумали.
    pop ebp в начале функции должен восстанавливать ebp, испорченный прологом, вставленным Delphi в начало функции перед asm-вставкой.
    Вставляйте int 3 в начало вставки и смотрите под Olly, в чём проблема.
     
  9. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    essess
    Вот эту фразу сразу не заметил. :) Шедевральное высказывание в данном контексте. Если они изменений не вносят, то они и не исполняются. Если бы исполнялись, однозначно сбивали бы стэк, и процесс бы падал.
     
  10. essess

    essess New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2008
    Сообщения:
    6
    l_inc
    Я признаюсь, что asm для меня темный лес.
    Попробую провести аналогию через Olly для ф-ции в основном и дополнительном, мож че и пойму =)
     
  11. essess

    essess New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2008
    Сообщения:
    6
    Чет пока ничего не пойму. =(
     
  12. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    В ф-ии, где находится EIP на скриншоте используется fastcall. Как в Delphi реализуются заголовочные файлы я не знаю.

    essess
    Выложи тогда где-нибудь исполняемый. Только добавь в ф-ию 8-9 nop'ов, или с отладочной информацией скомпилируй.
     
  13. OFFSIDE

    OFFSIDE New Member

    Публикаций:
    0
    Регистрация:
    23 сен 2006
    Сообщения:
    106
  14. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    essess
    Неизвестна модель вызова процедуры в дельфях, какие регистры сохраняются, как и сказал Mika0x65 нужен модуль, тока без отладочной инфы, компиль как есть.
    > Номер сервиса может быть неверный, в разных версиях ОС он разный, у тебя для SP2.
    >
    Инструкция popad никогда не будет исполнена, ядро возвращает управление не на инструкцию следующую за sysenter, а на ntdll.KiFastSystemCallRet(->Ret). Если юзаешь в шелкоде сервис, юзай шлюз 2e.
    Неудивительно что управление передаётся хз куда, после такого кода. Видимо нужно создать отдельную тему, на этот счёт.
    > Есчо раз, не известна модель, поэтому попробуй так:
    Код (Text):
    1.     push lParam
    2.     push wParam
    3.     push Msg
    4.     push hWnd
    5.     Call @UserStub
    6.     jmp @Exit
    7. @UserStub:
    8.     mov eax, $11DB
    9.     Call @FastSystemCall
    10.     ret $10
    11. @FastSystemCall:
    12.     mov edx,esp
    13.     sysenter
    14. @Exit:
    Через прерывание:
    Код (Text):
    1.     push lParam
    2.     push wParam
    3.     push Msg
    4.     push hWnd
    5.     mov edx,esp
    6.     Int $2Eh
    7.     lea esp,[esp + $10]
    Короче, модуль нужен.
     
  15. K10

    K10 New Member

    Публикаций:
    0
    Регистрация:
    3 окт 2008
    Сообщения:
    1.590
    в случае stdcall параметры в стеке. В процедуре не надо сохранять EAX, EDX и ECX. Остальные надо.
     
  16. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    K10
    А сервис полюбому сохраняет Ebx, Esi, Edi.
    Имеется ввиду, если не сохраняются ни какие в стеке регистры, тогда можно не использовать часть кода:
    так как они на низу стека, иначе если какойлибо регистр сохраняется в стеке, либо есть локальные переменные, а мы этого не знаем, тогда и нужно есчё раз сохранять в стеке входные параметры.
     
  17. essess

    essess New Member

    Публикаций:
    0
    Регистрация:
    19 окт 2008
    Сообщения:
    6
    Ура заработало =)

    Я, когда попросили выложить откомпиленый модуль, решил написать маленькую демку с его использованием и вней все заработало, я так понял, что в основном модуле был какойто Делфевый "ньюанс" запарывающий данный вызов.
    Буду разбираться в чем причина такого странного поведения.

    ВСЕМ ОГРОМНОЕ СПАСИБО!!!