Использовать esp для адресации массива

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

  1. Adrax

    Adrax Алексей

    Публикаций:
    0
    Регистрация:
    14 окт 2006
    Сообщения:
    135
    Адрес:
    г. Курск
    Уважаемые программисты!
    Пишу программку, в которой пытаюсь задействовать все регистры, включая esp (через esp хочу адресовать массив). Для этого сохраняю оригинальное содержимое esp в переменную, а затем - возвращаю его восвояси. После сохранения esp со стеком не работаю, функции не вызываю.
    Однако, возникла проблема. Вот фрагмент кода:
    Код (Text):
    1. invoke LoadLibrary,dllka
    2. push eax
    3. invoke GetProcAddress,eax,name1
    4. mov [scanf],eax
    5. pop eax
    6. invoke GetProcAddress,eax,name2
    7. mov [printf],eax
    8. cinvoke printf,inp
    9. cinvoke scanf,d,N
    10. mov [pstack],esp
    11. ;esp сохранил
    12. ;дальше хочу выделить 2 миллиона байт -
    13. ;типа "динамический массив"
    14. invoke GlobalAlloc,GPTR,2000000
    15. ;ставлю здесь int3 - отладчик выскакивает,
    16. ;показывает "нутро" программы.
    17. ;всё идёт по плану
    18. mov esp,eax
    19. ;ставлю здесь int3 (убрав предыдущий, естественно) -
    20. ;отладчик не выскакивает, а программа завершается,
    21. ;не выдав результата и
    22. ;причём не вызывая всплывания отладчика
    В качестве just-in-time debugger юзаю OllyDbg
    Весь исходник вот:
    Код (Text):
    1. format PE console
    2. include 'win32axp.inc'
    3. .data
    4. dllka db 'msvcrt.dll',0
    5. name1 db 'scanf',0
    6. scanf dd ?
    7. name2 db 'printf',0
    8. printf dd ?
    9. inp db 'Input N:',0
    10. d db '%d',0
    11. d4 db '%04d',0
    12. crlf db 13,10,0
    13. N dd ?
    14. len dd 1
    15. pstack dd ?
    16.  
    17. .code
    18. fuck:
    19. invoke LoadLibrary,dllka
    20. push eax
    21. invoke GetProcAddress,eax,name1
    22. mov [scanf],eax
    23. pop eax
    24. invoke GetProcAddress,eax,name2
    25. mov [printf],eax
    26. cinvoke printf,inp
    27. cinvoke scanf,d,N
    28. mov [pstack],esp
    29. invoke GlobalAlloc,GPTR,2000000
    30. mov esp,eax
    31.  
    32. mov ebx,[N]
    33. test ebx,ebx
    34. jl konets
    35.  
    36. mov edi,[len]
    37. xor esi,esi
    38. inc esi
    39. xor eax,eax
    40. cmp ebx,esi
    41. jb mtk1
    42.  
    43. mtk0:
    44. xor ecx,ecx
    45.  
    46. mtk:
    47. movzx edx,word [esp+ecx*2]
    48. imul edx,esi
    49. add eax,edx
    50. xor edx,edx
    51. mov ebp,2710h
    52. div ebp
    53. mov word[esp+ecx*2],dx
    54. inc ecx
    55. cmp ecx,edi
    56. jb mtk
    57. test eax,eax
    58. jnz mtk
    59. inc esi
    60. cmp esi,ebx
    61. mov edi,ecx
    62. jbe mtk0
    63. mov [len],edi
    64.  
    65. mtk1:
    66. mov ebp,esp
    67. mov esp,[pstack]
    68. movzx eax,word [ebp-2+edi*2]
    69. cinvoke printf,d,eax
    70. mov esi,[len]
    71. dec esi
    72. jz konets
    73.  
    74. mtk2:
    75. dec esi
    76. movzx ecx,word[ebp+esi*2]
    77. cinvoke printf,d4,ecx
    78. test esi,esi
    79. jnz mtk2
    80.  
    81. konets:
    82. cinvoke printf,crlf
    83. invoke ExitProcess,0
    84. .end fuck
    Почему так происходит? Никак не пойму...
    И ещё - почему всплыв на int3, OllyDbg не может трассировать код? Если б могла - я бы, наверное, сам

    уже разобрался
     
  2. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Adrax
    Пиши по-русски что ли, раз английского не знаешь. А по поводу трейса: ставишь бряк, Debug -> trace into / trace over, View -> Run trace.

    Возможно, у тебя преждевременный выход на konets, а т.к. указатель стека некорректный, винда молча прибивает прогу. В висте это исправили, кстати.
     
  3. FatMoon

    FatMoon New Member

    Публикаций:
    0
    Регистрация:
    28 ноя 2002
    Сообщения:
    954
    Адрес:
    Russia
    Элементарно - отладчик кладет в стек адрес возврата (адресуя по старому esp). Выполняет 1 команду пошагово - esp теперь указывает на совершенно левую область - пытается из стека что-то вынуть, а там получается исключение, причем не в программе, а в самом отладчике.
     
  4. rain

    rain New Member

    Публикаций:
    0
    Регистрация:
    22 апр 2006
    Сообщения:
    976
    1) Вообще-то полезно смотреть в левый нижний угол окна олика и читать что там происходит когда он не может трассировать код

    2) Может вы используете двухбайтовый бряк ("int 3" в фасм, не приемлимый в среде вин32, и поэтому олик бросает нарушение доступа) вместо однобайтового бряка ("int3" в фасм) и поэтому трассировка дальше невозможна из-за попадания в середину опкода команды

    3) Если вы похерили еsp то JIT отладчик не всплывёт я и сам толком не знаю почему, но таковы особенности
     
  5. rain

    rain New Member

    Публикаций:
    0
    Регистрация:
    22 апр 2006
    Сообщения:
    976
    отладчик использует юзерский стек для своих нужд? это что-то новенькое :)
    до туда дело не доходит
     
  6. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
    Adrax
    Ваш код можно усовершенствовать, не прибегая к помощи регистра esp. К примеру, не использовать во внутреннем цикле сравнение счетчика ecx с регистром edi, а загнать сразу в ecx величину [len] и делать декремент счетчика, сравнивая его с 0. А можно просто сравнивать ecx c [len], тут копейки будут теряться на сравнение. Нет необходимости постоянно загружать в регистр ebp константу, достаточно загрузить ее один раз перед циклами.
    ИМХО здесь можно обойтись без наворотов с esp - подобное его использование может привести к существенным проблемам.
     
  7. FatMoon

    FatMoon New Member

    Публикаций:
    0
    Регистрация:
    28 ноя 2002
    Сообщения:
    954
    Адрес:
    Russia
    а фиг его знает... Когда брекпойнт ставит типа int 3 - куда он нафиг денется??? а указатель на начало выделенной области, а стек растет в другую сторону - и что-то там явно будет с исключением
     
  8. Adrax

    Adrax Алексей

    Публикаций:
    0
    Регистрация:
    14 окт 2006
    Сообщения:
    135
    Адрес:
    г. Курск
    2 IceStudent
    Разве имя метки имеет значение? Я их раньше вообще l1, l2, l3 называл, а сейчас именую так, чтобы не запутаться

    2 FatMoon
    Отладчик юзает стек... Не знаю... Но спасибо за версию!

    2 rain
    Спасибо за разъяснения!

    2 crypto
    Спасибо за совет!
    Но всё же сейчас вопрос стоит именно - как заюзать esp в моих целях?
     
  9. FatMoon

    FatMoon New Member

    Публикаций:
    0
    Регистрация:
    28 ноя 2002
    Сообщения:
    954
    Адрес:
    Russia
    Adrax
    навскидку:

    add eax,1000 ;ну чисто для пробы
    mov esp,eax ;как и было
    ;тут поставь брек
    ...
    Если не вывалится - значит моя версия прошла. Попытка записи в стек была равносильна записи за границы выделенной области. А int 3 - в обязательном порядке что-то запишет в стек (адрес возврата, флаги)

    add:

    проверил сам. Олли у меня НЕ вываливается в 1-м варианте, но дает нормальное "Debugged program was unable to process exeption"
    во втором (add eax, 1000) вообще замечательно отрабатывает.
     
  10. rain

    rain New Member

    Публикаций:
    0
    Регистрация:
    22 апр 2006
    Сообщения:
    976
    да не запишет int3 ничего стек :) разве что самопальный обработчик исключения какой-то
     
  11. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    FatMoon
    Я проверял, олли нормально работает даже с нулевым стеком, до первого call'a :) А если подменить стек просто на буфер, то и с вызовами работает.
     
  12. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    int N юзает стек, так же как и call, так же как и ret.
     
  13. FatMoon

    FatMoon New Member

    Публикаций:
    0
    Регистрация:
    28 ноя 2002
    Сообщения:
    954
    Адрес:
    Russia
    rain
    возможно, что и так... (прочитал обработку int и ничего не понял)

    И если происходит переключение задач в этот момент, тоже в стек приложения ничего не запишется?
     
  14. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    а как же адрес возврата и флаги? )
     
  15. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    Adrax
    я уже не раз обращал внимание на то, что все ваши проблемы от того, что имя стартовой метки используете не кошерное ;)
     
  16. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    n0name
    Каким образом?

    FatMoon
    Ты имеешь ввиду CONTEXT?
     
  17. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    IceStudent
    адрес возврата и флаги кладет в него.
     
  18. rain

    rain New Member

    Публикаций:
    0
    Регистрация:
    22 апр 2006
    Сообщения:
    976
    давайте проясним ситуацию. Что мы имеем: приложение под отладкой с оликом. При этом если в приложение генерирует исключение то сперва получает управление отладчик, даже при установленном сехе.
    в мане интела:
    это происходит аппаратно, но что если esp = 0?
    я не знаю досконально как это это происходит(может кто-то объяснит), но олик нормально получает управление и в стеке никаких изменений не показывает
     
  19. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Разве? Насколько я понимаю, отладчик узнает об исключении только в том случае, если ни один SEH обработчик не согласился обработать исключение. Со слов Mat Pietrek'а отладчик вызывает ф-ия UnhandledExceptionFilter, которая вызывается в этом случае.
     
  20. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Mika0x65
    это second chance насколько я помню. а сначала отладчик получает first chance exception, до вызова любых хендлеров. подправьте если не так