Проблема с кодом в стеке и записью оттуда в память

Тема в разделе "WASM.BEGINNERS", создана пользователем _qwerty_, 2 май 2007.

  1. _qwerty_

    _qwerty_ New Member

    Публикаций:
    0
    Регистрация:
    24 фев 2007
    Сообщения:
    17
    Привет всем.

    Возник вопрос. Есть такой код:

    Код (Text):
    1. sub esp, SIZE_  ; резервируем место в стеке
    2. mov ecx, SIZE_
    3. mov esi, start1
    4. mov edi, esp
    5. rep movsb   ; копируем в стек наш код
    6. jmp esp ; прыжок в стек
    7.  
    8. start1:
    9.  
    10.     invoke  MessageBox, 0, szTest, szTest, MB_OK
    11.     mov [qwerty], 0BBBBh
    12.     invoke  ExitProcess, 0
    13.  
    14. SIZE_ = $ - start1
    Как видно, он копирует вызов MessageBox'а и прочее в стек, а затем переходит туда.
    Без строчки "mov [qwerty], 0BBBBh" программа выполняется нормально и MessageBox появляется,
    а если вместе с ней, то MessageBox либо вообще не появляется, либо появляется без текста и без заголовка. Почему?
    И еще, если вместо MessageBox'а вызывать какую-нибудь api-функцию (напр. FindFirst), заполняющую какую-нибудь структуру, то она не выполняется, а LastError = ERROR_NOACCESS (000003E6). Почему?
     
  2. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    И где же определена метка qwerty, кроме вашего ника?

    А структура, небось, в стеке хранится.
     
  3. _qwerty_

    _qwerty_ New Member

    Публикаций:
    0
    Регистрация:
    24 фев 2007
    Сообщения:
    17
    > И где же определена метка qwerty, кроме вашего ника?
    Так я только кусок кода привел. Определена она в той же секции, что и код. Атрибуты на секцию разумеется стоят и на чтение, и на запись, и на выолнение.
    В отладчике "mov [qwerty], 0BBBBh" выполняется нормально и число 0xbbbb успешно записывается, а вот с MsgBox'ом фигня такая получается 8)

    > А структура, небось, в стеке хранится.
    Нет. А если бы в стеке - я ж под нее место бы выделил...

    add:
    И еще, когда MsgBox не появляется на экране вообще, в отладчике: "Access violation when reading [???????]". (где "??????" - адрес, причем каждый раз разный.)

    Вот оба исходника:

    Код (Text):
    1. format PE GUI 4.0
    2. include '%fasminc%\win32w.inc'
    3. include '%fasminc%\encoding\win1251.inc'
    4.  
    5. section '.code' code readable writeable executable
    6. entry $
    7.  
    8.     mov     [qwerty], 0AAAAh
    9.  
    10.     sub     esp, SIZE_
    11.     mov     ecx, SIZE_
    12.     mov     esi, start1
    13.     mov     edi, esp
    14.     rep     movsb
    15.  
    16.     jmp     esp
    17.  
    18. start1:
    19.  
    20.     invoke  MessageBox, 0, szTest, szTest, MB_OK
    21.  
    22.     mov     [qwerty], 0BBBBh
    23.  
    24.     invoke  ExitProcess, 0
    25.  
    26. SIZE_ = $ - start1
    27.  
    28.  
    29. data import
    30.     library kernel32, 'kernel32.dll',\
    31.                     user32, 'user32.dll'
    32.     include '%fasminc%\api\kernel32.inc'
    33.     include '%fasminc%\api\user32.inc'
    34. end data
    35.  
    36. szTest  du  'hello!',0
    37. qwerty  dw  ?
    Код (Text):
    1. format PE GUI 4.0
    2. include '%fasminc%\win32a.inc'
    3. entry start
    4.  
    5. section '.code' code readable writeable executable
    6. start:
    7.  
    8.  
    9.     sub     esp, SIZE_
    10.     mov     ecx, SIZE_
    11.     mov     esi, start1
    12.     mov     edi, esp
    13.     rep     movsb
    14.  
    15.     jmp     esp
    16.  
    17. start1:
    18.  
    19.     invoke  FindFirstFile, szMask, findbuf
    20.     inc     eax
    21.     jz      finish
    22.     dec     eax
    23.     mov     [hFind], eax
    24. @@:
    25.     mov     eax, FILENAME
    26.     invoke  MessageBox, 0, eax, szMask, MB_OK
    27.     invoke  FindNextFile, [hFind], findbuf
    28.     test        eax, eax
    29.     jne     @b
    30. finish:
    31.     invoke  ExitProcess, 0
    32.  
    33. SIZE_ = $ - start1
    34.  
    35.  
    36. data import
    37.     library kernel32, 'kernel32.dll',\
    38.             user32, 'user32.dll'
    39.     include '%fasminc%\api\kernel32.inc'
    40.     include '%fasminc%\api\user32.inc'
    41. end data
    42.  
    43. FILENAME        =   findbuf + 44
    44. findbuf         db  sizeof.FINDDATAW dup (?)
    45. szMask      db  '*.asm', 0
    46. hFind       dd  ?
     
  4. Freeman

    Freeman New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2005
    Сообщения:
    1.385
    Адрес:
    Ukraine
    ухты. у меня мсжбокс с наклоненной перечоркнутой буквой h. не знаю, чо получаецо так. можт защита от выполнения кода в стеке... но если сделоть
    Код (Text):
    1. start1:
    2.  
    3.         invoke  MessageBox, 0, szTest, szTest, MB_OK
    4.  
    5.         mov            word [qwerty], 0BBBBh
    6.  
    7.         invoke  ExitProcess, 0
    8.         szTest  du     'hello!',0
    9. SIZE_ = $ - start1
    то пашет норм
     
  5. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Такое происходит когда вызываешь ф-ию API с невыравненным по границе 4 стеком. Если добавить
    Код (Text):
    1. push eax
    2. and esp, 0xFFFFFFF8
    3. invoke  MessageBox, 0, szTest, szTest, MB_OK
    4. mov     [qwerty], 0BBBBh
    то все будет Ок. Тогда же можно убрать и 'mov [qwerty]m 0BBBBh'.
     
  6. _qwerty_

    _qwerty_ New Member

    Публикаций:
    0
    Регистрация:
    24 фев 2007
    Сообщения:
    17
    Mika0x65
    Спасибо :) Забыл я про выравнивание стека %)

    А зачем перед and esp, 0xFFFFFFF8 нужно push eax? В принципе, я догадываюсь - что бы затем при выравнивании esp не навыравнивать ничего лишнего.
    Только мне такой ситуации получить не удается (что бы без push eax не работало).
     
  7. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Да, это нужно чтобы не загнать esp на участок только что скопированного кода.
    Это зависит от размера кода.
     
  8. _qwerty_

    _qwerty_ New Member

    Публикаций:
    0
    Регистрация:
    24 фев 2007
    Сообщения:
    17
    Хм... а каким образом это зависит от размера кода?
    Я сначала резервирую место в стеке под код, копирую его и esp указывает на начало моего кода, а умножение на 0xFFFFFFF8 выровняет esp в меньшую сторону и поэтому esp никогда не попадет на только что скопированный код! Или я не прав???

    Объясни, пожалуйста.
     
  9. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Не в ту сторону о стеке подумал, вот и все объяснение :dntknw:. Конечно, не нужен там push eax.
     
  10. _qwerty_

    _qwerty_ New Member

    Публикаций:
    0
    Регистрация:
    24 фев 2007
    Сообщения:
    17
    Еще раз спасибо!