Access violation при возврате из 64 битного режима

Тема в разделе "WASM.WIN32", создана пользователем Thetrik, 13 фев 2020.

  1. Thetrik

    Thetrik UA6527P

    Публикаций:
    0
    Регистрация:
    25 июл 2011
    Сообщения:
    875
    Все работает, вот лог:
     
    Indy_ нравится это.
  2. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    Наверно что бы кто тупо это запустил и дал отчёт нужно ждать до весны :sad:

    Мне необходим этот тест.
    --- Сообщение объединено, 14 фев 2020 ---
    Thetrik,

    Вот ты вовремя. Запускай многократно, если у тебя был анстаб то это не может не падать, это невозможно.
    --- Сообщение объединено, 14 фев 2020 ---
    Thetrik,

    Ты сказал что ошибка не появляется после перезагрузки SS, это точно, тоесть при многократных циклах/тестах ?

    Я не использовал удобный callfar, а jmpfar что бы до смены мода не было обращений к стеку, что бы повторить твою ошибку. Такого не может быть, если у тебя падает после смены при обращении к стеку, а это аналогично сделано и ошибки нет.
     
  3. Thetrik

    Thetrik UA6527P

    Публикаций:
    0
    Регистрация:
    25 июл 2011
    Сообщения:
    875
    Ну да. После того как я сделал сохранение/восстановление SS - перестало падать (оба семпла).
     
    Indy_ нравится это.
  4. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    Thetrik,

    T3 это код:

    Код (Text):
    1.     mov r10d,esi
    2.     mov edx, edi
    3.     syscall
    4.     jmp far m16:32
    5.     ...
    6.     push
    аналогичный твоему:

    Код (Text):
    1.  
    2.  jmp far m16:32
    3.  ret
    4.  
    - после возврата в compat mode одинаковая выборка в стек. sysret мы исключили, с iret не понятно, точнее ясно что прерывание никак дк не затрагивает, но это может делать планировщик..

    Почему тогда твой код падает, а мой такой же нет ?

    > После того как я сделал сохранение/восстановление SS - перестало падать

    А это точно, тоесть может просто вероятность падения уменьшилась или вообще не падает ?
     
  5. Thetrik

    Thetrik UA6527P

    Публикаций:
    0
    Регистрация:
    25 июл 2011
    Сообщения:
    875
    Работает 2 часа, падений нет.

    В семпле, также происходит изменение стека в long mode. Мб из-за этого? Во втором тесте я помимо комментирования перезагрузки сегмента также закомментил смену стека. Падений все равно нет. МБ функцию поменять? NtQueryPerformanceCounter заменить на NtQueryInformationProcess как у меня?
     
  6. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    Thetrik,

    На 8-ке нечто странное, NtQueryInformationProcess имеет 5 аргументов: R10, RDX, R8, R9, [RSP]. Если вызвать с переключением стека(xchg rsp,r14), то сервис успешно отрабатывает. Если стек не переключить, то сервис возвращает #AV, не смотря на то, что аргументы валидны. В твоём семпле такой ошибки нет.
    --- Сообщение объединено, 15 фев 2020 ---
    Вот скрин.
    --- Сообщение объединено, 15 фев 2020 ---
    Я изменил пе-хидер(стек и subsys.), что бы разницы в адресах стека небыло.
    --- Сообщение объединено, 15 фев 2020 ---
    Thetrik,

    Кстате у тебя это не правильно:

    Код (Text):
    1.     .if ebx = 0
    2.         movsxd rcx, dword [eax]
    3.     .elseif ebx = 1
    4.         movsxd rdx, dword [eax]
    5.     .elseif ebx = 2
    6.         movsxd r8, dword [eax]
    7.     .elseif ebx = 3
    8.         movsxd r9, dword [eax]
    9.     .else
    10.         movsxd rdi, dword [eax]
    11.         mov [rsp + rbx*8], rdi
    12.     .endif
    --- Сообщение объединено, 15 фев 2020 ---
    Хотя нет, всё верно, в стабах mov r10,rcx.
     

    Вложения:

    • scall.png
      scall.png
      Размер файла:
      12 КБ
      Просмотров:
      294
  7. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    Thetrik,

    Косяк был со смещением параметров..
    --- Сообщение объединено, 16 фев 2020 ---
    Аргументы syscall:

    Код (Text):
    1.         mov     rsi, TrRsp[rbp]         ; get previous stack address
    2.         lea     rsi, (4 * 8)[rsi]       ; compute copy source address
    3.         ...
    4.         mov     rax, 8[rsi]             ; copy first argument
    5.         mov     8[rdi], rax             ;
    6.  
    7.         ALTERNATE_ENTRY KiSystemServiceCopyEnd
    8.  
     

    Вложения:

    • G3.7z
      Размер файла:
      3,5 КБ
      Просмотров:
      270
  8. Pavia

    Pavia Well-Known Member

    Публикаций:
    0
    Регистрация:
    17 июн 2003
    Сообщения:
    2.409
    Адрес:
    Fryazino
    iret команда противная, особенно в связки с другими. Если запретить прерывания, то сработавшее исключение фиксируется внутри процессора и висит до разрешения прерываний, что происходит при IRET. Проблема в том что исключения фиксируют адрес только после сброса прерывания. Т.е после iret на ту команду на которую укажет. По этому отладчик кажет что исключение пришлось на jmp. Когда как исключение на самом деле произошло внутри функции.

    Это проверяется через счётчик тактов достаточно поставить RDTSC до jmp far @f и после.

    А вот что-бы найти место исключения надо постараться. Разрешить прерывания там где они запрещены и ещё по хорошему надо отсеять ветки в которых ss был перегружен очищен и изменён на корректный.
     
  9. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    Pavia,

    > висит до разрешения прерываний

    Если выполнить cli/ud2 система сразу упадёт, ничего не зависнет.

    > Т.е после iret на ту команду на которую укажет.

    При обработке прерывания исключение невозможно, так как контекст прерывания полностью изолирован. IRET не может вызвать исключение, так как если cs:eip/rip не валид, то будет исключение после смены мода, когда невалид сегмент начнёт исполняться.

    > По этому отладчик кажет что исключение пришлось на jmp.

    Там срабатывает точка останова уже в compat., далее при обращении к стеку идёт исключение. Совершенно не ясно как такое может быть; если бы контекст был невалид, то код бы не выполнялся(без обращений к стеку) и точка останова не сработала бы.

    Возврат из сервиса идёт через sysret, может там что то не по докам работает.. хотя опять же не понятно, так как падение не каждый раз, а случайно.
     
  10. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    Thetrik,

    Так что с семплом выше, падает или нет ??
     
  11. Thetrik

    Thetrik UA6527P

    Публикаций:
    0
    Регистрация:
    25 июл 2011
    Сообщения:
    875
    Извиняюсь, не видел сообщение. Нет не падает.
    Тут еще один ньюанс есть, мб будет кому-то интересно. NtWow64ReadVirtualMemory64 на Win10, рассматривает хендлы как беззнаковые. Так нельзя передать -1 в нее, поскольку WoW64 расширяет это значение как беззнаковое (использует mov вместо movsx):
    Win7:

    win7.png
    Win10:
    win10.png
    Вариант обхода данного ограничения, вместо псевдохендла использовать реальный хендл.
     
    M0rg0t нравится это.
  12. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    Thetrik,

    > Нет не падает.

    Я не помню тех подробности, тут не ответили, я просил потестить на кл, но там толпа барыг и им тоже взападло пускануть семпл. Теста небыло, а как и что я не помню. Нужно начинать всё заново.

    Соответственно такое отношение к тебе и будет далее, не заметил/проигнорил разбирайся сам; я все нюансы нужные для себя выяснил :punish:
     
  13. Thetrik

    Thetrik UA6527P

    Публикаций:
    0
    Регистрация:
    25 июл 2011
    Сообщения:
    875
    Indy_, я тестил все семплы которыебыли скинуты. Я сразу писал что не падает, а после перезагрузки SS и мои перестали падать. Последний тоже тестировал - не падало, просто забыл отписать сюда, т.к. думал что отписал.