Sysenter & EFlags.DF

Тема в разделе "WASM.ZEN", создана пользователем Clerk, 2 янв 2009.

  1. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Сбрасывает ли инструкция Sysenter этот флажёк ?
    Смотрел в манах на амд, про него ничего нет(у меня P4). Сказано что изменяет VM, IF, RF.
     
  2. Freeman

    Freeman New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2005
    Сообщения:
    1.385
    Адрес:
    Ukraine
    в интел манах тож тока VM, IF, RF устанавливает в 0
     
  3. Clerk

    Clerk Забанен

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

    Freeman New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2005
    Сообщения:
    1.385
    Адрес:
    Ukraine
    огаога. сбросело
     
  5. Clerk

    Clerk Забанен

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

    Freeman New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2005
    Сообщения:
    1.385
    Адрес:
    Ukraine
    пень Д
     
  7. Clerk

    Clerk Забанен

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

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Freeman
    Остаётся надеятсо что существует баговая комбинация eflags/eip при которой значение этого флажка не определено(чтоб проскачить в KiFastCallEntry с взведённым df, остальные входы сбрасывают), как вариант возможно для сискалл пройдёт, хотя врятле, мелкомягкие походу знали это, да и потестить негде, попробую сбрутфорсить, может чего и получится, но я уже почемуто даже не надеюсь..
     
  9. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Виндбг дебажит недостоверно такие вещи, поэтому на его результаты я бы полагаться не стал. Он сам мог сбросить DF даже если он был и установлен.
    Например, fs он всегда перезагружает в 0x30 в ядре во время пошагового трейса, код вида
    Код (Text):
    1.   mov ax, ds
    2.   mov fs, ax
    3.   mov eax, [fs:0xffdff124]
    4.   mov cx, 0x30
    5.   mov fs, cx
    не будет исполнен корректно, поскольку сразу после инструкции mov fs, ax когда fs получит значение 0x23, ядерная часть отладчика сбросит fs в 0x30 обратно и код не выполнится.
    Такие куски кода приходится пропускать, ставя бряк после того, как сегментному регистру вернут первоначальное значение.
    Подозреваю, что так же может быть и с DF при переходе в ядро.
     
  10. Freeman

    Freeman New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2005
    Сообщения:
    1.385
    Адрес:
    Ukraine
    проверь в своем отладчеке :)))
     
  11. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Всё верно в манах, если там чтото не огаворено, значит не юзаетсо. Чтоб проверить похучил:
    Код (Text):
    1. KGDT_R3_DATA equ 00020H
    2. KGDT_R3_CODE equ 00018H
    3. KGDT_R0_DATA equ 00010H
    4. KGDT_R0_CODE equ 00008H
    5. KGDT_R0_PCR equ 00030H
    6. KGDT_R3_TEB equ 00038H
    7.  
    8. RPL_MASK equ 00003H
    9.  
    10. sysenter macro
    11.     BYTE 0Fh
    12.     BYTE 34h
    13. endm
    14.  
    15. sysexit macro
    16.     BYTE 0Fh
    17.     BYTE 35h
    18. endm
    19.  
    20. GET_POINTER macro Reg32, Offset_
    21. Local l1
    22.     Call l1
    23. l1:
    24.     pop Reg32
    25.     lea Reg32,[Reg32 + (Offset_ - offset l1)]
    26. endm
    27.  
    28. MSR_SYSENTER_CS     equ 174h
    29. MSR_SYSENTER_ESP        equ 175h
    30. MSR_SYSENTER_EIP        equ 176h
    31.  
    32. EFLAGS_TF       equ 0000000000000100000000b ;Trap Flag  (Single Step)
    33. EFLAGS_DF       equ 0000000000010000000000b ;Direction Flag
    34.  
    35. USER_SHARED_DATA_BASE   equ 0FFDF0000h
    36.  
    37. ENTRY_DATA struct
    38. ExFreePoolEntry PVOID ?
    39. Pool                PVOID ?
    40. ENTRY_DATA ends
    41. PENTRY_DATA typedef ptr ENTRY_DATA
    42.  
    43. STACK_CODE_SIZE equ ((offset check_ - offset shell_ + 3) and (not(3)))
    44.  
    45. ;***************************
    46. ;* WARNING: BSOD IF TF = 1 *
    47. ;***************************
    48.  
    49. iKiFastCallEntry proc C
    50.     pushfd
    51.     mov ecx,KGDT_R3_DATA or RPL_MASK
    52.     mov ds,cx
    53.     mov es,cx
    54.     inc dword ptr ds:[USER_SHARED_DATA_BASE + PAGE_SIZE - 2*4]  ;Fast system calls 
    55.     test eax,eax   
    56.     jns dispatch_
    57.     pop dword ptr ds:[USER_SHARED_DATA_BASE + PAGE_SIZE - 3*4]  ;Entry eflags
    58.     cmp eax,-1
    59.     je check_
    60.     cmp eax,-2
    61.     push KGDT_R0_PCR
    62.     mov ecx,STACK_CODE_SIZE / 4
    63.     pop fs
    64.     sub esp,STACK_CODE_SIZE
    65.     push edx    ;-> Esp
    66.     push esi
    67.     push edi
    68.     cld
    69.     GET_POINTER Esi, offset shell_
    70.     lea edi,[esp + 3*4]
    71.     mov eax,dword ptr ds:[USER_SHARED_DATA_BASE + PAGE_SIZE - 4]    ;Original entry.
    72.     rep movsd
    73.     mov ecx,MSR_SYSENTER_EIP
    74.     xor edx,edx
    75.     pop edi
    76.     pop esi
    77.     wrmsr
    78.     GET_POINTER Edx, offset EntryData
    79.     lea eax,[esp + 4]
    80. ;   pushfd  ;Save DF
    81.     push ENTRY_DATA.Pool[edx]
    82.     mov edx,ENTRY_DATA.ExFreePoolEntry[edx]
    83.     cld
    84.     jmp eax
    85. dispatch_:
    86.     lea esp,[esp + 4]
    87.     jmp dword ptr ds:[USER_SHARED_DATA_BASE + PAGE_SIZE - 4]    ;Original entry.       
    88. shell_:
    89.     Call Edx    ;ExFreePool
    90. ;   popfd   ;Restore DF
    91.     sti
    92.     pop ecx ;-> Esp
    93.     mov edx,dword ptr ds:[USER_SHARED_DATA_BASE + 304h] ;UsSystemCallRet -> ntdll!KiFastSystemCallRet
    94.     push KGDT_R3_TEB or RPL_MASK
    95.     pop fs
    96.     sysexit ;Eax = (DF)
    97. check_:
    98.     sti
    99.     inc dword ptr ds:[USER_SHARED_DATA_BASE + PAGE_SIZE - 4*4]  ;Fast system calls for check
    100.     pushfd
    101.     test dword ptr [esp],EFLAGS_DF
    102.     setnz al
    103.     lea esp,[esp + 4]   ;Remove eflags.
    104.     movzx eax,al        ;(DF)
    105.     mov dword ptr ds:[USER_SHARED_DATA_BASE + PAGE_SIZE - 5*4],eax  ;DF
    106.     mov ecx,edx ;-> Esp
    107.     mov edx,dword ptr ds:[USER_SHARED_DATA_BASE + 304h] ;UsSystemCallRet -> ntdll!KiFastSystemCallRet
    108.     sysexit ;Eax = (DF)
    109. iKiFastCallEntry endp
    110.  
    111. EntryData   ENTRY_DATA <>
    112.  
    113. ENTRY_OFFSET equ (offset EntryData - offset iKiFastCallEntry)
    114.  
    115. POOL_SIZE   equ ((offset EntryData - offset iKiFastCallEntry + sizeof ENTRY_DATA + 3) and (not(3)))
    116.  
    117. iKiLoadFastSyscall proc uses esi edi
    118. ;Only first processor.
    119. ;Default in MSR_SYSENTER_ESP
    120. ;Default in MSR_SYSENTER_CS(KGDT_R0_CODE)
    121.     invoke KeSetSystemAffinityThread, 1
    122.     invoke ExAllocatePool, NonPagedPool, POOL_SIZE
    123.     .if Eax
    124.     push eax
    125.     lea esi,iKiFastCallEntry
    126.     mov edi,eax
    127.     mov ecx,POOL_SIZE / 4
    128.     cld
    129.     mov edx,dword ptr [ExFreePool + 2]
    130.     rep movsd
    131.     mov edx,dword ptr [edx]
    132.     mov ENTRY_DATA.Pool[eax + ENTRY_OFFSET],eax
    133.     mov ENTRY_DATA.ExFreePoolEntry[eax + ENTRY_OFFSET],edx
    134.     cli
    135.     mov ecx,MSR_SYSENTER_EIP
    136.     rdmsr
    137.     xchg dword ptr [esp],eax
    138.     xor edx,edx
    139.     wrmsr
    140.     sti
    141.     xor eax,eax
    142.     pop dword ptr ds:[USER_SHARED_DATA_BASE + PAGE_SIZE - 4]        ;Previous entry.
    143.     mov dword ptr ds:[USER_SHARED_DATA_BASE + PAGE_SIZE - 2*4],eax  ;Fast system calls
    144.     mov dword ptr ds:[USER_SHARED_DATA_BASE + PAGE_SIZE - 3*4],eax  ;Entry eflags
    145.     mov dword ptr ds:[USER_SHARED_DATA_BASE + PAGE_SIZE - 4*4],eax  ;Fast system calls for check
    146.     mov dword ptr ds:[USER_SHARED_DATA_BASE + PAGE_SIZE - 5*4],eax  ;DF
    147.     .endif
    148.     push eax
    149.     invoke KeRevertToUserAffinityThread
    150.     pop eax
    151.     ret
    152. iKiLoadFastSyscall endp
    Получилось вобщем как и ожидал результат, не сбрасываются все остальные флажки, про которые не сказано в манах:
    [​IMG]
    В частности не сбрасывается DF, но он сбрасывается в диспетчере, не инструкцией cld, а через popfd, я этого не заметил. Также не сбрасывается TF, при исполнении sysenter c взведённым TF вызывается диспетчер исключений, который чекает ип, если это KiFastCallEntry, то сбрасывает TF и продолжает исполнять диспетчер сервиса, ибо быстрый вызов не использует стек, моё ИМХО эта инструкция большая ошибка, которую совершила эта контора, в случае трассировки она не ускоряет вызов, а очень сильно его замедляет, гораздо дольше чем через Int.
     
  12. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Кстати никогда не обращал внимания, rdmsr взводит RF.
     
  13. nester7

    nester7 New Member

    Публикаций:
    0
    Регистрация:
    5 дек 2003
    Сообщения:
    720
    Адрес:
    Russia
    Мой браузер и IDE (да и остальной повседневный софт) постоянно юзает sysenter с взведенным TF, огга :)

    Если в процессе идет трассировка через TF, то там уже, по определению, всё жутко тормозит, будь-то трассировка
    через DebugApi или через in-process SEH/VEH. Так что... на эту "большую ошибку этой конторы" можно и не обращать внимания.

    Конечно же, имхо :)
     
  14. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    nester7
    Функционал дебугапи предоставлен только для одной цели - сообщить потоку его юзоющего об событии в отлаживаемом потоке, в частности фильтрация исключений, но это никак не связано с пошаговой отладкой. В данном топике разбираетсо низкоуровневый механизм предоставляемый процессором и не с каким функционалом столь высокого уровня не связан. Изначально этот топик продолжение темы на VT, Гордон в курсе, предпологалось что системный вход имеет две уязвимости, одна связана с селекторами, вторая считалось с пропуском DF. Как оказалось DF сбрасывается програмно. Механизм работы sysenter слишком кривой. Данная инструкция не сохраняет флажки, Cs, Ss. Поэтому он и неполноценный мягко сказано. Так как флажки не сохраняются, TF не сбрасываетсо при смене кольца и возникает отладочное исключение, обойти это невозможно. Ось это исключение обрабатывает, тратя на это сотни инструкций, против единственной Int, которая сбрасывает флажки. Если трассировка не используется это весьма эффективно, так как нет тех обращений к памяти и проверок что имеются при исполнении Int, поэтому и быстрый вызов. Но при трассировке переход в ядро, в реальном ядре на KiFastCallEntry занимает в десятки раз больше времени, чем посредством Int. Само собой разумеется что с учётом планирования ты это не заметишь, темболее скорее всего что ты понимаешь под трассировкой уставновку точки останова после каждой инструкции, даже не затрагивая пошаговую отладку(TF). Использование структурных обработчиков исключений(ты имел ввиду юзермод) также тут не причём. Что понимать под трассировщиком - это не тот механизм, что использует юзермодные калбаки. Имеется ввиду трассировка, есполняемая на самом низком уровне, тоесть в IDT перехвачен шлюз и диспетчер при каждом подобном исключении взводит повторно TF, продолжая пошаговую отладку. Юзермодный же механизм требует в сотни раз больше времени на исполнение.
    На эту большую ошибку конторы не обратит внимания только тот, кто с этим не сталкнулся, а смотрит со стороны не понимая сути.)
     
  15. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    И есчо. Касательно этого:
    Код (Text):
    1. ;***************************
    2. ;* WARNING: BSOD IF TF = 1 *
    3. ;***************************
    Ось выносится изза необработанного отладочного исключения, но его так просто не словить. Диспетчер #DB при исполнении Sysenter с взведённым TF получает управление. Вот этот код:
    Код (Text):
    1. 00407C3E _KiTrap01                                        push 0
    2. 00407C40                                                  mov word ptr ss:[esp+2],0
    3. 00407C47                                                  push ebp
    4. 00407C48                                                  push ebx
    5. 00407C49                                                  push esi
    6. 00407C4A                                                  push edi
    7. 00407C4B                                                  push fs
    8. 00407C4D                                                  mov ebx,30
    9. 00407C52                                                  mov fs,bx                                                    ;  Modification of segment register
    10. 00407C55                                                  mov ebx,dword ptr fs:[0]
    11. 00407C5C                                                  push ebx
    12. 00407C5D                                                  sub esp,4
    13. 00407C60                                                  push eax
    14. 00407C61                                                  push ecx
    15. 00407C62                                                  push edx
    16. 00407C63                                                  push ds
    17. 00407C64                                                  push es
    18. 00407C65                                                  push gs
    19. 00407C67                                                  mov ax,23
    20. 00407C6B                                                  sub esp,30
    21. 00407C6E                                                  mov ds,ax                                                    ;  Modification of segment register
    22. 00407C71                                                  mov es,ax                                                    ;  Modification of segment register
    23. 00407C74                                                  mov ebp,esp
    24. 00407C76                                                  test dword ptr ss:[esp+70],20000
    25. 00407C7E                                                  jnz short ntoskrnl.V86_kit1_a
    26. 00407C80                                                  cld
    27. 00407C81                                                  mov ebx,dword ptr ss:[ebp+60]
    28. 00407C84                                                  mov edi,dword ptr ss:[ebp+68]
    29. 00407C87                                                  mov dword ptr ss:[ebp+C],edx
    30. 00407C8A                                                  mov dword ptr ss:[ebp+8],BADB0D00
    31. 00407C91                                                  mov dword ptr ss:[ebp],ebx
    32. 00407C94                                                  mov dword ptr ss:[ebp+4],edi
    33. 00407C97                                                  test byte ptr fs:[50],0FF
    34. 00407C9F                                                  jnz ntoskrnl.Dr_kit1_a
    35. 00407CA5                                                  cmp dword ptr fs:[54],0
    36. 00407CAD                                                  jnz short ntoskrnl.00407D10
    37. 00407CAF                                                  mov ecx,dword ptr ss:[ebp+68]
    38. 00407CB2                                                  cmp ecx,ntoskrnl._KiFastCallEntry
    39. 00407CB8                                                  je ntoskrnl.00407B7D
    Видно что ип сравнивается с адресом шлюза, если исключение на нём возникло, юзоется следующий код:
    Код (Text):
    1. 00407B7D                                                  mov dword ptr ss:[ebp+68],ntoskrnl._KiFastCallEntry2
    2. 00407B84                                                  and byte ptr ss:[ebp+71],0FE
    3. 00407B88                                                  jmp ntoskrnl.Kei386EoiHelper
    Тоесть состояние потока восстанавливается каким было на момент возникновения трассировочного исключения и передаётся на второй шлюз KiFastCallEntry2(что и юзоет амд через Syscall). На это много времени нужно. И что самое главное если подменён адрес шлюза в мср, то возврат не исполняется, ибо адрес отличен от KiFastCallEntry, а чтобы это словить нужно поставить свой диспетчер исключений. Это в простейшем случае делоется через перехват второго шлюза в IDT, либо регистрацией диспетчера в KiDebugRoutine. Ни то ни другое для подобного тестового кода не нужно, темболее что второй вариант вызовет коллизии с уже зарегистрированным диспетчером, который принадлежит ядерному отладчику(в моём случае это баговый сисер).
    Теперь ты должен уже понять сколь много времени займёт трассировка Sysenter.
    [Да и вообще, кто сможет продебажить например MessageBox() в юзермоде так чтоб независло, тогда и разговор будет. Закрыто.]
     
  16. nester7

    nester7 New Member

    Публикаций:
    0
    Регистрация:
    5 дек 2003
    Сообщения:
    720
    Адрес:
    Russia
    Так, давай еще раз и по порядку :)

    1. Я понимаю, что при sysenter + TF нужно программно обработать то, что int делала аппаратно,
    и это делает sysenter (в данном случае) далеко не fast call.
    2. В повседневном софте это накуй никому не нужно и sysenter там fast, а значит, говорить, что это ппц какая ошибка - очень натянуто,
    что, собсно, я и хотел сказать, не более.
    3. Механизм-мезанизм... Сам ты обрабатываешь, похучив IDT, иль ядро это делает (с последующим вызовом UM callback'ов) - в любом случае это
    томоза, разница в цифрах, и только. Собсно, не о том речь.
    4. Я очень рад, что книги, вроде "врутреннего устройства Windows" писались не тобой - там бы на каждый пук был бы метровый листинг из ольгиного
    дизасма, с кучей околотемной информации, сдобреной олпанским изыком и расплытым смыслом.
    5. [Открыто. Не стоит таким образом затыкать рот. Не достойны разговора с тобой? Ну, не отвечай тогда, это же форум :) ]

    Кстати, VT - это что/где?
     
  17. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Clerk
    Можно фильтровать падонкафский сленг пожалуйста? Очень напрягает. И, думаю, не меня одного
     
  18. nester7

    nester7 New Member

    Публикаций:
    0
    Регистрация:
    5 дек 2003
    Сообщения:
    720
    Адрес:
    Russia
    Очень напрягает. И, думаю, не меня одного
    Как минимум, двух :)

    Для Clerk'а, в силу его хороших технических знаний (и способностей?), это игнорируется.
    Стал бы его кто-нибудь терпеть, если бы он вещал в бегинерсах с вопросами
    про массивы и указатели? :) Врят ли. Но напрягает просто ппц - я тупо копирую его
    пост в редактор и там по предложениям разбираю, пытаясь связать мысли автора
    в его предложениях и уловить смысл :dntknw:
     
  19. Freeman

    Freeman New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2005
    Сообщения:
    1.385
    Адрес:
    Ukraine
    хм. а я нормально так читаю :) в силу того что сам предпочитаю сей деолект. тут как и везде главное практека. но пожалуй это не тема топика.
    форум http://virustech.org/f
     
  20. nester7

    nester7 New Member

    Публикаций:
    0
    Регистрация:
    5 дек 2003
    Сообщения:
    720
    Адрес:
    Russia
    Freeman
    Спасибо. А я-то не мог отделаться от мысли о VTune :)

    У анимешников (иль как эт слово нужно писать? ) тоже есть свой сленг, у админов - свой,
    у электриков - , у автомастеров - , у... ицетера.
    Постоянно это использовать - неуважение. Просто потому, что другим это сложно читать,
    а главное - понимать - что раньше было просто словосочетанием, теперь превращается в хyeтерацию,
    на которую нужно пару секунд залипнуть, чтобы понять о чем тут речь.

    Собсно, мне похеристически на это дело (меня не особо заломает в очередной раз это вставить в редактор),
    но было бы здорово, если бы этого было меньше на этом сайте вне хипа :)