Сейчас на форуме: UniSoft, _MBK_, laslo, bartolomeo (+6 невидимых)

 eXeL@B —› Программирование —› CPPEH_RECORD и исключения
Посл.ответ Сообщение


Ранг: 324.3 (мудрец), 222thx
Активность: 0.480.37
Статус: Участник

Создано: 29 июля 2011 07:20 · Поправил: DenCoder
· Личное сообщение · #1

Пробелы в механизмах обработки исключительных ситуаций раньше меня мало волновали. Достаточно было перехватить обработчики... Но недавно решил покопать NtFlushInstructionCache и увидел такой код

Code:
  1. 80587C67                                   loc_80587C67:           ; CODE XREF: 80587C78 j
  2. 80587C67 05C 89 5D E0                      mov     [ebp+var_20], ebx
  3. 80587C6A 05C C7 45 FC 01 00 00 00          mov     [ebp+ms_exc.disabled], 1
  4. 80587C71 05C 83 4D FC FF                   or      [ebp+ms_exc.disabled], 0FFFFFFF
  5.  
  6. 80587C75                                   loc_80587C75:           ; CODE XREF: 805FDC02 j
  7. 80587C75 05C 39 5D E0                      cmp     [ebp+var_20], ebx
  8. 80587C78 05C 75 ED                         jnz     short loc_80587C67


1) Локальная переменная ms_exc типа CPPEH_RECORD. Здесь ms_exc.disabled = 1, как я нашёл на васме, эквивалентно try{}. Но блок операторов пустой и следом же ms_exc.disabled = -1, что на великих просторах нигде не удалось найти, кроме как в листингах декомпиляции. Нашёл только, что ms_exc.disabled = -2 эквивалентно catch{}. Но опять же - непонятен механизм.

2) ms_exc почему-то всегда располагается в [ebp - 0x18]. Можно понять, что это связано с тем, что длина структуры sizeof(CPPEH_RECORD) = 0x18 и что механизм обработки исключений связан с расположением этой переменной в начале стека... но какой?

3) Ида больше знает об этой структуре, чем где-нибудь ещё. На сайте microsoft вообще почему-то о ней умалчивают... По крайней мере, запрос в лоб ничего не даёт.
Code:
  1. 00000000 CPPEH_RECORD    struc ; (sizeof=0x18, standard type)
  2. 00000000 old_esp         dd ?
  3. 00000004 exc_ptr         dd ?                    ; offset
  4. 00000008 prev_er         dd ?                    ; offset
  5. 0000000C handler         dd ?                    ; offset
  6. 00000010 msEH_ptr        dd ?                    ; offset
  7. 00000014 disabled        dd ?
  8. 00000018 CPPEH_RECORD    ends


4) Вернёмся к коду выше. Этот кусок - главный смысл всей функции NtFlushInsructionCache. Как видно, цикл продолжается, пока [ebp - 0x20] не равно нулю. Но внутри цикла нет никаких операций над этой переменной... Есть только джамп в середину из обработчика.

Code:
  1. 805FDBF9                                   sub_805FDBF9 proc near  ; DATA XREF: 804F36AC o
  2. 805FDBF9 000 8B 65 E8                      mov     esp, [ebp-18h]; esp = old_esp
  3. 805FDBFC 000 83 4D FC FF                   or      dword ptr [ebp-4], 0FFFFFFFFh; ms_exc.disabled = -1
  4. 805FDC00 000 33 DB                         xor     ebx, ebx
  5. 805FDC02 000 E9 6E A0 F8 FF                jmp     loc_80587C75


Следовательно, одна из инструкций или вся последовательность
80587C6A 05C C7 45 FC 01 00 00 00 mov [ebp+ms_exc.disabled], 1
80587C71 05C 83 4D FC FF or [ebp+ms_exc.disabled], 0FFFFFFF
вызывает исключение.

5) Смотрим на ссылку o
Code:
  1. 804F3698 stru_804F3698   _msEH <0FFFFFFFFh, offset sub_805FDBB8, offset sub_805FDBCB>
  2. 804F3698                                                                     ; DATA XREF: 80587BFD o
  3. 804F36A4 _msEH <0FFFFFFFFh, offset loc_805FDBDF, offset sub_805FDBF9>

Знакомое дело - здесь 2 группы обработчиков. По-моему, в каждой первый - обработка самой исключительной ситуации, второй - завершающий, __finally{}.

Собственно, вот и главный кусок кода функции, расположенный в 1-ом обработчике, без которого функция работать не будет

Code:
  1. PAGE:805FDBDF                                   sub_805FDBDF proc near  ; DATA XREF: 804F36A4o
  2. PAGE:805FDBDF 000 8D 45 E0                      lea     eax, [ebp-20h]; та самая переменная в цикле
  3. PAGE:805FDBE2 000 50                            push    eax
  4. PAGE:805FDBE3 004 8D 45 D0                      lea     eax, [ebp-30h]; dwFlushSize
  5. PAGE:805FDBE6 004 50                            push    eax
  6. PAGE:805FDBE7 008 8D 45 CC                      lea     eax, [ebp-34h]; dwFlushAddress
  7. PAGE:805FDBEA 008 50                            push    eax
  8. PAGE:805FDBEB 00C FF 75 EC                      push    dword ptr [ebp-14h]; ms_exc.msEH_ptr
  9. PAGE:805FDBEE 010 E8 39 11 03 00                call    _MiFlushRangeFilter@16 ; MiFlushRangeFilter(x,x,x,x)
  10. PAGE:805FDBF3 000 C3                            retn
  11. PAGE:805FDBF3                                   sub_805FDBDF e


О том, как регистрируются обработчики, ещё более менее можно найти. Где можно почитать о ms_exc и как влияет на ход выполнения программы ms_exc.disabled = 1 и ms_exc.disabled = -1 ?

-----
IZ.RU




Ранг: 58.0 (постоянный), 13thx
Активность: 0.020.01
Статус: Участник

Создано: 29 июля 2011 13:47
· Личное сообщение · #2

https://www.openrce.org/articles/full_view/21
disabled == trylevel




Ранг: 324.3 (мудрец), 222thx
Активность: 0.480.37
Статус: Участник

Создано: 29 июля 2011 14:44 · Поправил: DenCoder
· Личное сообщение · #3

reverser, спасибо, чуть больше разобрался. Используется схема SEH3...

Что-то как-то я сам не догадался реверснуть главный хэндлер, там было бы понятно... Но остаётся только один вопрос:

Code:
  1. 80587C6A 05C C7 45 FC 01 00 00 00          mov     [ebp+ms_exc.disabled], 1
  2. 80587C71 05C 83 4D FC FF                   or      [ebp+ms_exc.disabled], 0FFFFFFF

здесь нет инструкций, вызывающих исключение... Эксперимента ради (меня и так уже сконфузили эти 2 команды ))) нашёл в блокноте такой же пролог для SEH3, поставил бряки на всех обработчиках, вставил эти 2 инструкции и... естественно ничего . Как тогда работает NtFlushInstructionCache? ))

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

Code:
  1. PAGE:80587BFB                                   ; NTSTATUS __stdcall NtFlushInstructionCache(HANDLE ProcessHandle, PVOID BaseAddress, ULONG FlushSize)
  2. PAGE:80587BFB                                   _NtFlushInstructionCache@12 proc near   ; DATA XREF: 804E49E8o
  3. PAGE:80587BFB
  4. PAGE:80587BFB                                   var_4C          = byte ptr -4Ch
  5. PAGE:80587BFB                                   dwFlushAddress  = dword ptr -34h
  6. PAGE:80587BFB                                   dwFlushSize     = dword ptr -30h
  7. PAGE:80587BFB                                   var_28          = byte ptr -28h
  8. PAGE:80587BFB                                   var_20          = dword ptr -20h
  9. PAGE:80587BFB                                   pProcess        = dword ptr -1Ch
  10. PAGE:80587BFB                                   ms_exc          = CPPEH_RECORD ptr -18h
  11. PAGE:80587BFB                                   ProcessHandle   = dword ptr  8
  12. PAGE:80587BFB                                   BaseAddress     = dword ptr  0Ch
  13. PAGE:80587BFB                                   FlushSize       = dword ptr  10h
  14. PAGE:80587BFB
  15. PAGE:80587BFB                                   ; FUNCTION CHUNK AT PAGE:805AA35F SIZE 00000020 BYTES
  16. PAGE:80587BFB
  17. PAGE:80587BFB 000 6A 3C                                         push    3Ch
  18. PAGE:80587BFD 004 68 98 36 4F 80                                push    offset stru_804F3698
  19. PAGE:80587C02 008 E8 7C B2 F5 FF                                call    __SEH_prolog
  20. PAGE:80587C07 05C 64 A1 24 01 00 00                             mov     eax, large fs:124h
  21. PAGE:80587C0D 05C 8A 80 40 01 00 00                             mov     al, [eax+140h]
  22. PAGE:80587C13 05C 88 45 D8                                      mov     [ebp+var_28], al
  23. PAGE:80587C16 05C 8B 75 0C                                      mov     esi, [ebp+BaseAddress]
  24. PAGE:80587C19 05C 33 DB                                         xor     ebx, ebx
  25. PAGE:80587C1B 05C 8B 7D 10                                      mov     edi, [ebp+FlushSize]
  26. PAGE:80587C1E 05C 3B F3                                         cmp     esi, ebx
  27. PAGE:80587C20 05C 74 2E                                         jz      short loc_80587C50
  28. PAGE:80587C22 05C 3B FB                                         cmp     edi, ebx
  29. PAGE:80587C24 05C 74 5D                                         jz      short loc_80587C83
  30. PAGE:80587C26 05C 3B F3                                         cmp     esi, ebx
  31. PAGE:80587C28 05C 74 26                                         jz      short loc_80587C50
  32. PAGE:80587C2A 05C 3A C3                                         cmp     al, bl
  33. PAGE:80587C2C 05C 74 22                                         jz      short loc_80587C50
  34. PAGE:80587C2E 05C 89 5D FC                                      mov     [ebp+ms_exc.disabled], ebx
  35. PAGE:80587C31 05C 3B FB                                         cmp     edi, ebx
  36. PAGE:80587C33 05C 74 17                                         jz      short loc_80587C4C
  37. PAGE:80587C35 05C 8D 04 3E                                      lea     eax, [esi+edi]
  38. PAGE:80587C38 05C 3B C6                                         cmp     eax, esi
  39. PAGE:80587C3A 05C 0F 82 35 27 02 00                             jb      loc_805AA375
  40. PAGE:80587C40 05C 3B 05 D4 7E 56 80                             cmp     eax, _MmUserProbeAddress
  41. PAGE:80587C46 05C 0F 87 29 27 02 00                             ja      loc_805AA375
  42. PAGE:80587C4C
  43. PAGE:80587C4C                                   loc_80587C4C:                           ; CODE XREF: 80587C33j
  44. PAGE:80587C4C                                                                           ; 805AA37Aj
  45. PAGE:80587C4C 05C 83 4D FC FF                                   or      [ebp+ms_exc.disabled], 0FFFFFFFFh
  46. PAGE:80587C50
  47. PAGE:80587C50                                   loc_80587C50:                           ; CODE XREF: 80587C20j
  48. PAGE:80587C50                                                                           ; 80587C28j
  49. PAGE:80587C50                                                                           ; 80587C2Cj
  50. PAGE:80587C50 05C 89 5D E4                                      mov     [ebp+pProcess], ebx
  51. PAGE:80587C53 05C 83 7D 08 FF                                   cmp     [ebp+ProcessHandle], 0FFFFFFFFh
  52. PAGE:80587C57 05C 0F 85 CD 26 02 00                             jnz     sub_805AA32A
  53. PAGE:80587C5D
  54. PAGE:80587C5D                                   loc_80587C5D:                           ; CODE XREF: 805AA35Aj
  55. PAGE:80587C5D 05C 3B F3                                         cmp     esi, ebx
  56. PAGE:80587C5F 05C 74 19                                         jz      short loc_80587C7A
  57. PAGE:80587C61 05C 89 75 CC                                      mov     [ebp+dwFlushAddress], esi
  58. PAGE:80587C64 05C 89 7D D0                                      mov     [ebp+dwFlushSize], edi
  59. PAGE:80587C67
  60. PAGE:80587C67                                   loc_80587C67:                           ; CODE XREF: 80587C78j
  61. PAGE:80587C67 05C 89 5D E0                                      mov     [ebp+var_20], ebx
  62. PAGE:80587C6A 05C C7 45 FC 01 00 00 00                          mov     [ebp+ms_exc.disabled], 1
  63. PAGE:80587C71 05C 83 4D FC FF                                   or      [ebp+ms_exc.disabled], 0FFFFFFFFh
  64. PAGE:80587C75
  65. PAGE:80587C75                                   loc_80587C75:                           ; CODE XREF: 805FDC02j
  66. PAGE:80587C75 05C 39 5D E0                                      cmp     [ebp+var_20], ebx
  67. PAGE:80587C78 05C 75 ED                                         jnz     short loc_80587C67
  68. PAGE:80587C7A
  69. PAGE:80587C7A                                   loc_80587C7A:                           ; CODE XREF: 80587C5Fj
  70. PAGE:80587C7A 05C 39 5D E4                                      cmp     [ebp+pProcess], ebx
  71. PAGE:80587C7D 05C 0F 85 DC 26 02 00                             jnz     loc_805AA35F
  72. PAGE:80587C83
  73. PAGE:80587C83                                   loc_80587C83:                           ; CODE XREF: 80587C24j
  74. PAGE:80587C83                                                                           ; 805AA370j
  75. PAGE:80587C83 05C 33 C0                                         xor     eax, eax
  76. PAGE:80587C85
  77. PAGE:80587C85                                   loc_80587C85:                           ; CODE XREF: 805AA34Aj
  78. PAGE:80587C85                                                                           ; 805FDBD5j
  79. PAGE:80587C85 05C E8 34 B2 F5 FF                                call    __SEH_epilog
  80. PAGE:80587C8A 000 C2 0C 00                                      retn    0Ch
  81. PAGE:80587C8A                                   _NtFlushInstructionCache@12 endp


Code:
  1. PAGE:805AA32A 000 53                                            push    ebx
  2. PAGE:805AA32B 004 8D 45 D4                                      lea     eax, [ebp-2Ch]
  3. PAGE:805AA32E 004 50                                            push    eax             ; Object
  4. PAGE:805AA32F 008 FF 75 D8                                      push    dword ptr [ebp-28h] ; AccessMode
  5. PAGE:805AA332 00C FF 35 58 97 56 80                             push    _PsProcessType  ; ObjectType
  6. PAGE:805AA338 010 6A 20                                         push    20h             ; DesiredAccess
  7. PAGE:805AA33A 014 FF 75 08                                      push    dword ptr [ebp+8] ; Handle
  8. PAGE:805AA33D 018 E8 17 22 FC FF                                call    _ObReferenceObjectByHandle@24 ; ObReferenceObjectByHandle(x,x,x,x,x,x)
  9. PAGE:805AA342 000 8B 4D D4                                      mov     ecx, [ebp-2Ch]
  10. PAGE:805AA345 000 89 4D E4                                      mov     [ebp-1Ch], ecx
  11. PAGE:805AA348 000 3B C3                                         cmp     eax, ebx
  12. PAGE:805AA34A 000 0F 8C 35 D9 FD FF                             jl      loc_80587C85
  13. PAGE:805AA350 000 8D 45 B4                                      lea     eax, [ebp-4Ch]
  14. PAGE:805AA353 000 50                                            push    eax
  15. PAGE:805AA354 004 51                                            push    ecx
  16. PAGE:805AA355 008 E8 4B 9C F4 FF                                call    _KeStackAttachProcess@8 ; KeStackAttachProcess(x,x)
  17. PAGE:805AA35A 000 E9 FE D8 FD FF                                jmp     loc_80587C5D


-----
IZ.RU





Ранг: 324.3 (мудрец), 222thx
Активность: 0.480.37
Статус: Участник

Создано: 29 июля 2011 14:46
· Личное сообщение · #4

Code:
  1. .text:804F3698 FF FF FF FF B8 DB 5F 80 CB DB+    stru_804F3698   _msEH <0FFFFFFFFh, offset sub_805FDBB8, offset sub_805FDBCB>
  2. .text:804F3698 5F 80                                                                     ; DATA XREF: 80587BFDo
  3. .text:804F36A4 FF FF FF FF DF DB 5F 80 F9 DB+                    _msEH <0FFFFFFFFh, offset sub_805FDBDF, offset sub_805FDBF9>


__except для TryLevel = 0
Code:
  1. PAGE:805FDBB8 000 8B 45 EC                                      mov     eax, [ebp-14h]
  2. PAGE:805FDBBB 000 8B 00                                         mov     eax, [eax]
  3. PAGE:805FDBBD 000 8B 00                                         mov     eax, [eax]
  4. PAGE:805FDBBF 000 89 45 DC                                      mov     [ebp-24h], eax
  5. PAGE:805FDBC2 000 33 C0                                         xor     eax, eax
  6. PAGE:805FDBC4 000 40                                            inc     eax
  7. PAGE:805FDBC5 000 C3                                            retn


__finally для TryLevel = 0

Code:
  1. PAGE:805FDBCB 000 8B 65 E8                                      mov     esp, [ebp-18h]
  2. PAGE:805FDBCE 000 83 4D FC FF                                   or      dword ptr [ebp-4], 0FFFFFFFFh
  3. PAGE:805FDBD2 000 8B 45 DC                                      mov     eax, [ebp-24h]
  4. PAGE:805FDBD5 000 E9 AB A0 F8 FF                                jmp     loc_80587C85


__except для TryLevel = 1
Code:
  1. PAGE:805FDBDF 000 8D 45 E0                                      lea     eax, [ebp-20h]
  2. PAGE:805FDBE2 000 50                                            push    eax
  3. PAGE:805FDBE3 004 8D 45 D0                                      lea     eax, [ebp-30h]
  4. PAGE:805FDBE6 004 50                                            push    eax
  5. PAGE:805FDBE7 008 8D 45 CC                                      lea     eax, [ebp-34h]
  6. PAGE:805FDBEA 008 50                                            push    eax
  7. PAGE:805FDBEB 00C FF 75 EC                                      push    dword ptr [ebp-14h]
  8. PAGE:805FDBEE 010 E8 39 11 03 00                                call    _MiFlushRangeFilter@16 ; MiFlushRangeFilter(x,x,x,x)
  9. PAGE:805FDBF3 000 C3                                            retn


__finally для TryLevel = 1
Code:
  1. PAGE:805FDBF9 000 8B 65 E8                                      mov     esp, [ebp-18h]
  2. PAGE:805FDBFC 000 83 4D FC FF                                   or      dword ptr [ebp-4], 0FFFFFFFFh
  3. PAGE:805FDC00 000 33 DB                                         xor     ebx, ebx
  4. PAGE:805FDC02 000 E9 6E A0 F8 FF                                jmp     loc_80587C75


-----
IZ.RU




Ранг: 58.0 (постоянный), 13thx
Активность: 0.020.01
Статус: Участник

Создано: 30 июля 2011 00:31
· Личное сообщение · #5

Смотрим в исходники:
private\ntos\mm\flushbuf.c:
Code:
  1. ...
  2.             RangeBase = BaseAddress;
  3.             RangeLength = Length;
  4.  
  5.             do {
  6.                 Retry = FALSE;
  7.                 try {
  8.                     KeSweepIcacheRange(FALSE, RangeBase, RangeLength);
  9.                 } except(MiFlushRangeFilter(GetExceptionInformation(),
  10.                                             &RangeBase,
  11.                                             &RangeLength,
  12.                                             &Retry)) {
  13.                     if (GetExceptionCode() != STATUS_ACCESS_VIOLATION) {
  14.                         Status = GetExceptionCode();
  15.                     }
  16.                 }
  17.             } while (Retry != FALSE);
  18. ...


private\ntos\inc\i386.h:

Code:
  1. //  386 and 486 have transparent caches, so these are noops.
  2.  
  3. #define KeSweepDcache(AllProcessors)
  4. #define KeSweepCurrentDcache()
  5.  
  6. #define KeSweepIcache(AllProcessors)
  7. #define KeSweepCurrentIcache()
  8.  
  9. #define KeSweepIcacheRange(AllProcessors, BaseAddress, Length)





Ранг: 324.3 (мудрец), 222thx
Активность: 0.480.37
Статус: Участник

Создано: 30 июля 2011 08:05
· Личное сообщение · #6

Явно исполнительная часть ядра винды здесь отличается от моей. Вот так и должно быть, но у меня не так...

-----
IZ.RU




Ранг: 58.0 (постоянный), 13thx
Активность: 0.020.01
Статус: Участник

Создано: 30 июля 2011 19:37
· Личное сообщение · #7

Не отличается. На 368 тело __try{} пустое.




Ранг: 324.3 (мудрец), 222thx
Активность: 0.480.37
Статус: Участник

Создано: 30 июля 2011 21:51
· Личное сообщение · #8

ntoskrnl.exe 5.1.2600.6055 всё именно так - тело __try{} пустое.

-----
IZ.RU



 eXeL@B —› Программирование —› CPPEH_RECORD и исключения
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати