Перехват syscall из ring 3

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

  1. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    mwizard
    Этот флажёк может юзать обычная программа в целях защиты, пакеры это используют. Подмена обработчика в MSR это потенциальный бсодогенератор.
    Вот как это нужно делать http://frmn.org.ua/index.php?page=show&id=18
     
  2. Exp10der

    Exp10der Мастер дзена

    Публикаций:
    0
    Регистрация:
    27 авг 2007
    Сообщения:
    337
    Адрес:
    Красноярск
    Clerk кстати да делал, но особо не тестил на практике, хотя да согласен вариант не из лучших имхо
     
  3. mwizard

    mwizard New Member

    Публикаций:
    0
    Регистрация:
    13 апр 2009
    Сообщения:
    13
    Это понятно, просто юзеры сами системных вызовов не делают :) Мне это показалось забавным.

    Вопросов нет. Но это драйвер. А речь о user mode.
     
  4. Flasher

    Flasher Member

    Публикаций:
    0
    Регистрация:
    31 янв 2004
    Сообщения:
    640
    Для перехвата sysenter хукаем KiFastSystemCall.
    Для перехвата int2e из юзермода никак вроди.
     
  5. mwizard

    mwizard New Member

    Публикаций:
    0
    Регистрация:
    13 апр 2009
    Сообщения:
    13
    <irony>Тогда уже для int 2e хукаем KiIntSystemCall.</irony>

    Это всё немного не то, KiFastSystemCall внутри выглядит просто: mov edx, esp и sysenter. Следовательно, хук будет не на sysenter, на лишь на том, что его вызывает. Никто не мешает приложениям аля Skype вызывать sysenter напрямую, не прибегая к вызову KiFastSystemCall.

    В общем, рабочим вариантом остается загрузка образа в память средствами ОСи, дизассемблирование кода до ближайшего call, jmp, jnz и прочего и установка на них hardware breakpoints, если есть права, либо int 3, если прав нет (только сохранить где-то заменяемую инструкцию, естественно). И так пока дизассемблер не найдет syscall.
     
  6. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Приложения не используют быстрый вызов, ибо в отличае от вызова сервиса через 0x2e прерывание, возврат из сервиса, вызванного инструкцией Sysenter происходит не на инструкцию следующую за ней, а на адрес определённый в разделяемой памяти(это не касается XPSP1). Это KiFastSystemCallRet. Недостаток один - не известен номер сервиса по возврату. Поэтому никто кроме MsRem'а это не юзает наверно.
     
  7. mwizard

    mwizard New Member

    Публикаций:
    0
    Регистрация:
    13 апр 2009
    Сообщения:
    13
    Вы абсолютно правы, нужно лишь учитывать, что KiFastSystemCallRet на самом деле представляет из себя только одну инструкцию - retn, и нужен он в первую очередь для того, чтобы "вернуться" из call dword ptr [edx], из которых состоят большинство Nt* функций в ntdll. Поэтому sysenter легко вызывается минуя KiFastSystemCall кодом вида

    Код (Text):
    1. mySysCall proc
    2. sysenter ; мы попадаем в KiFastSystemCallRet, но стек не изменяется
    3. mySysCall endp
    4.  
    5. KiFastSystemCallRet proc
    6. ret ; из стека выдавливается адрес, по которому находится "jmp somewhere" и происходит прыжок туда
    7. KiFastSystemCallRet endp
    8.  
    9. push 1234h ; передаем какие-то параметры обработчику syscall-ов.
    10. push 0ABCDh
    11. call mySysCall ; в стек заносится eip следующего за этой инструкцией jmp.
    12. jmp somewhere
    Вот, чем не вызов syscall из кода приложения? Можно обойтись даже без mySysCall, просто добавляя в стек адрес, куда мы хотим вернуться после выхода.

    Я допускаю, что что-то понимаю неверно.

    А кто/что такое MsRem?
     
  8. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    mwizard
    Во первых какой есчо сискалл, у меня процессор эту инструкцию не поддерживает. Её атлоны юзают.
    Во вторых код какойто бред. Обработчик инструкции Sysenter требует в регистре Edx указатель на параметры находящиеся в стеке уменьшенный на 2*4. Сам регистр Esp при вызове сервиса не используется и не имеет значения. По возврату ядро загружает в регистр Esp значение, которое было в регистре Edx перед вызовом сервиса. Соответственно этой модели и должен быть оформлен вызов.
     
  9. mwizard

    mwizard New Member

    Публикаций:
    0
    Регистрация:
    13 апр 2009
    Сообщения:
    13
    бред - понял, исправлюсь :)

    Но тем не менее это не отрицает возможности использования sysenter вне KiFastSystemCall, верно?
     
  10. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Прав. Вот именно поэтому бесполезно пытаться отловить из юзермода вызов сервиса гдето внутри приложения. Это нужно в ядре делать.
     
  11. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Вот код кстати для перехвата KiFastSystemCall в текущем процессе:
    Код (Text):
    1. UsSharedData    equ 7FFE0000h
    2. UsSystemCall    equ 7FFE0300h
    3.  
    4. UsNtMajorVersion equ 0026Ch
    5. UsNtMinorVersion equ 00270h
    6.  
    7. OS_VERSION_ID_2000  equ 0
    8. OS_VERSION_ID_XP    equ 1
    9. OS_VERSION_ID_2003  equ 2
    10. OS_VERSION_ID_VISTA equ 3
    11. OS_VERSION_ID_7 equ 4
    12.  
    13. $NtProtectVirtualMemory macro
    14.     mov eax,ServiceId
    15.     mov edx,esp
    16.     Int 2Eh
    17.     lea esp,[esp + 5*4]
    18. endm
    19.  
    20. ;В случае успеха EFlags.ZF = 1.
    21. GET_VERSION_ID macro
    22.     mov ecx,dword ptr ds:[UsSharedData + UsNtMajorVersion]
    23.     mov edx,dword ptr ds:[UsSharedData + UsNtMinorVersion]
    24.     cmp ecx,5
    25.     je v_5_x_
    26.     cmp ecx,6
    27.     jne err_ver_
    28. ;6.X
    29.     test edx,edx
    30.     mov eax,OS_VERSION_ID_VISTA
    31.     jz end_ver_ ;6.0
    32.     dec edx
    33.     inc eax     ;OS_VERSION_ID_7
    34.     jz end_ver_ ;6.1
    35.     jmp err_ver_
    36. v_5_x_:
    37.     xor eax,eax ;OS_VERSION_ID_2000
    38.     test edx,edx
    39.     jz end_ver_ ;5.0
    40.     inc eax     ;OS_VERSION_ID_XP
    41.     dec edx
    42.     jz end_ver_ ;5.1
    43.     inc eax     ;OS_VERSION_ID_2003
    44.     dec edx
    45.     jz end_ver_
    46. err_ver_:
    47.     mov eax,STATUS_NOT_IMPLEMENTED
    48. end_ver_:
    49. endm
    50.  
    51. .code
    52. comment '
    53. KiFastSystemCall:
    54.     mov edx,esp ;-> jmp short ptr call_ref_
    55.     sysenter
    56.     [x nop]
    57. KiFastSystemCallRet:
    58.     ret     ;-> nop
    59.     [jmp KiFastSystemCallRetHandler]        ;x5
    60. call_ref_:
    61.     jmp KiFastSystemCallHandler ;x5 (KiFastSystemCallRet + 6)
    62.     '
    63. IcpRedirectionUsSystemCall proc uses ebx esi edi Dispatcher:PVOID
    64. Local OldProtect:ULONG
    65. Local ProtectAddress:PVOID
    66. Local ProtectSize:ULONG
    67. Local ServiceId:ULONG
    68.     GET_VERSION_ID
    69.     jnz exit_
    70.     Call dt_
    71. dt_:
    72.     pop edx
    73.     movzx edx,byte ptr [edx + eax + (offset ServiceTable - offset dt_)]
    74.     assume fs:nothing
    75.     mov eax,fs:[TEB.Peb]
    76.     mov ServiceId,edx
    77.     mov eax,PEB.Ldr[eax]
    78.     mov eax,PEB_LDR_DATA.InLoadOrderModuleList.Flink[eax]
    79.     mov eax,LDR_DATA_TABLE_ENTRY.InLoadOrderModuleList.Flink[eax]   ;ntdll.dll
    80.     mov esi,ds:[UsSystemCall]   ;KiFastSystemCall
    81.     mov edi,ds:[UsSystemCall + 4]   ;KiFastSystemCallRet
    82.     mov ecx,LDR_DATA_TABLE_ENTRY.DllBase[eax]
    83.     mov edx,LDR_DATA_TABLE_ENTRY.SizeOfImage[eax]
    84.     cmp esi,ecx
    85.     jb not_imp_
    86.     cmp edi,ecx
    87.     jb not_imp_
    88.     add ecx,edx
    89.     cmp esi,ecx
    90.     ja not_imp_
    91.     cmp edi,ecx
    92.     ja not_imp_
    93.     cmp byte ptr [edi],0C3h ;ret
    94.     jne err_stub_
    95.     cmp dword ptr [esi],340FD48Bh   ;mov edx,esp/sysenter
    96.     mov ebx,edi
    97.     jne err_stub_
    98.     sub ebx,esi
    99.     jbe err_stub_
    100.     cmp ebx,4
    101.     jb err_stub_
    102.     cmp ebx,32
    103.     ja err_stub_
    104.     add ebx,4
    105.     add edi,6
    106.    
    107.     mov ProtectSize,ebx
    108.     mov ProtectAddress,esi
    109.  
    110.     lea eax,OldProtect
    111.     lea ecx,ProtectSize
    112.     lea edx,ProtectAddress
    113.     push eax
    114.     push PAGE_EXECUTE_READWRITE
    115.     push ecx
    116.     push edx
    117.     push NtCurrentProcess
    118.     $NtProtectVirtualMemory
    119.     test eax,eax
    120.     mov edx,Dispatcher
    121.     jnz exit_
    122.    
    123.     sub edx,edi
    124.     sub edx,5
    125.     mov dword ptr [edi + 1],edx
    126.    
    127.     mov byte ptr [edi],0E9h ;Jmp Handler
    128.    
    129.     mov bh,0EBh
    130.     xchg bl,bh
    131.    
    132.     lock xchg word ptr [esi],bx
    133.    
    134.     lea eax,OldProtect
    135.     lea ecx,ProtectSize
    136.     lea edx,ProtectAddress
    137.     push eax
    138.     push PAGE_EXECUTE_READWRITE
    139.     push ecx
    140.     push edx
    141.     push NtCurrentProcess
    142.     $NtProtectVirtualMemory
    143. exit_:
    144.     ret
    145. not_imp_:
    146.     mov eax,STATUS_NOT_IMPLEMENTED
    147.     jmp exit_
    148. err_stub_:
    149.     mov eax,STATUS_UNSUCCESSFUL
    150.     jmp exit_
    151. ServiceTable:
    152.     BYTE 077h
    153.     BYTE 089h
    154.     BYTE 08Fh
    155.     BYTE 0D2h
    156.     BYTE 0D8h
    157. IcpRedirectionUsSystemCall endp
    И бинарник:
    Код (Text):
    1. PiEntry:
    2. db 055h, 08Bh, 0ECh, 083h, 0C4h, 0F0h, 053h, 056h, 057h, 08Bh
    3. db 00Dh, 06Ch, 002h, 0FEh, 07Fh, 08Bh, 015h, 070h, 002h, 0FEh
    4. db 07Fh, 083h, 0F9h, 005h, 074h, 014h, 083h, 0F9h, 006h, 075h
    5. db 01Dh, 085h, 0D2h, 0B8h, 003h, 000h, 000h, 000h, 074h, 019h
    6. db 04Ah, 040h, 074h, 015h, 0EBh, 00Eh, 033h, 0C0h, 085h, 0D2h
    7. db 074h, 00Dh, 040h, 04Ah, 074h, 009h, 040h, 04Ah, 074h, 005h
    8. db 0B8h, 002h, 000h, 000h, 0C0h, 00Fh, 085h, 0D0h, 000h, 000h
    9. db 000h, 0E8h, 000h, 000h, 000h, 000h, 05Ah, 00Fh, 0B6h, 094h
    10. db 010h, 0E0h, 000h, 000h, 000h, 064h, 0A1h, 030h, 000h, 000h
    11. db 000h, 089h, 055h, 0F0h, 08Bh, 040h, 00Ch, 08Bh, 040h, 00Ch
    12. db 08Bh, 000h, 08Bh, 035h, 000h, 003h, 0FEh, 07Fh, 08Bh, 03Dh
    13. db 004h, 003h, 0FEh, 07Fh, 08Bh, 048h, 018h, 08Bh, 050h, 020h
    14. db 03Bh, 0F1h, 00Fh, 082h, 09Eh, 000h, 000h, 000h, 03Bh, 0F9h
    15. db 00Fh, 082h, 096h, 000h, 000h, 000h, 003h, 0CAh, 03Bh, 0F1h
    16. db 00Fh, 087h, 08Ch, 000h, 000h, 000h, 03Bh, 0F9h, 00Fh, 087h
    17. db 084h, 000h, 000h, 000h, 080h, 03Fh, 0C3h, 00Fh, 085h, 082h
    18. db 000h, 000h, 000h, 081h, 03Eh, 08Bh, 0D4h, 00Fh, 034h, 08Bh
    19. db 0DFh, 075h, 078h, 02Bh, 0DEh, 076h, 074h, 083h, 0FBh, 004h
    20. db 072h, 06Fh, 083h, 0FBh, 020h, 077h, 06Ah, 083h, 0C3h, 004h
    21. db 083h, 0C7h, 006h, 089h, 05Dh, 0F4h, 089h, 075h, 0F8h, 08Dh
    22. db 045h, 0FCh, 08Dh, 04Dh, 0F4h, 08Dh, 055h, 0F8h, 050h, 06Ah
    23. db 040h, 051h, 052h, 06Ah, 0FFh, 08Bh, 045h, 0F0h, 08Bh, 0D4h
    24. db 0CDh, 02Eh, 08Dh, 064h, 024h, 014h, 085h, 0C0h, 08Bh, 055h
    25. db 008h, 075h, 02Eh, 02Bh, 0D7h, 083h, 0EAh, 005h, 089h, 057h
    26. db 001h, 0C6h, 007h, 0E9h, 0B7h, 0EBh, 086h, 0DFh, 0F0h, 066h
    27. db 087h, 01Eh, 08Dh, 045h, 0FCh, 08Dh, 04Dh, 0F4h, 08Dh, 055h
    28. db 0F8h, 050h, 06Ah, 040h, 051h, 052h, 06Ah, 0FFh, 08Bh, 045h
    29. db 0F0h, 08Bh, 0D4h, 0CDh, 02Eh, 08Dh, 064h, 024h, 014h, 05Fh
    30. db 05Eh, 05Bh, 0C9h, 0C2h, 004h, 000h, 0B8h, 002h, 000h, 000h
    31. db 0C0h, 0EBh, 0F2h, 0B8h, 001h, 000h, 000h, 0C0h, 0EBh, 0EBh
    32. db 077h, 089h, 08Fh, 0D2h, 0D8h
     
  12. Flasher

    Flasher Member

    Публикаций:
    0
    Регистрация:
    31 янв 2004
    Сообщения:
    640
    Код (Text):
    1. KiFastSystemCallRetHandler proc C
    2.     test eax,eax
    3.     jnz _return
    4.     mov edx,dword ptr [esp]
    5.     mov edx,dword ptr [edx-0Bh]
    6.  
    7. ;в edx номер сервиса
    8.  
    9. _return:
    10.     ret
    11. KiFastSystemCallRetHandler endp
    Clerk, Ты же сам когда-то помогал высчитывать смешение по номеру сервиса.. :)
     
  13. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Flasher
    Это ведь для системного стуба. В произвольном коде не известно откуда и что было загружено в Eax.
     
  14. Flasher

    Flasher Member

    Публикаций:
    0
    Регистрация:
    31 янв 2004
    Сообщения:
    640
    Понятно.
    Но всёже тема крайне интересна..