Возврат из RtlRemoteCall

Тема в разделе "WASM.WIN32", создана пользователем GoldFinch, 31 мар 2010.

  1. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    как вернуться из RtlRemoteCall?
    пробую вызвать NtSetContextThread(-2, context) в конце вызванного кода - не восстанавливаются eax, edx, ecx

    Код (Text):
    1. include 'win32ax.inc'
    2. entry main
    3.  
    4. .code
    5.  
    6. proc main
    7.         local hThread:DWORD
    8.         invoke CreateThread, 0, 0, TestThread, 0, CREATE_SUSPENDED, 0
    9.         mov [hThread], eax
    10.         invoke RtlRemoteCall, -1, [hThread], testcode, 1, NtSetContextThread, TRUE, TRUE
    11.         invoke ResumeThread, [hThread]
    12.         ret
    13. endp
    14.  
    15. proc TestThread arg:DWORD
    16.         invoke MessageBoxA, 0, "OK", "TestThread", 0
    17.         ret
    18. endp
    19.  
    20. align 4
    21. testcode:
    22.         int3 ; for debug
    23.         ;[esp+0] address of context saved by RtlRemoteCall
    24.         ;[esp+4] NtSetContextThread address
    25.         mov eax, [esp+4]
    26.         push -2 ; GetCurrentThread()
    27.         call eax
    28.         int3 ; unreachable!
    29.  
    30. section '.idata' import data readable writeable
    31.  
    32.   library kernel32,'KERNEL32.DLL',\
    33.           user32,'USER32.DLL',\
    34.           ntdll, 'NTDLL.DLL'
    35.  
    36.   include 'api\kernel32.inc'
    37.   include 'api\user32.inc'
    38.  
    39.   import ntdll,\
    40.         NtSetContextThread, 'NtSetContextThread',\
    41.         RtlRemoteCall, 'RtlRemoteCall'
     
  2. d2k9

    d2k9 Алексей

    Публикаций:
    0
    Регистрация:
    14 сен 2008
    Сообщения:
    325
    Есть траблы с восст. регистров на х64. Но здесь я вижу вроде х86 - GetCurrentThread возвращает псевдо хэндл -2, а вам нужен настоящий хэндл с правами THREAD_SET_CONTEXT для норм работы с натив функциями. Также вроде чтобы установить контекст тред должен быть замороженным.
     
  3. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    GoldFinch
    Модель возврата из сервисов такова, что эти регистры не сохраняются, а используются при возврате(KiServiceExit(), в отличае от KiServiceExit2(), восстанавливающей полный трап-фрейм.)
    Используйте сервис NtContinue для восстановления контекста полностью.
    Текущий поток определяется локально константой (NtCurrentThread = -2).
     
  4. d2k9

    d2k9 Алексей

    Публикаций:
    0
    Регистрация:
    14 сен 2008
    Сообщения:
    325
    Clerk
    Хм, а разве все регистры не сохраняются по [esp]? Ведь можно самому вручную восстановить. Да и вообще логичнее использовать шелкод который сам всё восстановит чем на глюко сервисы полагаться работающие через раз.
     
  5. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    действительно, RtlRemoteCall меняет только eip и esp, так что контекст можно восстановить руками,
    но мне почему-то захотелось применить апи
     
  6. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    не... чтото я не понимаю, как не трогая регистры восстановить eip и esp, если оба лежат в стеке
    разве что самомодификацией кода
     
  7. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    Clerk
    спасибо, NtContinue помогло.
     
  8. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    GoldFinch
    Да что там восстанавливать... Упростил пример из старых закромов с исходниками для случая, когда два dword'а (оригинальный esp, за ним оригинальный eip) лежат на вершине стека:
    Код (Text):
    1. push eax
    2.     mov eax,dword[esp+4]
    3.     xchg eax,esp
    4.     push dword[eax+8]
    5.     mov esp,eax
    6. pop eax
    7. pop esp
    8. sub esp,4
    9. ret
     
  9. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    d2k9
    Нисколько не через раз. Нормально возврат из сервисов быстрый посредством инструкции Sysexit, которая требует в регистрах Ecx и Edx параметры(адрес возврата и указатель на стек), регистр Eax возвращает статус. Никто не говорил что эти регистры должны сохраняться.
     
  10. d2k9

    d2k9 Алексей

    Публикаций:
    0
    Регистрация:
    14 сен 2008
    Сообщения:
    325
    Clerk
    На х64 всё намного веселее ;)
     
  11. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    d2k9
    Про x64 и слова небыло, или уже принято также как и линус толкать куда непопадя ?
     
  12. Sol_Ksacap

    Sol_Ksacap Миша

    Публикаций:
    0
    Регистрация:
    6 мар 2008
    Сообщения:
    623
    GoldFinch
    >как не трогая регистры восстановить eip и esp, если оба лежат в стеке
    iret для 2^6 моды :)

    d2k9
    Нативные функции с псевдохендлами не работают, тред должен быть замороженным, траблы с восстановлением х64-регистров, некие "весёлости" чётко оговоренной в x64 конвенции вызовов, работающие через раз сервисы, инкрементирующийся счётчик загрузок невыгружаемых dll, сессионные рамки даже для глобальных межсессионно секций,..
    Понятно, что людям свойственно ошибаться время от времени, но эта череда расхождений ужасна. Мы собираемся попросить тебя прекратить распространение дезинформации.
     
  13. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Sol_Ksacap
    IRET-фрейм является частью трап-фрейма и вынесен в контекст без изменений, спициально для возврата посредством Iretd.
    Тред необязательно должен быть заморожен.
     
  14. Sol_Ksacap

    Sol_Ksacap Миша

    Публикаций:
    0
    Регистрация:
    6 мар 2008
    Сообщения:
    623
    Clerk
    Пропарсил бы наш пост до конца. Окей, в рамках ежегодного месячника инделюзионного восприятия:
    В первой части сообщения мы полусерьёзно предлагаем ТС воспользоваться инструкцией iret из многобитного юзермода для одновременного восстановления ss:rsp и cs:rip. (О трапфрейме ни слова не было сказано).
    Во второй части мы перечисляем суждения, которые считаем ошибочными. (Нет необходимости сообщать нам о том, что какие-то из них неверны – ведь именно об этом мы и говорим).

    Да простит нас GoldFinch за оффтоп.
     
  15. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    ничего не имею против конструктивного оффтопа, тем более что я уже получил ответы на сабжевый вопрос
     
  16. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Sol_Ksacap
    Вы утверждаете очевидные вещи. Эта структура(без смены кпл, когда стек не переключается):
    Код (Text):
    1. IRET_FRAME struct
    2. rEip        PVOID ?
    3. rSegCs  DWORD ?
    4. rEFlags DWORD ?
    5. IRET_FRAME ends
    Является частью контекста специально для загрузки этих регистров инструкцией Iret.
    Для автора это не имеет значения, так как контекст восстанавливается сразу и полнотью средствами ядра(NtContinue).
     
  17. Sol_Ksacap

    Sol_Ksacap Миша

    Публикаций:
    0
    Регистрация:
    6 мар 2008
    Сообщения:
    623
    Clerk
    >Вы утверждаете очевидные вещи.
    Да, нельзя не согласится. И нам жаль, что определённый человек не может понять, о чём же мы говорим.