Есть: 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, подскажите в чем причина и варианты устранения.
Может быть, в несохранении регистров? Для коррекктной работы асм-вставка должна сохранять ebx и ещё что-то там (полный список есть в документации).
да надо ставить pushad в самом начале после asm а в конце popad типо того : Код (Text): function NtUserPostMessage(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): BOOL; stdcall; asm pushad pop ebp mov eax, $11DB call @SystemCall ret $10 @SystemCall: mov edx, esp sysenter popad end; Или просто в отладчике пройтись по етому коду и глянуть что не так
Я посмотрел pushad и popad а pusha и popa дали вообще интересную картину я так понял проблема при вызове ret $10. А в орегинальном варианте, я щас ошибок не вылетает, а происходит зациклевание(возвращается к предыдущим строкам кода после вызова ret $10) и программа повисает намертво. Чудеса прям какието.
С Delphi дела не имел, но, может, проблема в несоответствии конвенции вызова? Судя по дизасму из скриншота Delphi любит fastcall, значит, первые три параметра передадутся в eax, ecx и edx. Тогда не 'ret 0x10', а 'ret 0x4'.
2 Mika0x65 Поменял 'ret 0x10' на 'ret 0x4' отладчик дал практически такуюже картинку как с pusha, да и в основном модуле все прекрасно работает. Пример откуда брал вставку asm: http://www.vbstreets.ru/VB/Articles/66404.aspx pusha и pushad в основном модуле в работу функции никаких изменений не вносят... т.е. с ними работает как и без них
CyberManiac Все необходимые регистры и так сохранены. axe_roma Сами вообще подумали, чё сделали? Мало того, что до popad дело вообще не дойдёт, так ещё ebp в начале испохаблен. Mika0x65 Ну да... а вот ключевое слово stdcall в прототипе функции совсем ни о чём не говорит. essess Вы бы прежде чем советам вида "pushad/popad" следовать, своей бы головой подумали. pop ebp в начале функции должен восстанавливать ebp, испорченный прологом, вставленным Delphi в начало функции перед asm-вставкой. Вставляйте int 3 в начало вставки и смотрите под Olly, в чём проблема.
essess Вот эту фразу сразу не заметил. Шедевральное высказывание в данном контексте. Если они изменений не вносят, то они и не исполняются. Если бы исполнялись, однозначно сбивали бы стэк, и процесс бы падал.
l_inc Я признаюсь, что asm для меня темный лес. Попробую провести аналогию через Olly для ф-ции в основном и дополнительном, мож че и пойму =)
В ф-ии, где находится EIP на скриншоте используется fastcall. Как в Delphi реализуются заголовочные файлы я не знаю. essess Выложи тогда где-нибудь исполняемый. Только добавь в ф-ию 8-9 nop'ов, или с отладочной информацией скомпилируй.
essess Неизвестна модель вызова процедуры в дельфях, какие регистры сохраняются, как и сказал Mika0x65 нужен модуль, тока без отладочной инфы, компиль как есть. > Номер сервиса может быть неверный, в разных версиях ОС он разный, у тебя для SP2. > Инструкция popad никогда не будет исполнена, ядро возвращает управление не на инструкцию следующую за sysenter, а на ntdll.KiFastSystemCallRet(->Ret). Если юзаешь в шелкоде сервис, юзай шлюз 2e. Неудивительно что управление передаётся хз куда, после такого кода. Видимо нужно создать отдельную тему, на этот счёт. > Есчо раз, не известна модель, поэтому попробуй так: Код (Text): push lParam push wParam push Msg push hWnd Call @UserStub jmp @Exit @UserStub: mov eax, $11DB Call @FastSystemCall ret $10 @FastSystemCall: mov edx,esp sysenter @Exit: Через прерывание: Код (Text): push lParam push wParam push Msg push hWnd mov edx,esp Int $2Eh lea esp,[esp + $10] Короче, модуль нужен.
K10 А сервис полюбому сохраняет Ebx, Esi, Edi. Имеется ввиду, если не сохраняются ни какие в стеке регистры, тогда можно не использовать часть кода: так как они на низу стека, иначе если какойлибо регистр сохраняется в стеке, либо есть локальные переменные, а мы этого не знаем, тогда и нужно есчё раз сохранять в стеке входные параметры.
Ура заработало =) Я, когда попросили выложить откомпиленый модуль, решил написать маленькую демку с его использованием и вней все заработало, я так понял, что в основном модуле был какойто Делфевый "ньюанс" запарывающий данный вызов. Буду разбираться в чем причина такого странного поведения. ВСЕМ ОГРОМНОЕ СПАСИБО!!!