Как вызвать KiSystemService?

Тема в разделе "WASM.BEGINNERS", создана пользователем IceFire, 9 май 2009.

  1. IceFire

    IceFire New Member

    Публикаций:
    0
    Регистрация:
    30 окт 2006
    Сообщения:
    244
    Great

    И в том, и в другом случае (STATUS_INVALID_HANDLE и STATUS_SUCCESS) hFile равен конкретному значению, к примеру - 0x1320. Но в первом случае - STATUS_INVALID_HANDLE, а во втором - все хорошо.

    Clerk
    Мне сейчас нет дела до стабильности перехвата и до возможности его обхода, я не малвару пишу и не коммерческий продукт. Это - просто инструмент, чтобы собрать данные. А собрать их не получается из-за STATUS_INVALID_HANDLE, который возвращает ZwWriteFile.
     
  2. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    А кому есть дело до потенциально кривых перехватов, разгребайте сами свой гуан. Придумал ерунду какуюто. Следует спрашивать об альтарнативе, решении которое должно быть реализовано, а не вычитав какойто принцип кричать как его заюзать. А в малваре это нельзя применить.
    Следует сохранить регистр флагов. Стек сдвигать нужно(из TSS загружать), прерывания необходимо разрешить после перезагрузки указателя на стек. Сегментные регистры Ds и Es необходимо перезагрузить(загрузить KGDT_R3_DATA or RPL_MASK). Установить обработчик исключений для #DB(ибо изза изменённого адреса в MSR будет необработанное трассировочное исключение при вышеприведённом вызове). Если юзаются функции помимо Zw* следует изменить PreviousMode вручную на KernelMode.
    Но кодес мой вы потестите..
     
  3. IceFire

    IceFire New Member

    Публикаций:
    0
    Регистрация:
    30 окт 2006
    Сообщения:
    244
    Clerk

    Спасибо, обязательно вечером попробую. Не кипятись, у меня есть желание разобраться во всем, я только-только начал что-то писать для ring0. Просто литературы мало, а может - я не знаю что читать. Буду признателен за любые ссылки. Я отлично понимаю, что копипастить чужой код, не вникая в смысл, - плохо. Поэтому и обращаюсь к вам за помощью там, где не понимаю.
     
  4. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    IceFire
    Не надо никаких previous mode.

    открывай хендл как OBJ_KERNEL_HANDLE , чтоб он был валидный из любого контекста.
     
  5. IceFire

    IceFire New Member

    Публикаций:
    0
    Регистрация:
    30 окт 2006
    Сообщения:
    244
    Great

    Ну да, Zw* функции его, вроде, должны ставить самостоятельно.
     
  6. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Никто ничего не должен тебе если явно не укажешь в InitializeObjectAttributes.
    У кернел хендлов старший бит стоит (80000000)
    я поэтому у тебя и спрашивал какое числовое значение хендла (!) чтобы посмотреть старший бит. он сброшен - хендл юзермодный.
    сделай как я говорю, должно работать

    InitializeObjectAttributes (
    &oa,
    &fileName,
    OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
    NULL,
    NULL
    );
     
  7. IceFire

    IceFire New Member

    Публикаций:
    0
    Регистрация:
    30 окт 2006
    Сообщения:
    244
    Great

    Спасибо!

    Все, действительно, заработало. Спасибо, что тебя не заломало все подробно объяснить. Я не знал, что у кернел-хендлов стоит старший бит. Сейчас появились другие проблемы, но я пока сам попробую разобраться.

    Подскажи, если не трудно, что почитать о программировании в кернел-моде, о том, как сделать сплайс безопасным. Я хочу разобраться сам и по пустякам не тревожить вас.
     
  8. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Оказалось, иногда я говорю что-то полезное)
    Ты просто создавал хендл в одном процессе, а обращался к нему из конткеста произвольного процесса. Поэтому и статус_инвалид_хендл.
    А я тебе еще больший секрет открою: там еще есть контрольные биты (по-моему, 0 и 1 - поэтому хендлы почти всегда кратны 4, поскольку они сброшены).

    Практически никак =) Придется исхитряться в каждом конкретном случае и подстраиваться под перехватываемую функцию. Либо сменить метод хука.
     
  9. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Как успехи с бсодогенератором, интересно скажите.
     
  10. IceFire

    IceFire New Member

    Публикаций:
    0
    Регистрация:
    30 окт 2006
    Сообщения:
    244
    Clerk

    БСОДогенератор получился =) Осталось отучить его делать БСОДы =) Некогда пока, как поковыряю еще - отпишу.
     
  11. IceFire

    IceFire New Member

    Публикаций:
    0
    Регистрация:
    30 окт 2006
    Сообщения:
    244
    Отписываюсь по поводу БСОДогенератора.

    Пытаюсь сделать все правильно (по посту Clerk'a). Переписал ф-цию вот так:

    Код (Text):
    1. __declspec(naked) void MyKiFastCallEntry(void)
    2. {
    3. __asm{
    4.             //get SrvNum
    5.             pop  edi    
    6.             mov  i, eax  
    7.      
    8.             pushad
    9.             pushfd
    10.             push fs
    11.        
    12.             /* Set FS to PCR */
    13.             mov ecx, 0x30 //mov ecx, KGDT_R0_PCR
    14.             mov fs, cx
    15.            
    16.             /* Set DS/ES */
    17.             mov ecx, KGDT_R3_DATA + RPL_MASK //mov ecx, KGDT_R0_DATA
    18.             mov ds, cx
    19.             mov es, cx
    20.            
    21.             /* Set the current stack */
    22.             //cli
    23.             //mov ecx, fs:[0x40]
    24.             //mov esp, ss:[ecx+KTSS_ESP0]
    25.             //sti
    26.             }
    27.            
    28.             WriteServiceNumber(i);
    29.             DbgPrint("Get service ID:%X \n",i);
    30.            
    31. __asm{    
    32.             pop fs
    33.             popfd
    34.             popad
    35.             jmp pMovedSysenterCode
    36.       }
    37. }
    Если раскомментировать это:
    Код (Text):
    1.             //mov ecx, fs:[0x40] //fs:0x40 [fs:KPCR_TSS]
    2.             //mov esp, ss:[ecx+KTSS_ESP0] //ss:[ecx+KTSS_ESP0]
    система виснет.

    Если добавить cli/sti - ребут незамедлительно.

    Что не так?
     
  12. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Сделать "правильно", это не по посту кого-то там, а как документировано в мсдн через IoConnectInterrupt. Она, точне ене она, а KINTERRUPT::lol: ispatchCode делает всю нужную работу по входу в кернел мод из юзер мода.
     
  13. IceFire

    IceFire New Member

    Публикаций:
    0
    Регистрация:
    30 окт 2006
    Сообщения:
    244
    Great

    ...и потом можно будет вызвать оригинальный обработчик KiFastCallEntry? Или сразу нужно вызывать Zw* функцию по коду?
     
  14. IceFire

    IceFire New Member

    Публикаций:
    0
    Регистрация:
    30 окт 2006
    Сообщения:
    244
    Great

    Прочитал в MSDN об IoConnectInterrupt и ничего не понял (. Как понял из описания, она регистрирует новый обработчик прерывания. Как ее использовать в перехваченной KiFastCallEntry?
     
  15. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Так, я попутал с другим тредом.
    Это зачем тебе?
    Что ты вообще собираешься делать из своего MyKiFastCallEntry?
    Распиши подробно что тебе надо вызывать оттуда и зачем
     
  16. IceFire

    IceFire New Member

    Публикаций:
    0
    Регистрация:
    30 окт 2006
    Сообщения:
    244
    Мне нужно определить номер системного сервиса, который сейчас вызывается. После этого дернуть ZwWriteFile и записать номер этого сервиса в файл. Все.

    В принципе, код написан и даже иногда работает )) Но БСОДит. Даже не БСОДит, а сразу уходит на ребут. Clerk вверху пост написал, в котором перечислил все, что надо делать, чтобы стабильно работало. Пытаюсь сделать по его совету.
     
  17. wasm_test

    wasm_test wasm test user

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

    Но если так неймется - можно это сделать и из обработчика. Для разрешения прерываний на стеке необходимо иметь валидный KTRAP_FRAME.
    ЕГо можно создавать вручную, но это страшный геморрой. Слава Биллу, винда предоставляет документированный механизм установки высокоуровневых обработчиков аппаратных прерываний. SYSENTER в принципе не сильно отличается от прерывания, поэтому IoConnectInterrupt для него тоже подойдет.
    IoConnectInterrupt создает объект KINTERRUPT, в нем есть поле DispatchCode (недокументировано). В него динамически записывается код обработки, который как раз создает валидный треп фрейм, разрешает прерывания и вызывает высокоуровневую ISR. Фактически, выполняет нормальный вход в ядро из режима пользователя.
    Нам нужен именно этот код. Проще всего выделить свободный вектор через HalGetInterruptVector (на висте работать не будет) и сделать IoConnectInterrupt на этот вектор со своей ISR. В ISR уже делать все, что требуется, а именно - можно, например, и ZwWriteFile вызвать. Правда, придется еще сделать грязный хак с понижением IRQL вручную, но в данном случае это допустимо.
    После установки этого фейкового вектора ставим хук на sysenter и в качестве обработчика в IA32_SYSENTER_EIP_MSR пишем адрес нашего KINTERRUPT::lol: ispatchCode. Либо можно скопировать код, но проще будет оставить фейковый вектор. Он никому не мешает.
    Примерный код "как это делать" можно найти в исходниках моего отладчика, простите за саморекламу, http://www.google.com/codesearch/p?...terrupt package:http://ngdbg\.googlecode\.com
    Он там закомментирован, поскольку не используется, но он в принципе должен быть рабочим. Только там таким образом ставится вектор 03 (#DB), но разницы с SYSENTER там не будет практически.
    Вот адрес &InterruptObject->DispatchCode нужно установить будет как обработчик SYSENTER.
     
  18. IceFire

    IceFire New Member

    Публикаций:
    0
    Регистрация:
    30 окт 2006
    Сообщения:
    244
    Great

    Делаю по твоему коду. IoConnectInterrupt возвращает STATUS_INVALID_PARAMETER. Хотя код я не менял.
    HalGetInterruptVector вернул TempVector=0x30, Irql = 0x1b, Affinity = 1.
     
  19. wasm_test

    wasm_test wasm test user

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

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Обработчик выполняется в DPC-стеке, его нужно переключить загрузив из TSS. Прерывания инструкция Sysenter маскирует. Всё подробно описано: http://files.virustech.org/indy/Code/Sysenter/CsDbg/Trap.asm