Привет всем. Возник вопрос. Есть такой код: Код (Text): sub esp, SIZE_ ; резервируем место в стеке mov ecx, SIZE_ mov esi, start1 mov edi, esp rep movsb ; копируем в стек наш код jmp esp ; прыжок в стек start1: invoke MessageBox, 0, szTest, szTest, MB_OK mov [qwerty], 0BBBBh invoke ExitProcess, 0 SIZE_ = $ - start1 Как видно, он копирует вызов MessageBox'а и прочее в стек, а затем переходит туда. Без строчки "mov [qwerty], 0BBBBh" программа выполняется нормально и MessageBox появляется, а если вместе с ней, то MessageBox либо вообще не появляется, либо появляется без текста и без заголовка. Почему? И еще, если вместо MessageBox'а вызывать какую-нибудь api-функцию (напр. FindFirst), заполняющую какую-нибудь структуру, то она не выполняется, а LastError = ERROR_NOACCESS (000003E6). Почему?
> И где же определена метка qwerty, кроме вашего ника? Так я только кусок кода привел. Определена она в той же секции, что и код. Атрибуты на секцию разумеется стоят и на чтение, и на запись, и на выолнение. В отладчике "mov [qwerty], 0BBBBh" выполняется нормально и число 0xbbbb успешно записывается, а вот с MsgBox'ом фигня такая получается 8) > А структура, небось, в стеке хранится. Нет. А если бы в стеке - я ж под нее место бы выделил... add: И еще, когда MsgBox не появляется на экране вообще, в отладчике: "Access violation when reading [???????]". (где "??????" - адрес, причем каждый раз разный.) Вот оба исходника: Код (Text): format PE GUI 4.0 include '%fasminc%\win32w.inc' include '%fasminc%\encoding\win1251.inc' section '.code' code readable writeable executable entry $ mov [qwerty], 0AAAAh sub esp, SIZE_ mov ecx, SIZE_ mov esi, start1 mov edi, esp rep movsb jmp esp start1: invoke MessageBox, 0, szTest, szTest, MB_OK mov [qwerty], 0BBBBh invoke ExitProcess, 0 SIZE_ = $ - start1 data import library kernel32, 'kernel32.dll',\ user32, 'user32.dll' include '%fasminc%\api\kernel32.inc' include '%fasminc%\api\user32.inc' end data szTest du 'hello!',0 qwerty dw ? Код (Text): format PE GUI 4.0 include '%fasminc%\win32a.inc' entry start section '.code' code readable writeable executable start: sub esp, SIZE_ mov ecx, SIZE_ mov esi, start1 mov edi, esp rep movsb jmp esp start1: invoke FindFirstFile, szMask, findbuf inc eax jz finish dec eax mov [hFind], eax @@: mov eax, FILENAME invoke MessageBox, 0, eax, szMask, MB_OK invoke FindNextFile, [hFind], findbuf test eax, eax jne @b finish: invoke ExitProcess, 0 SIZE_ = $ - start1 data import library kernel32, 'kernel32.dll',\ user32, 'user32.dll' include '%fasminc%\api\kernel32.inc' include '%fasminc%\api\user32.inc' end data FILENAME = findbuf + 44 findbuf db sizeof.FINDDATAW dup (?) szMask db '*.asm', 0 hFind dd ?
ухты. у меня мсжбокс с наклоненной перечоркнутой буквой h. не знаю, чо получаецо так. можт защита от выполнения кода в стеке... но если сделоть Код (Text): start1: invoke MessageBox, 0, szTest, szTest, MB_OK mov word [qwerty], 0BBBBh invoke ExitProcess, 0 szTest du 'hello!',0 SIZE_ = $ - start1 то пашет норм
Такое происходит когда вызываешь ф-ию API с невыравненным по границе 4 стеком. Если добавить Код (Text): push eax and esp, 0xFFFFFFF8 invoke MessageBox, 0, szTest, szTest, MB_OK mov [qwerty], 0BBBBh то все будет Ок. Тогда же можно убрать и 'mov [qwerty]m 0BBBBh'.
Mika0x65 Спасибо Забыл я про выравнивание стека %) А зачем перед and esp, 0xFFFFFFF8 нужно push eax? В принципе, я догадываюсь - что бы затем при выравнивании esp не навыравнивать ничего лишнего. Только мне такой ситуации получить не удается (что бы без push eax не работало).
Да, это нужно чтобы не загнать esp на участок только что скопированного кода. Это зависит от размера кода.
Хм... а каким образом это зависит от размера кода? Я сначала резервирую место в стеке под код, копирую его и esp указывает на начало моего кода, а умножение на 0xFFFFFFF8 выровняет esp в меньшую сторону и поэтому esp никогда не попадет на только что скопированный код! Или я не прав??? Объясни, пожалуйста.