Перехват KeFastSystemCall

Тема в разделе "WASM.WIN32", создана пользователем katrus, 23 июл 2008.

  1. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    Для профайлинга вызова API хочу сделать патч на KeFastSystemCall. Подумаль что самый простой способ - поменять адрес по которому находится KeFastSystemCall (7FFE0300) на свой.

    Так как адрес 7FFE0300 разделен между всеми процессами, сделал VirtualProtect(7FFE0300, 4, PAGE_WRITECOPY). Не работает :dntknw:

    Собственно, как правильно делать патч на KeFastSystemCall?
     
  2. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    Кстати, обнаружил, что просто пропатчить KiFastSystemCall нельзя. Длина этой функции всего 4 байта. Банальным образом нет места для jmp.
     
  3. 2FED

    2FED New Member

    Публикаций:
    0
    Регистрация:
    20 фев 2008
    Сообщения:
    1.002
    а за ней нопов нету, вылезти некуда?
     
  4. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    Сразу за ней - KiFastSystemCallRet. И нопов нема. Полследний байт jmp затирает KiFastSystemCallRet.
     
  5. a1ss

    a1ss New Member

    Публикаций:
    0
    Регистрация:
    18 ноя 2007
    Сообщения:
    120
    Ну и что? Используй короткий джамп. 2 байта до нопов допрыгнуть тебе хватит.

    later:посмотрел.. не хватит :) Ближайщее подходящее место через 0xCB байт :dntknw:
     
  6. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    Сам только что посмотрел - в округе нет никаких "пустот"
     
  7. Prince

    Prince New Member

    Публикаций:
    0
    Регистрация:
    9 июл 2008
    Сообщения:
    71
    sysenter/syscall/int2e перехват?
     
  8. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    Prince
    Это последняя мера. Не хочется писать дополнительный драйвер. Овчинка не стоит выделки ...
     
  9. CrystalIC

    CrystalIC New Member

    Публикаций:
    0
    Регистрация:
    26 июл 2008
    Сообщения:
    500
    Судя по ссылке которую вы указали (7FFE0300) вы решили выполнить перехват изменением адреса KiFastSystemCall в разделяемой ядром памяти, это UserSharedData.FastSystemCall вроде называется, не помню точно. Физический адрес для SP2 этой переменной равен 0FFDF0000h + 300h, в SP1 модель вызова другая. Для такого перехвата следует атомарно(lock xchg..) загрузить новый адрес, а эффективнее уменьшить на пять значение этой переменной(там адрес ntdll!KiFastSystemCall) а перед этой точкой находятся 5 инструкций nop, которые в процессе для которого выполняется перехват заменяются на инструкцию Jmp near KiFastSystemCallHandler.
    Второй вариант. По адресу KiFastSystemCall первая инструкция - mov edx,esp и она занимает 2 байта. Вместо этой инструкции вписать инструкцию Jmp short Reference, а Reference - это инструкция Jmp near KiFastSystemCallHandler, которая заёмёт 5 байт и разместить её можно сразу за точкой KiFastSystemCallRet, где есть 5 свободных байт для SP2. Там в WindowsVista вместо нопов находятся две инструкции lea esp,dword ptr ss:[esp], которые занимают больше 5 байт, так что можно вписать непосредственно адрес перехода(push KiFastSystemCallHandler/ret).
    Кстати интересный момент, Vista, код под олей:
    Код (Text):
    1. 008D0F34 KiFastSystemCallRet \$  C3                         ret
    2. 008D0F35                      .  8DA424 00000000            lea esp,dword ptr ss:[esp]
    3. 008D0F3C                      .  8D6424 00                  lea esp,dword ptr ss:[esp]
    4. 008D0F40 KiIntSystemCall     /$  8D5424 08                  lea edx,dword ptr ss:[esp+8]
    Интересно сравнить опкоды для одинаковых инструкций. Ну это другая тема.
    Третий вариант. Изменение собственно заглушки. Замена инструкции Call edx для SP1 либо Call dword ptr [edx] для остальных версий. Тут комментарии думаю излишни.
    Четвёртый вариант. Как ктото и сказал модификация MSR.
    Пятый вариант.
    Наиболее эффективен и сложен для реализации. Использование аппаратных точек останова.
    Установка аппаратной точки останова(DR) на адрес KiFastSystemCall для всех потоков либо для потока в котором следует выполнить перезват. Тут есть один важный момент, а именно использует ли код отладочные регистры помимо этого перехвата. Если нет то думаю стоит это заюзать.
    Шестой вариант. Механизм исключений. Подобно варианту 5. Запись инструкции которая вызовет исключение по адресу KiFastSystemCall. Для глобальной установки обработчика исключений следует использовать самый низкий хук, а именно той точки откуда поток начнёт выполнятся при возникновении исключения - ntdll!KiUserExceptionDispather. Это имеет смысл и для предыдущего пункта.
    Ну в общем и всё касательно юзермода, это основные способы перехвата этой точки.
    Насчёт режима ядра не буду обсуждать, так как раздел Win32. Думаю этого достаточно чтобы вы выбрали оптимальный вариант.
     
  10. blast

    blast New Member

    Публикаций:
    0
    Регистрация:
    8 мар 2008
    Сообщения:
    170
    Есть ещё вариант перечислить все экспортируемые функции ntdll и сравнивать их имена примерно так:

    .if word ptr [eax]=='wZ'
    ...
    Call Callback
    ...
    .endif

    7C90D379 > B8 00000000 MOV EAX,0
    7C90D37E BA 0003FE7F MOV EDX,7FFE0300
    7C90D383 FF12 CALL DWORD PTR DS:[EDX]
    7C90D385 C2 1800 RETN 18

    Патчить лучше всего MOV EDX,7FFE0300 на Call XX, обработчик будет примерно таким:

    SystemServiceHandler proc C
    ;в Eax номер сервиса, в стэке параметры.
    return_:
    mov edx,KUSER_SHARED_DATA.SystemCall[KUSER_SHARED_DATA_ADDRESS]
    retn 0
    SystemServiceHandler endp

    Если нужна совместимость с win2k, это один из самых оптимальных вариантов.

    katrus
    Если не нужна совместимость с win2k то проще и не палевнее всего поменять dword по адресу SystemCall, почему у тебя не получилось не понятно, все должно работать что-то не правильно вызываешь.
     
  11. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Тебе в любом случае будет выдана частная копия страницы, так что не ссы. Даже если поставишь PAGE_READWRITE.
    Винда не такая тупая, чтобы твои изменения отражались на всех остальных процессах.
    Чтобы отразились придется наоборот постараться

    UPD: Хм, у меня не получается ни изменить права доступа, ни записать туда что-то...
     
  12. CrystalIC

    CrystalIC New Member

    Публикаций:
    0
    Регистрация:
    26 июл 2008
    Сообщения:
    500
    Great
    lock xchg dword ptr ds:[0FFDF0000h + UsSystemCall],eax
    Сразу во всех процессах изменяется, любая запись в разделяемую память.
    [Если имеется ввиду юзермод то никак.]
     
  13. blast

    blast New Member

    Публикаций:
    0
    Регистрация:
    8 мар 2008
    Сообщения:
    170
    Да из юзермода никак не изменишь, а вообще если изменить то придется во все созданные процессы впихивать хэндлер и ставить нотификацию на создание новых, либо писать код прямо в shared memory, там места достаточно.