Дизассембл NTDLL - странный адрес для перехода

Тема в разделе "WASM.NT.KERNEL", создана пользователем Ivan_32, 11 мар 2010.

  1. Ivan_32

    Ivan_32 New Member

    Публикаций:
    0
    Регистрация:
    29 ноя 2008
    Сообщения:
    18
    Код (Text):
    1. .text:77F05070                 public ZwMapViewOfSection
    2. .text:77F05070 ZwMapViewOfSection proc near            ; CODE XREF: sub_77EC826D+100p
    3. .text:77F05070                                         ; RtlCreateQueryDebugBuffer+63p ...
    4. .text:77F05070                 mov     eax, 0A8h       ; NtMapViewOfSection
    5. .text:77F05075                 mov     edx, 7FFE0300h
    6. .text:77F0507A                 call    dword ptr [edx]
    7. .text:77F0507C                 retn    28h
    8. .text:77F0507C ZwMapViewOfSection endp
    Насколько я понял из этой темы, по адресу 0x7FFE0300 лежит код который вытаскивает из таблицы нужный адрес и дескриптор, пишет их в MSR-ы и выполняет SYSENTER. Меня интересует как поглядеть на этот код? IDA я так понимаю, вычисляет адреса по принципу PE.MountBase + RVA, но никаким 0x7FFE0300 там и не пахнет. Меня больше всего интересует как эта функция вычисляет (или откуда берет) нужный дескриптор+адрес. Я ведь правильно понимаю что сделать такой системный вызов по сути может любой процесс, если бы было по другому тот же DeviceIoControl не смог бы работать.
     
  2. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    в kernel32
     
  3. Ivan_32

    Ivan_32 New Member

    Публикаций:
    0
    Регистрация:
    29 ноя 2008
    Сообщения:
    18
    В дизассембле Kernel32.dll тоже максимальный адрес намного меньше этого.
    .data:77EA6FEC end DllEntryPoint ; это последняя строка в дизассембле.
    Может я неправильно пользуюсь идой?
     
  4. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Ivan_32
    MSR'ы загружает ядро при инициализации в функе KiLoadFastSyscallMachineSpecificRegisters(), код выше называется системным стабом, ссылка на разделяемую ядром память в конце ап, загружается туда тоже ядром на основе экспорта нтдлл в PspLookupKernelUserEntryPoints(). Эта память отображена на все процессы(0x7FFE0000) и ядро(0xFFDF0000).
    +0x300: KiFastSystemCall/KiIntSystemCall, +0x304: KiFastSystemCallRet, +0x2F8: 0xC3(Ret опкод).
     
  5. Ivan_32

    Ivan_32 New Member

    Публикаций:
    0
    Регистрация:
    29 ноя 2008
    Сообщения:
    18
    Clerk, огромное спасибо! Но вот еще такой вопрос. Получается в системе всего один адрес отвечает за SYSENTER( я думал что каждый раз при вызове в MSR-ы грузятся адреса функций в KM) и получается все входные параметры - это номера функций в ядре и какие то еще доп.параметры? А каким образом передаются аргументы для функций? Или они туда едут в регистрах общего назначения? Можно если не сложно алгоритм этого действа в общих чертах?
    Т.е. в eax пишется номер функции, в edx что то еще и вызывается SYSENTER параметры для которого ядро уже подгрузило. Скажем, если я опробую такой общий метод:
    mov eax,0x8
    mov edx,0x7FFE0300
    call [edx]

    PS: Дизассемблер в CheatEngine(им всегда смотрю память процессов - очень удобно, хоть и дизассемблер хромает...) показал по адресу 0x7FFE0300 вот такую штуку:
    7FFE0300 - f0 64 1d 77 f4 64 1d - lock sbb eax,1d64f477
     
  6. Twister

    Twister New Member

    Публикаций:
    0
    Регистрация:
    12 окт 2005
    Сообщения:
    720
    Адрес:
    Алматы
    Не надо пользоваться непонятно чем, используй нормальные утилиты. OllyDbg может тебе показать, что по адресу 7FFE0300 лежит указатель на KiFastSystemCall:
    Код (Text):
    1. 7FFE0300  7C90E4F0  ntdll.KiFastSystemCall
    Именно он и вызывается кодом
    Код (Text):
    1. mov     edx, 7FFE0300h
    2. call    dword ptr [edx]
    Ну а там всего-ничего до разгадки тайны осталось:
    Код (Text):
    1. 7C90E4F0 > 8BD4             MOV EDX,ESP
    2. 7C90E4F2   0F34             SYSENTER
    3. 7C90E4F4 > C3               RETN
    На стеке.
     
  7. Ivan_32

    Ivan_32 New Member

    Публикаций:
    0
    Регистрация:
    29 ноя 2008
    Сообщения:
    18
    Так ведь дескриптор стека берется из IA32_SYSENTER_CS+8 да и сам ESP из IA32_SYSENTER_ESP или я что то неправильно понял?
     
  8. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    У вас температура, вы бредите? Какая таблица? Какие дескрипторы?

    Обычный системный сервис выполняется командой SYSENTER или int 0x2e. В случае с сисентер нужно передать параметры:
    EAX = номер системного сервиса в таблице (младшие 12 бит), номер таблицы системных сервисов (2 бита).
    ну или просто можно сказать, что в EAX номер системного сервиса.
    а в EDX указатель на параметры, один за другим. располагают их на стеке.
    Параметры передаются как обычные параметры в ф-ии push'ами, поэтому они там уже лежат. Достаточно записать esp в edx. (на самом деле, там еще лежит адрес возврата из KiFastSystemCall в ZwXXX, и еще один адрес возврата из ZwXXX в пользовательский код, но ядро делает корректировки самостоятельно).

    На системах, что не поддерживают инструкцию SYSENTER, используется программное прерывание 2E.
    Системный сервис выполняется командой int 0x2e. в EAX по прежнему номер системного сервиса, в EDX уже должен быть прямой указатель на параметры (минуя два адреса возврата).
    Именно это и делает код KiIntSystemCall:
    lea edx, [esp+8] ; edx = указатель на параметры (взять стек и пропустить 8 байт - два адреса возврата)
    int 0x2e

    Вот такие вот дела. Еще есть KiFastSystemCallRet - ее видели все, кто хоть раз что-то отлаживал в ольке.
    Она состоит из одного RET и туда управление попадает после каждого системного сервиса, для этого в EDX ядро предварительно перед SYSEXIT загружает адрес этой самой KiFastSystemCallRet, которое берет из той же структуры KUSER_SHARED_DATA, из которой и юзермодный код берет адрес SystemCallStub. В юзермод эта структура промаплена про адресу 7FFE0000 обычно, в ядро - FFDF0000.
    В случае с int 0x2e возврат выполняется обычным iretd.
    int 0x2e сейчас обычно используется в драйверах (например, хотят вызвать неэкспортируемый системный сервис из дарйвера ядра. нужно юзать int 0x2e, SYSENTER из ядра нельзя вызывать).

    Хотя, выше я немножко приврвал насчет SYSEXIT. Как я помню, возврат из сервиса, в который вошли по SYSENTER, происходит через тот же IRETD. Впрочем, это совершенно не важно в данном контексте.
     
  9. d2k9

    d2k9 Алексей

    Публикаций:
    0
    Регистрация:
    14 сен 2008
    Сообщения:
    325
    Great
    А загрузить свой адрес возврата минуя KiFastSystemCallRet?
     
  10. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Great
    Он и через Iret и через Sysexit выполняется. Зависит от некоторых условий, как например TF.
    d2k9
    Ведь вы можите логически подумать, наверно.. :)
     
  11. d2k9

    d2k9 Алексей

    Публикаций:
    0
    Регистрация:
    14 сен 2008
    Сообщения:
    325
    Ессно :)
    Тока зачем, если Грейт поднял эту тему и походу посвящён во все тонкости? ;)
     
  12. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    d2k9
    Чтоб не захламляли ни мне, ни другим личку своими тупыми вопросами.)
     
  13. d2k9

    d2k9 Алексей

    Публикаций:
    0
    Регистрация:
    14 сен 2008
    Сообщения:
    325
    А я вам сейчас ничего и не писал ;)
     
  14. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Откуда и с какой целью? Из юзермода с целью перехватить возврат из сервиса? Не получится, загружается из ядра. Из ядра - смысла мало.

    Хм. Да, точно. На трассировку условие есть
     
  15. d2k9

    d2k9 Алексей

    Публикаций:
    0
    Регистрация:
    14 сен 2008
    Сообщения:
    325
    В юзермоде, как вариант извратиться и в юзермоде записать перед вызовом в эту структуру свой адрес возврата, а затем вернуть обратно.
    З.Ы. Перехваченные функции в ядре через SSDT к примеру при вызове из юзермода через сисколы или прерывания ессно срабатывают, а не оригинальные? Что-то я замотался сегодня...
     
  16. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    d2k9
    В юзермод KUSER_SHARED_DATA промаплена только на чтение.

    Что?
     
  17. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    d2k9
    Думаю вы не против лог выложить:
    ;))
     
  18. d2k9

    d2k9 Алексей

    Публикаций:
    0
    Регистрация:
    14 сен 2008
    Сообщения:
    325
    Clerk
    Конечно, мне нежалко, другим поможет ;)
     
  19. d2k9

    d2k9 Алексей

    Публикаций:
    0
    Регистрация:
    14 сен 2008
    Сообщения:
    325
    Фигово, получается любой лузер может перехватить KiFastSystemCallRet и измываться над сисколами :dntknw:
     
  20. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    d2k9
    Например ?